投稿
公告

ETH Input Data 分析

作者:admin 2021-10-13 我要评论

之前,PolyNetwork失窃事件的一个小插曲,一地址向黑客地址转账在inputdata中告知其泰达币已被冻结,不要用泰达币,黑...

原始形式:

大家将原始的 input data 分为三个部分进行剖析:

参 数

在 evm 实行字节码的约定中,静态种类左补齐零至 64 长度,而动态种类则是右补齐零至 64 长度。
总结下容易见到的静态种类:uint,bool,Address,bytes[0-32], 动态数组种类:bytes,string,address[],bytes32[].....
大家通过 pyethereum的ABI编码函数 来研究不同数据种类的编码方法。
静态种类
先导入 encode_abi 函数

import rlp  
from ethereum.abi import encode_abi

inh3ut data

在ETH协议中,当买卖(transaction)为合约创建时,input data 是竞价推广账户初始化程序的 EVM 代码;

而当买卖(transaction)为消息调用时,input data 是合约函数调用数据。
正常状况下容易的消息调用如调用转账函数时需要填写你要转账的地址 _to 和你要转账的数目 _amount,这部分基本信息都包含在 input data 里面。
大家通过一个调用合约的转账买卖具体剖析,来理解消息调用时 input data 的结构。

函数标识符

这里的函数标识符即为函数选择器,依据官方文档可知函数选择器是某个函数签名的 Keccak(SHA-3)哈希的前 4 字节(高位在左的大端序)。

分析形式:

大家以函数 transfer 为例

> encode_abi.hex
000000000000000000000000345d8e3a1f62ee6b1d483890976fd66168e390f2
0000000000000000000000000000000000000000000000000000000000000001

对于小于 32 字节的定长数组会被自动填充到 32 字节:

> encode_abi.hex
// 自动填充 0
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000003


动态种类
动态种类编码要稍微复杂一些,需要先计算偏移量进行占位处置,大家通过一个容易的例子来具体说明。

> encode_abi.hex
// 参数 1 的偏移量:32*3=96 十六进制 0x60
0000000000000000000000000000000000000000000000000000000000000060
// 参数2的偏移量=参数 1 偏移量+参数 1 数据部分长度=96+32*4=224 十六进制0xE0
00000000000000000000000000000000000000000000000000000000000000e0
// 参数3的偏移量=参数 2 偏移量+参数 2 数据部分长度=224+32*4=352 十六进制0x160
0000000000000000000000000000000000000000000000000000000000000160
// 偏移量 0x60 地方开始传入参数 1 的数据
0000000000000000000000000000000000000000000000000000000000000003//元素个数
00000000000000000000000000000000000000000000000000000000000000a1//第一个数组元素
00000000000000000000000000000000000000000000000000000000000000a2//第二个数组元素
00000000000000000000000000000000000000000000000000000000000000a3//第三个数组元素
// 0xe0地方。参数 2 的数据
0000000000000000000000000000000000000000000000000000000000000003
00000000000000000000000000000000000000000000000000000000000000b1
00000000000000000000000000000000000000000000000000000000000000b2
00000000000000000000000000000000000000000000000000000000000000b3
//0x160 地方。参数 3 的数据
0000000000000000000000000000000000000000000000000000000000000003
00000000000000000000000000000000000000000000000000000000000000c1
00000000000000000000000000000000000000000000000000000000000000c2
00000000000000000000000000000000000000000000000000000000000000c3


短地址攻击
经过前面的剖析当静态种类如 address 长度不足 32 字节时 EVM 会依据规则将长度补齐到 32 字节,假如当转账的地址以00结尾,如0x641988625108585185752230bde001b3ebd0fc00,转账时将地址后面的两个零去掉,EVM 依旧会觉得 address_to是 32 位的,所以它会从_value的高位取 0 来补充,amount的位数会多两位也就是会乘以256。
攻击过程如下:

将恶意转账地址最后一个字节的 0 去掉
函数标识符:a9059cbb
转账地址:
000000000000000000000000641988625108585185752230bde001b3ebd0fc
转账金额:
00000000000000000000000000000000000000000000000000000000000000001
因为 EVM 的补位规则,分析结果为:
0xa9059cbb000000000000000000000000641988625108585185752230bde001b3ebd0fc0000000000000000000000000000000000000000000000000000000000000000100
大家分解后发现,转账金额已经多了两位也就是多了一个字节,即为原来转账的 256倍
函数标识符:a9059cbb
转账地址:
000000000000000000000000641988625108585185752230bde001b3ebd0fc00
转账金额:
00000000000000000000000000000000000000000000000000000000000000100

怎么样在 input data 附着信息

在ETH中直接进行转账买卖的 input data 字段默认是没内容的,但大家可以通过设置钱包达成文章开头的“聊天功能”。
大家以 MetaMask 钱包为例展示怎么样通过转账在 input data 字段附着一些额外的信息。

1、第一大家需要打开钱包高级选项的显示十六进制数据开关

2、在转账时将你要附着的信息通过十六进制编码后填入下方十六进制数据中,记得在开头加上 0x 然后进行转账

3、转账成功后在 etherscan 中就可以看到附着信息

大家可以通过代码

bytess4"))或者在线工具获得这种函数签名。
下图可以看出加密结果的前四个字节 跟 input data 中函数标识符一致。

这里之所以要将函数签名截断到四个字节是考虑到 Gas 本钱问题。

在一笔买卖中0字节需要支付 4 gas,而非0字节需要 68 gas 也就是 0 字节的 17 倍。在 SHA-3 加密中生成的 32 字节随机字符串更倾向于多的非 0 字节,所以大概本钱是32x68=2176 gas,而截断本钱大概为 4x68=272 gas,可见截断到四个字节可以节省约 8 倍的 gas 费。

而函数标识符有哪些用途是指定调用哪一个函数,在同一个合约中两个不同函数的 SHA-3 签名的前 4 字节相同的概率是十分小的,所以截断到四个字节实质不会干扰函数调用。

概要

大家可以通过买卖中的 input data 将一些信息永久存储在区块链中,可以通过此项技术在食品药品监管部门的商品防伪溯源、财税部门的电子票据打假验真、学术成就存证等方面达成应用落地。

0xa9059cbb:函数标识符

000000000000000000000000345d8e3a1f62ee6b1d483890976fd66168e390f2: 第一个参数为 address 即你要转账的地址,并补位到 32 字节即 64 个 16 进制字符

0000000000000000000000000000000000000000000054b7d8ed70650b290000: 第二个参数为 value 即你要转账的数目,并补位到 32 字节即 64 个 16 进制字符

 通过对比剖析大家可以发现 input data 的基本结构为函数标识符+参数

之前,Poly Network 失窃事件的一个小插曲,一地址向黑客地址转账在 input data 中告知其 泰达币 已被冻结,不要用 泰达币,黑客知道后向该地址转账 13.37 以太币。

事后大多数人便通过 input Data 在区块链上“聊天”向黑客“索要”数字货币,那样大家常常在区块链浏览器中看到的 input Data 到底是什么?知晓创宇区块链安全实验室 为你解答。

查询更多

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 蚂蚁集团蒋国飞:外贸数字化

    蚂蚁集团蒋国飞:外贸数字化

  • 北京常识产权保护草案提出运

    北京常识产权保护草案提出运

  • 思特奇:IaaS和PaaS层商品软件技

    思特奇:IaaS和PaaS层商品软件技

  • twitterCEO:ETH或者其他技术没办

    twitterCEO:ETH或者其他技术没办