#DASP# Front Running (7)
0x00 Info
本篇介绍DASP第七种漏洞类型–前置执行。 可以理解为因为区块链是公开,其他用户或者合约的交易信息均透明可查,恶意用户可以利用这些已知信息制造有利于自己的交易,并通过提高手续费的方式抢先执行获利。
当然,在front-running-griefing-and-the-perils-of-virtual-settlement中描述,如果这个恶意用户本身又是矿工,可以任意安排交易并审查其他人交易,使自己利益最大化。
0x01 实例
LastIsMe
LastIsMe是一个lottery游戏合约,在一个游戏回合(一定的区块数内)参与者购买一张票认领最后一个座位,回合结束时最后一个就坐的玩家会获得头奖。
攻击者可以在回合快结束时观察其他玩家的交易池,通过提高gas来挤掉其他玩家的交易从而获得奖金。
ICO
ICO本身是一道CTF题,它包含一个DAPP网站和与其交互的两个合约(HaCoin & ICO),部署在rinkeby测试链上。
HaCoin是一个Token合约,比赛的目标也是从该合约中获取超过31337枚HackCoin,而这个合约本身并没有问题,需要配合Web网站存在的XSS漏洞来提权,才能进行转币操作。很有意思,具体writeup参见ZeroNights ICO Hacking Contest Writeup。
而另一个合约ICO是一个lottery合约,游戏规则也很简单,5个块为一回合,回合内参与者猜一个数字,回合结束时机器人会随机抛出一个数字,如果谁猜中谁就获胜。而该合约存在前置执行漏洞。
function spinLottery(uint number) public {
if (msg.sender != robotAddress) {
playerNumber[msg.sender] = number;
players.push(msg.sender);
NewLotteryBet(msg.sender);
} else {
require(block.number - lotteryBlock > 5);
lotteryBlock = block.number;
for (uint i = 0; i < players.length; i++) {
if (playerNumber[players[i]] == number) {
desires[players[i]].active = true;
desires[players[i]].email = "*Use changeEmail func to set your email.*";
Proposal(players[i], desires[players[i]].email);
}
}
delete players; // flushing round
NewLotteryRound(lotteryBlock);
}
}
机器人发布的随机数明文提交到交易池,如果攻击者能够足够快的检索pending交易并找到该随机数,然后使用该随机数参与游戏,保证两笔交易在同一个块中,并提高gas在机器人发布随机数的交易之前执行,就能获胜。
BancorFormula
详细分析:Implementing Ethereum trading front-runs on the Bancor exchange in Python