区块链の智能合约学习
以34C3 CTF中的智能合约题目为例,学习区块链技术中智能合约特性的知识
题目链接:
https://archive.aachen.ccc.de/34c3ctf.ccc.ac/challenges/index.html
send 1505 szabo 457282 babbage 649604 wei 0x949a6ac29b9347b3eb9a420272a9dd7890b787a3
什么是Etherscan
其实是一种特殊的浏览器,就像Chrome、Firefox、IE等一样,不过Etherscan让我们浏览的不是Internet内容,而是Blockchain的内容。
主页是etherscan.io
,需要科学上网。
解题:
0x00
send、wei等为以太坊的关键字,具体单位关系自行百度,1505 * 10 ** 12 + 457282 * 10 ** 6 + 649604)/10 ** 18 = 0.001505457282649604
ether,注意babbage有时是KWei,有时是MWei,此题为MWei。但是不需要支付这笔钱也可解出flag
题目中给出了地址,访问它得到字节码:
反编译&反汇编给出的字节码:(https://ethervm.io/decompile
附代码)
1 | contract Contract { |
0x01
可见总共main+三个函数,main作为入口主要用来选择函数,接下来查看函数在交易中的调用情况:
真正成功的记录只有中间没有感叹号的五条,挨着看一下:
第四条记录调用了Receive(),剩下四条均调用func_00CC()。那么主要分析这两个函数(不懂的地方查一查solidity手册)
0x02:func_00CC
1、main()函数头(见上面反编译结果)
(1)if (msg.value) { revert(memory[0x00:0x00]); }
msg.value的值代表转账者给合约转账的金额数,此行语句说明没有支付,忽略。
(2) 第三行:var var2 = msg.data[0x04:0x24] & 0xffff;
此过程是个传参过程,从0x04
开始读取0x20(32)
个字节长度,然后进行0xffff
运算。该数据没有进行除法处理,可以判断其变量类型byte2
(3) 随后开始调用func_00CC()执行,有return值
2、func_00CC内部
第二行的if对arg0 & 0xffff
和storage[0x01] & 0xffff
进行比较,不相等则返回0x00
0x03
逻辑清楚后,现在只剩下找出支付成功后的返回值(唯一可能的flag载体):
根据交易记录:
可知第四次交易时发生了转账,即调用了Receive(),所以在第五次交易时调用func_00CC()执行,可以得到return值。
可使用浏览器的Parity Trace功能,来查看第五次记录:
甚至连Hex转Text的功能都提供了,getflag:
附:对于func_00CC()中,判断输入与storage[0x01]处,可以用getStorageAt()得到保存的数据。
方法不限,Node+web3.js可行,调用API也可行。
由此获取其最后两个字节的值0xc1cb
,只后也可以自行发送0x2a0f7696c1cb
作为Input Data,获得Output。