// 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;
}
}
}
이번 mission은 delegatecall의 개념을 잘 이해하고 Contract의 owner를 탈취해야 한다.
delegatecall의 개념을 알고 있다면 나름 쉽게 풀 수 있다.
delgatecall를 잘 모른다?? 그럼 빨리 가서 보고와!!!
코드를 살펴보면 Delegate 컨트랙트에서 pwn() 함수를 호출하면 owner가 msg.sender로 바뀐다.
그리고 Delegation 컨트랙트에서는 address(delegate).delegatecall(msg.data)로 delegatecall을 하는데 msg.data의 함수를 가져온다.
그러면 msg.data에서 pwn함수를 가져와야 하니 msg.data에 인자 값은 pwn() 함수 일 것이다.
Dapp에서 특정 method를 호출하고 싶을 경우 Method ID를 이용하여 호출한다.
Method ID는 keccak256을 해시한 값의 첫 4byte이다. 그리고 Method ID Tansaction을 발생 시 data에 넣어야 하는 코드이다.
help()에 sendTransaction()을 사용하여 delegatecall을 이용하면 된다.
일단 사용하기 전 pwn()의 method ID를 얻어야 한다.
2가지 방법이 있는데
FunctionSignature()를 이용하거나 keccak256()으로 hash함수를 만든 다음 앞 4byte만 가져오면 된다.
그래서 send Transaction을 하면 owner가 바뀌는 것을 확인할 수 있다.