Ethernaut学习智能合约系列(一)

最近稍微有点空闲,就想去好好研究下智能合约的安全问题,因为是新兴产业,所以没有现成的教程或者是材料,所以只能找一些较为基础但是能够帮助我们学习智能合约的平台,这里的Ethernaut就是一个基于web3和solidity的智能合约审计平台。

平台地址:https://ethernaut.zeppelin.solutions

0. Hello  Ethernaut

这里按照教程来走就好了,首先要安装MetaMask这款插件,然后将网络设置成Ropsten test network,最后给自己打点钱,这里由于是测试网络,因此均是免费的。

图片[1]-Ethernaut学习智能合约系列(一)-安全小百科

打钱的就用这里的“buy”即可,不需要真正意义上的打钱!

下面就是创建实例“Get new instance”,这里创建时候需要付“gas”,也就是从你的以太坊账户中扣钱(具体解释参照这篇文章http://ns1.btckan.com/news/topic/48347),然后在metamask中同意扣费即可运行智能合约。

图片[2]-Ethernaut学习智能合约系列(一)-安全小百科这里类似于web测试,但是输入需要在console里进行交互

下面就直接贴出wp,并对部分地方进行解释

最后提交instance,然后就能看到合约源码了,这里如果对代码不熟悉,可能还需要去看solidity文档(https://solidity.readthedocs.io/en/develop/),另外推荐一个solidity小游戏网站(https://cryptozombies.io/zh/course)

图片[3]-Ethernaut学习智能合约系列(一)-安全小百科

回过头来看

图片[4]-Ethernaut学习智能合约系列(一)-安全小百科

这个abi接口类似于API接口,在这个接口里我们可以看到所有可以调用的函数,具体分析文章(https://blog.csdn.net/shunfa888/article/details/80073081)

1. FallBack

这一关其实最重要的就是最后的那个未命名函数,具体解释文章如下:http://www.tryblockchain.org/14825685263030.html

这里的未命名函数即为回调函数,意思是如果调用合约时,没有匹配上任何一个函数(或者没有传哪怕一点数据),就会调用默认的回退函数。此外,当合约收到ether时(没有任何其它数据),这个函数也会被执行。

因此这里其实就是考察的这个点,回到代码中去,这里我们的最终要求是成为合约owner,并且要将取出合约所有的balance,因此第一步我们需要成为合约owner,这里条件是转钱,每次只能转小于0.01个ether,合约同名函数Fallback为初始化函数,这里初始化时默认给owner 1000ether,所以如果一次一次转,然后挤掉owner,这显然是不现实的,因此就需要来看看这个回调函数,当转钱数目大于0并且贡献值大于0时,发送者就能成为合约债主,所以这里的顺序应该是先做贡献,然后用sendTransaction这个函数来转钱,转钱时候触发回调函数,成为债主,最后使用withdraw来提钱。

最后submit instance即可~

知识点:回调函数的应用

2.Fallout

这条题目有点莫名其妙,通关条件是成为合约owner,所有重点看怎么成为owner的条件,下面附上源码

这里设的坑点是想要成为owner只有constructor里的函数,但是跟上一题目一样,合约同名函数为构造函数,也就是在合约初始化的时候用的,但是奇怪的是这里的构造函数是payable类型,也就是用来转账的函数,明显不符合初始化的功能,如果仔细看就会发现这个注释constructor其实是用来误导你的,因为这个函数中其实用1来混杂l,所以这其实不是个构造函数,所以直接调用这个函数,然后进行转账即可

知识点:构造函数的使用

3.Coin Flip

这一关名为硬币翻转问题,也就是猜测每一次硬币翻转的是正面还是反面,然后用true和false来表示,连续猜对十次即可通关,猜错一次直接重置次数为0

首先来看构造函数,将我们的猜对次数初始化为0,然后进行flip函数,这个函数传入bool值,返回bool值

blockvalue表示前一个区块的hash值,revert函数表示重置为初试状态,FACTOR其实是2^255,所以这里的coinFlip是blockValue/2^255,由于FACTOR值换算为256的二进制,则第一位为1,后面全为0,而现在我们不知道前一个区块的hash值,又由于这里是整除,也就是最后结果非0既1,这取决与前一个区块hash值的最高位,类似于这种题目,我们需要另外部署智能合约,然后计算区块的hash值

这里部署采用的是在线的平台https://remix.ethereum.org/

下面给出我的部署代码(这个平台的在线编译十分严格,所以是规范智能合约书写的好平台!)

然后点击Run,这里选择coin_hack函数进行编译,每一步都会付gas所以当页面没反应时记得查看一下是不是需要付gas

付完gas之后右边的Transactions recorded应该就有了,这时候记得保存record为json文件然后就可以run transactions

最后在deployed contracts里就有部署的合约,然后调用hack函数,这里也需要付gas,由于网速问题,这里只能一个一个调用,然后回到题目中输入

contract.consecutiveWins()即可查看猜测成功的次数(_v里的c值即表示成功次数)

图片[5]-Ethernaut学习智能合约系列(一)-安全小百科

图片[6]-Ethernaut学习智能合约系列(一)-安全小百科

知识点:智能合约的计算问题

4.Telephone

先贴代码

这里通关条件为成为合约owner,这里函数也很简单,首先是构造函数,将合约owner赋给合约创建者,然后是一个改变合约状态的函数,这里先来了解下tx.origin和msg.sender

在一个合约里,他们都表示当前交易的发送账号地址,但是如果涉及两个合约A和B,用户通过合约A来调用合约B,那么对于合约B来说,msg.sender则表示合约A,tx.origin则表示用户,所以这一题想要通关仍需要构造两个合约。

然后查看contract.owner就会发现已经变成了自己。

这里附上讲解tx.origin和msg.sender的文章:https://bitshuo.com/topic/59afc169fbcd445a40a3e2e6

知识点:tx.origin的应用

5.Token

通关目标是黑掉这个合约,初始化给了用户20个token,想办法获得更多

这里首先是构造函数,将用户的balance值进行初始化,这里初始化为多少我们并不知道

最后的balanceOf函数是用来查看用户余额的,因此只能看中间的transfer函数存不存在问题

这里出现的问题其实就是无符号计算的问题,也就是整数溢出,这里的balances和_value值均是无符号整数,所以当1-2的时候就会变成-1,但是这里由于是无符号整数,所以会变成111111……这样最大的值,所以这里默认有20个,那么转21个既可以通过整数下溢来攻击这个合约

然后提交就能显示通关的页面~

知识点:整数下溢攻击

 

 

相关推荐: 记一次iis6.0解析漏洞getshell

起初想对母校进行一次友情检测,实在没有找到突破口就想从旁站看看,然后就有了这篇文章,但是最后没有提权成功,很气~ 旁站有很多个,但是要么是找到漏洞找不到后台,要么找到后台直接是个静态页面,搜寻了很久之后,最终在这个废品网找到了突破口! 随手一试,果然试出了问题…

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论