2018DDCTF-mini-blockchain分析

去年的题目,现在仍然开着:http://116.85.48.107:5000/b942f830cf97e/
分析一遍代码感觉对区块链又加深了理解。下一步自己尝试写一写
题意:银行发行了100W的DDB,黑客append两个区块转给自己99W9999。让我们找回钱并且在商店花200W买两个钻石。
1.信息收集:
把首页杂乱的信息整理
image.png
得到信息:
创世区块地址
银行地址及资金:1
黑客地址及资金:999999
商店地址及资金:0
image.png
得到信息:
UTXO-1:向黑客地址转资金999999
UTXO-2:向银行地址转资金1
image.png
得到信息:
创世区块高度为0,资金100W
黑客append空块高度为2
image.png
得到信息:
黑客把银行地址100W资金转到高度为1的区块99W9999,转到银行地址1。留下一句:HAHA, IM THE BANK NOW!
2.源码分析
注:为了看得更清楚,注释用的//
image.png
Flask框架,默认url:/b942f830cf97e
FLAG()函数,返回GLAG。

查看路由得到信息:
image.png

image.png
/默认路径下展示homepage
get_balance_of_all()输出所有账户余额及UTXO,及整个函数返回:创世区块、地址、UTXO、区块链、查看源码的信息
image.png
/flag路径下,如果你的钻石>=2调用FALG()函数输出flag。否则输出钻石不够要向商店地址转100W才得到一个钻石

image.png
/5ecr3t_free_D1diCoin_b@ckD00r/路径下,可以在银行地址向指定地址转账。尝试一下:
image.png
我们可以在这里知道转账的代码,可以模仿写出自己的转账代码。

image.png
/create_transaction路径POST访问创建交易,尝试一下。看来只能用脚本了。。。怪不得题目建议用脚本。
image.png
然后我们可以看出代码意思:如果商店地址有100W则给你一个钻石,然后立马把商店地址的100W转到商店钱包。

image.png
/reset路径,如果把链搞砸了可以重置区块链
image.png
/source_code路径,可以查看源码

在我们看路由的时候发现了很重要的信息:
image.png
工作量证明难度要求hash值00000开头

然后审计具体函数:
image.png
计算参数hash摘要信息。而且是先md5再sha256,更加加固了信息摘要安全性。

image.png
哈希运算,我们定位使用该函数的地方,可以看到是python的reduce()函数调用,该函数是对第一个参数(函数)运算后的值与第二个参数运算。在区块链中应该是来更容易计算:父区块hash+本区块hash+随机数
reduce函数使用规则可以参考一下链接:http://www.runoob.com/python/python-func-reduce.html
image.png
image.png
image.png
定位调用reduce的函数找到,这三个函数直接返回reduce函数的计算值,来计算UTXO、TX、Block的hash值。

image.png
来限制格式必须是字典容器模型格式或JSON格式,如果attrs参数中所有值有没在d参数中的则抛出异常。
定位一下使用has_attrs()函数的地方:
image.png
在添加块中要求block必须有三元素:前一区块hash值、nonce值、汇报
image.png
在交易中必须有:输入、输出、签名
image.png
在UTXO中必须有:资金数量、地址、id值

所以我们可以知道各个字段的包含关系:
image.png

image.png
常量hash值,64个0。在计算hash值得时候用到
image.png
在python中验证一下字符串*数字结果。

image.png

地址是N,65537是e,返回地址的私钥d(RSA参数,不懂可百度)来验证。

image.png
生成钱包地址(公钥)及私钥。

image.png
签名函数,把交易信息用私钥加密得到签名摘要。

image.png
创建一个交易输出,参数为目的地址和资金数量

image.png
创建一个交易,其中签名为把交易id通过私钥加密

image.png
创建一个区块,包括三要素:前一区块hash值、nonce值、汇报。前一区块hash值必须是16进制且限制nonce长度要小于128。

image.png
查找区块链中最后一个区块,返回其高度?

image.png
获取所有的UTXO信息

image.png
计算钱包的余额。默认三个地址都为0,循环累加UTXO中每个地址的资金,返回各个地址的余额。

image.png
验证UTXO签名。其实就是rsa的解密过程。签名为密文,地址为公钥,解密算出明文(信息摘要)正确,则证明了是交易人地址验证签名正确。

image.png
image.png
添加区块,过程略微复杂,主要是验证添加的区块是否满足规范,否则抛出异常。
大致过程如下:
1.验证三要素。(第三要素”交易”又有输入、输出(输出即UTXO又包含id值、资金数量、地址)、签名)。包括验证输出要小于输入等等可能出现问题的地方。
2.创建区块(包含三要素),产生区块hash。保证区块hash值满足规范但又小于difficulty值。
3.区块链高度加一,且长度不能超过50。

image.png
设置session,有区块和我们的钻石数。首先产生创世区块100W资金,然后银行被黑客添加区块转账99W9999,黑客又添加了空块。

image.png
得到所有信息函数。在主页调用了,我们看到的主页信息就是调用了该函数。

3.构造思路
由于没有别人来挖矿(添加区块)即我们拥有100%算力。可以结合51%算力攻击,我们可以随意添加区块来改变主链方向。同时也可利用双花攻击来达到双次花费。
初始信息:
image.png
通过append区块把钱找回:
image.png
同时我们关注代码部分,shop会立即把钱转到shop钱包
image.png
即目前情况为:
image.png
那么我们就可以再次分叉来发动双花攻击了。
image.png

此时主链已经成为:1-2(2)-3(2)-4(2)-5(3)-6(3)已经覆盖shop把钱转到自己钱包,100W又到了shop所有又获得1个钻石。

4.Payload脚本
参考:一叶飘零师傅

image.png
获取初始session,抓取主页信息。
image.png
贴一下源码中的函数及常量,以便我们使用。
image.png
写好挖矿脚本,爆破遍历nonce满足小于difficulty且’00000’开头
image.png
添加第一个自己的区块,注意header的构造:添加Content-Type为json。
image.png
按照思路逐个提交构造的区块,然后再访问/flag目录即可得到falg。
image.png

发表评论

电子邮件地址不会被公开。 必填项已用*标注

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部