去年的题目,现在仍然开着:http://116.85.48.107:5000/b942f830cf97e/
分析一遍代码感觉对区块链又加深了理解。下一步自己尝试写一写
题意:银行发行了100W的DDB,黑客append两个区块转给自己99W9999。让我们找回钱并且在商店花200W买两个钻石。
0x01 信息收集
把首页杂乱的信息整理

得到信息:
- 创世区块地址
- 银行地址及资金:1
- 黑客地址及资金:999999
- 商店地址及资金:0

得到信息:
- UTXO-1:向黑客地址转资金999999
- UTXO-2:向银行地址转资金1

得到信息:
- 创世区块高度为0,资金100w
- 黑客append空块,高度为2

得到信息:
- 黑客把银行地址100w资金转到高度1的区块99w9999,转到银行地址1。并留下一句:HAHA,IM THE BANK NOW!
0x02 源码分析

- Flask框架,默认url:/b942f830cf97e
- FLAG()函数,返回FLAG
查看路由信息:


- 默认路径下展示homepage
- get_balance_all()输出所有账户余额UTXO,及整个函数返回:创世区块、地址、UTXO、区块链、查看源码的信息

- /flag路径下,如果你的钻石>=2调用FALG()函数输出flag。否则输出钻石不够要向商店地址转100W才得到一个钻石

/5ecr3t_free_D1diCoin_b@ckD00r/string:address路径下,可以在银行地址向指定地址转账。尝试一下:

我们可以在这里知道转账的代码,可以模仿写出自己的转账代码。

- /create_transaction路径POST访问创建交易,尝试一下。看来只能用脚本了。。。怪不得题目建议用脚本。

- 然后我们可以看出代码意思:如果商店地址有100W则给你一个钻石,然后立马把商店地址的100W转到商店钱包。

- /reset路径,如果把链搞砸了可以重置区块链

/source_code路径,可以查看源码
在我们看路由的时候发现了很重要的信息:工作量证明难度要求hash值00000开头

然后审计具体函数:

- 计算参数hash摘要信息。而且是先md5再sha256,更加加固了信息摘要安全性。

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



- 定位调用reduce的函数找到,这三个函数直接返回reduce函数的计算值,来计算UTXO、TX、Block的hash值。

来限制格式必须是字典容器模型格式或JSON格式,如果attrs参数中所有值有没在d参数中的则抛出异常。
定位一下使用has_attrs()函数的地方:

- 在添加块中要求block必须有三元素:前一区块hash值、nonce值、汇报

- 在交易中必须有:输入、输出、签名

在UTXO中必须有:资金数量、地址、id值
所以我们可以知道各个字段的包含关系:


- 常量hash值,64个0。在计算hash值得时候用到

- 在python中验证一下字符串*数字结果。

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

- 生成钱包地址(公钥)及私钥。

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

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

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

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

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

- 获取所有UTXO信息

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

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


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

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

- 得到所有信息函数。在主页调用了,我们看到的主页信息就是调用了该函数。
0x03 构造思路
由于没有别人来挖矿(添加区块)即我们拥有100%算力。可以结合51%算力攻击,我们可以随意添加区块来改变主链方向。同时也可利用双花攻击来达到双次花费。
- 初始信息:

- 通过append区块把钱找回:

- 同时我们关注代码部分,shop会立即把钱转到shop钱包

- 即目前情况为:

- 那么我们就可以再次分叉来发动双花攻击了。

- 此时主链已经成为:1-2(2)-3(2)-4(2)-5(3)-6(3)已经覆盖shop把钱转到自己钱包,100W又到了shop所有又获得1个钻石。
0x04 payload脚本
- 参考:一叶飘零师傅

- 获取初始session,抓取主页信息。

- 贴一下源码中的函数及常量,以便我们使用。

- 写好挖矿脚本,爆破遍历nonce满足小于difficulty且’00000’开头

- 添加第一个自己的区块,注意header的构造:添加Content-Type为json。

- 按照思路逐个提交构造的区块,然后再访问/flag目录即可得到falg。
