728x90
반응형
문제 : https://ethernaut.openzeppelin.com/level/0x3c34A342b2aF5e885FcaA3800dB5B205fEfa3ffB
https://ethernaut.openzeppelin.com/level/0x3c34A342b2aF5e885FcaA3800dB5B205fEfa3ffB
ethernaut.openzeppelin.com
Code Analysis
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Fallback {
mapping(address => uint256) public contributions;
address public owner;
constructor() {
owner = msg.sender;
contributions[msg.sender] = 1000 * (1 ether);
}
modifier onlyOwner() {
require(msg.sender == owner, "caller is not the owner");
_;
}
function contribute() public payable {
require(msg.value < 0.001 ether);
contributions[msg.sender] += msg.value;
if (contributions[msg.sender] > contributions[owner]) {
owner = msg.sender;
}
}
function getContribution() public view returns (uint256) {
return contributions[msg.sender];
}
function withdraw() public onlyOwner {
payable(owner).transfer(address(this).balance);
}
receive() external payable {
require(msg.value > 0 && contributions[msg.sender] > 0);
owner = msg.sender;
}
}
해당 함수를 하나하나 분석해보겠다.
Constructor()
- 배포자에게 owner 권한을 부여
- msg.sender의 기여도를 1000 ether로 설정
Contribute()
- 0.001 ether 미만만 전송 가능
- 자신의 기여도가 기존 owner 보다 커지면 owner을 탈취할 수 있음
- 하지만, 배포자가 1000 ether 기여도로 시작하기에 일반적인 contribute로는 절대 넘을 수 없다.
getContribution()
- 본인의 기여도 조회 가능
withdraw()
- owner만 컨트랙트 내의 이더를 모두 출금 가능
receive()
- 해당 컨트랙트의 fallback 함수 (함수명을 명시하지 않고 ETH 전송 시 실행)
- 기여도가 0보다 크고, msg.value>0인 경우, owner를 msg.sender로 무조건 변경
- 해당 함수에서 취약점이 발생한다.
Exploit Scenario
- contribute 함수를 호출하여 이더를 보낸다.
- contributtions[msg.sender] > 0 상태가 됨
- msg.value > 0인 ether을 보내면 receive() 작동
- owner = msg.sender가 됨
- withdraw()로 전체 이더를 출금함
Exploit

처음 contribute함수를 실행하여, 0.0009만큼의 이더를 보낸다.
이에 따라 msg.sender의 기여도가 >0이 된다.
msg.value > 0인 ether을 보내주며 receive()가 작동된다.
이후 owner가 msg.sneder라는 것을 확인할 수 있다.
player과, contract.owner()을 실행해보면 확인할 수 있음
이후 withdraw로 전체 이더를 출금하면 된다.
728x90
반응형
'Hacking > Write Up' 카테고리의 다른 글
| [1-Day] CVE-2017-0199 (1) | 2025.05.29 |
|---|---|
| [Web3] Fallout (0) | 2025.05.25 |
| [Web3] Hello Ethernaut (0) | 2025.05.25 |
| [Pwnable] hook (0) | 2025.05.16 |
| [Pwnable] oneshot (0) | 2025.05.16 |