OnlyPwner - Shapeshifter Writeup

OnlyPwner - Shapeshifter Writeup-魔法少女雪殇
OnlyPwner - Shapeshifter Writeup
此内容为付费阅读,请付费后查看
300
立即购买
您当前未登录!建议登陆后购买,可保存购买订单
付费阅读

题目信息

  • 挑战名称: Shapeshifter
  • 作者: bobface
  • 目标: 获得 100 ETH 或更多
  • 特殊说明: 运行在 Shanghai 硬分叉(2023)

题目背景

The gas optimizooooors have launched their latest psyop in the form of a PR stunt. They deposited 100 ETH into a contract, where the first person to solve the challenge receives the full amount. Obviously, they don't want anyone to actually win this sum, so they implemented clever protections against winning the highest possible amount.

合约分析

Stunt 合约核心逻辑

contract Stunt is IStunt {
    function attempt(address target) external override onlyContract(target) {
        bytes32 firstResult = ITarget(target).first();
        require(firstResult == hex"deadbeef", "first failed");

        bytes32 secondResult = ITarget(target).second();
        require(secondResult == hex"c0ffeebabe", "second failed");

        bytes32 thirdResult = ITarget(target).third();
        require(thirdResult == hex"1337", "third failed");

        solved[target] = true;
    }

    function claimReward(address target) external override onlyContract(target) {
        require(solved[target], "not solved");
        require(!claimed[target], "already claimed");

        claimed[target] = true;

        uint256 size;
        assembly {
            size := extcodesize(target)
        }

        uint256 reward;
        if (size <= 3) {
            // Don't worry, that is impossible.
            reward = 100 ether;
        } else if (size <= 10) {
            reward = 1e12;
        } else if (size <= 100) {
            reward = 1e10;
        }

        (bool success, ) = target.call{value: reward}("");
        require(success, "transfer failed");
    }
}

奖励机制

代码大小奖励
≤ 3 字节100 ETH
≤ 10 字节0.000001 ETH
≤ 100 字节0.00000001 ETH
> 100 字节0 ETH

挑战分析

要获得 100 ETH,需要满足:

  1. attempt() 验证通过:合约必须实现 first()second()third() 三个函数
  2. claimReward() 时代码大小 ≤ 3 字节

看似矛盾:一个实现三个函数的合约不可能只有 3 字节!

漏洞发现

关键洞察

代码大小检查是在 claimReward() 时进行的,不是在 attempt() 时!

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容