撰文:Thinking@慢雾安全团队
事件背景
分析源自一笔转账金额10wUSDT,手续费却高达7,676枚ETH的天价手续费交易。https://etherscan
将int转成Hexhttps://github
判断是否可以被2整除,如果不行需要在字符开头添加一个0,这里主要是为了能够成功的将数据2个1组写入到buffer。https://github
if(a
returna;}
以出错的示例数据:33974229950.550003进行分析,经过intToBuffer函数中的intToHex和padToEven处理后得到7e9059bbe.8ccd,这部分浏览器js和nodejs的结果都是一致的。
工信部等三部门发文:加强区块链在健康养老领域集成创新和融合应用:金色财经报道,工业和信息化部、民政部、国家卫生健康委等三部门近日联合印发《智慧健康养老产业发展行动计划(2021-2025年)》,《计划》指出,推动区块链等新一代信息技术在健康及养老领域的集成创新和融合应用,推进区块链等新一代信息技术以及移动终端、可穿戴设备、服务机器人等智能设备在居家、社区、机构等养老场景集成应用,在“时间银行”内运用区块链等技术,赋能互助养老,创新低龄老年人服务高龄老年人、伙伴式陪伴等互助养老模式。[2021/10/23 20:50:34]
不一致的地方是在newBuffer的操作:
newBuffer(padToEven(hex.slice(2)),'hex');
处理方式分析:浏览器js
工信部开展新型信息消费示范项目申报工作,将面向区块链等技术:工业和信息化部办公厅发布关于组织开展2020年新型信息消费示范项目申报工作的通知,示范内容面向5G、人工智能、区块链等前沿技术,从提升产品服务供给、加快模式创新和优化消费环境等方面着力,遴选一批新型信息消费示范项目,总结形成可复制、可推广的经验做法,加快扩大和升级信息消费。[2020/4/3]
通过webpack打包好js文件并对文件进行引用,然后在浏览器上进行调试分析。
首先输入的示例字符33974229950.550003会进入到intToBuffer的函数中进行处理。
声音 | 工信部谢少锋:需增加区块链等技术研发投入 推动工业互联网发展:工业和信息化部信息化和软件业服务司司长谢少锋在数博会演讲中指出,要继续5G、人工智能、区块链等前沿技术的研发投入,推动工业互联网发展。[2019/5/27]
同步分析intToBuffer的处理过程,这部分和」关键代码分析「部分的代码逻辑是一样的,处理转换部分得到的结果是7e9059bbe.8ccd。
接下来分析如何将转换后的字符填充进入的buffer中,通过这步可以得到buffer的内容是126,144,89,187,14,140,205对应的是7e,90,59,bb,e,8c,cd。
慢雾安全工程师:安全审计是目前保护DeFi项目安全最高性价比的方式:12月30日,在慢雾科技主办的Hacking Time区块链安全攻防峰会上,慢雾科技高级安全工程师yudan和Kong根据bZx最早期的两次闪电贷攻击案例,介绍了闪电贷基本的攻击形式——代币价格操纵,详细讲述了基于价格操纵的闪电贷的防御方案以及在其价格无法被操纵的情况下,如何利用闪电贷另辟蹊径,通过操纵 LP Token的单价来进行获利。并通过慢雾被黑档案库与大家一起回顾了2020 DeFi被黑事件。
yudan和Kong认为,DeFi安全形势严峻,安全审计是目前保护项目安全最高性价比的方式。在当下DeFi黑暗森林里我们在临渊而行,需如履薄冰。[2020/12/30 16:04:29]
动态 | 慢雾预警:Electrum钓鱼更新事件预警:据慢雾区消息,此前对Electrum钱包进行攻击的黑客利用Electrum的软件异常构造恶意的软件更新提示,诱导用户更新下载恶意软件使用,慢雾团队提醒用户,如果您使用的Electrum 提示更新请注意仔细核对信息,认准官方网站和软件版本并作签名校验。真实的官方网站和下载链接如下:
github.com/spesmilo/electrum(GitHub的仓库托管代码)、https://electrum.org/(该项目的网站)
假冒的是:github.com/electrum-wallet/electrum/releases
如果您看到以上虚假地址,请忽略它并更改服务器。
此外,慢雾区提醒项目方,可接入 DApp 防火墙免疫此类攻击,阻断攻击者进一步扩大攻击范围。[2018/12/28]
>0x7e->126>0x90->144>0x59->89>0xbb->187>0xe->14>0x8c->140>0xcd->205
这里发现e.这部分的小数点消失了,于是开始解小数点消失之迷,追踪到hexWrite这个函数,这个函数会将得到的数据2个一组进行切分。然后用了parseInt对切分后的数据进行解析。
然而parseInt('e.',16)->14===parseInt('e',16)->14消失的小数点被parseInt吃掉了,导致最终写入到buffer中的数据发生了错误,写入buffer的值是7e9059bbe8ccd。
处理方式分析:nodejs
由于浏览器上出问题的是7_**__**_e9059bbe.8ccd在写入buffer的时候小数点被parseInt吃掉了导致数据出错,但是经过分析,node的数据也是错误的,且产生错误的原因是和浏览器的不一样。
首先我们先看下如下的示例:
node三组不同的数据填充到buffer得到的结果居然是一样的,经过分析node的buffer有个小特性,就是2个一组切分后的数据,如果没法正常通过hex解析的,就会把那一组数据以及之后的数据都不处理了,直接返回前面可以被正常处理的那部分数据。可以理解为被截断了。这部分可以参考node底层的buffer中node_buffer.cc中的代码逻辑。
>newBuffer('7e9059bbe','hex')>newBuffer('7e9059bbe.8ccd','hex')>newBuffer('7e9059bb','hex')
执行结果的比较
node由于会将原始数据7e9059bbe.8ccd中的e.及之后的数据进行截断,所以最终错误的值是7e9059bb,相比正确的值07e9059bbe小。
node的执行结果:
浏览器由于会将原始数据7e9059bbe.8ccd中的.吃掉,所以最终错误的值是7e9059bbe8ccd,相比正确的值07e9059bbe大很多。
浏览器的执行结果:
问题的原因
ethjs-util的intToBuffer函数不支持浮点型的数据,且在这个函数中没有判断传入的变量类型,来确保变量类型是预期内的。由于ethereumjs的toBuffer引用了ethjs-util的intToBuffer进行处理,也没有对数据进行检查。导致了这次事件的发生,所幸最终善良的矿工归还了「天价手续费7626ETH」。
吸取的教训
从第三方的库的角度来看,在编码过程中应该要遵循可靠的安全的编码规范,在函数的开头要对传入的数据进行合法性的检查,确保数据和代码逻辑是按照预期内执行。
从库的使用者的角度来看,使用者应该要自行阅读第三方库的开发文档和对接文档,并且也要对代码中接入第三方库的逻辑进行测试,通过构造大量的数据进行测试,确保业务上能够正常按照期望执行,保证高标准的测试用例的覆盖率。
参考资料:https://github.com/ethereumjs/ethereumjs-monorepo/issues/1497https://blog.deversifi.com/23-7-million-dollar-ethereum-transaction-fee-post-mortem/https://www.chainnews.com/news/611706276133.htm
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。