前文我们分析了蜜罐合约的题目以及不足,本文我们重点研究如何通过逆向操作来深度分析蜜罐合约,并提供给攻击者防御者一些好的建议。
于是我们继续查看逆向合同:
这个函数中我们能看到需要传入四个参数,与地址相与操作意味着这是某个地址。
而if (arg2 > storage[keccak256(memory[0x00:0x40])]) { revert(memory[0x00:0x00]); }代表ERC20中的授权参数,我们从approve中能够看出该存储位置为0x03,此函数中的变量存储位置同样为0x03,所以为同一个参数。
即类似于:require(_value <= allowed[_from][msg.sender]);
而:if (storage[0x02] + msg.sender != arg3) { revert(memory[0x00:0x00]); }代表了0x02位置的参数+msg.sender需要 == arg3参数。
而位置0x02的参数可以通过如下方法进行查询,即为53231323。
所以我们需要传入 53231323+uint(msg.sender)。
之后我们尝试上述方案。
首先使用账户调用takeMoney。
这个时候就满足require (takeRecord[msg.sender] == true);。
之后我们需要将钱转出。
所以我们在账户下调用approve函数:
传入参数:0x7083bcda08538cba3437d98ad01edfa73e2e2276,1000即赋予0x7083bcda08538cba3437d98ad01edfa73e2e2276代替账户转账1000的权利。
查看allowance得到:
即授权成功。
之后我们进行转账操作。
调用attack函数:
此时我们需要调整一下合约的gas值:
尽量调整大一些,防止gas不足。之后查看:
之后调用`CaptureTheFlag`,成功!
结论
这是首次尝试使用蜜罐进行真实环境的尝试,在设计代码的时候是以欺骗者角度出发。为了让用户“上钩”我们必须给用户设计一个非常诱人的目标(这里是用CTF的flag),并非常明显的给用户一种提示,即需要满足什么条件。当用户拿到这个条件后会去代码中找达成条件的函数,而这些函数必须要非常明显并且易读。
对于熟悉攻击的人来说,这都是一些简单的技巧便能绕过。从而会让参与者觉得这个这个是合约的一个bug(内心窃喜?),当欢天喜地的去传入代币后会发现,完全不起作用??
目的达到,蜜罐便成功。
而对于防守方来说,要知己知彼才能做到万无一失,所以要了解攻击者的想法才能做到很好的防御,这篇文章愿能提供一些思路。












暂无评论内容