第十二关:Privacy
本关知识点
1. 区块中的数据没有隐私性
2. 以太坊数据存储写入的两种方式
1. strings和bytes都是大端存储,从左边开始存储数据。
2. 其他类型数据属于小端,从右边开始存储数据。
3. 以太坊数据存储位置可计算
4. 强制类型转换
1. 题目要求
解开这个合约来完成这一关
2. 代码功能解读
3. 漏洞分析
让locked等于false
因为区块链上的数据都是透明的,所以我们可以通过请求得到data[2]中的32个字节,然后拿到16个字节后,传入unlock方法即可。
4. 攻击方法
web3的getStorageAt方法得到data[2]的数据
根据合约的存储规则,计算得到data[2]的槽位为:5
web3.eth.getStorageAt("vitcim地址", 5);
截取获取数据的前面16字节的数作为答案调用unlock方法
存储的槽位信息如图:
-----------------------------------------------------
| unused (31) | locked(1) | <- slot 0
-----------------------------------------------------
| ID(32) | <- slot 1
-----------------------------------------------------
| unused (28) | awkwardness(2) | denomination (1) | flattening(1) | <- slot 2
-----------------------------------------------------
| data[0](32) | <- slot 3
-----------------------------------------------------
| data[1](32) | <- slot 4
-----------------------------------------------------
| data[2](32) | <- slot 5
-----------------------------------------------------
5. 攻击调用图
6. 知识点分析
在做区块链的猜谜游戏的时候,答案存放在区块链中是会被读取的,要尽量规避这个问题,比如把答案的hash存储到链上,防止直接读取到答案。或者在游戏结束后生成链下随机数答案来规避这个问题。
以太坊有两种存储方式,大端(strings & bytes,从左开始)及小端(其他类型,从大开始)。因此,从32到16转换时,需要砍掉右边的16个字节。
这里slice参数为0和34的原因是这个我们输入的数据包含"0x"这会占用2个字符,而且方法是半开半闭,所以从0开始,取值为34。
如果对大家有用,请点赞;如果喜欢,请订阅,会一直更新~