BlockSec TxInfo 是 BlockSec Team 开发的一套针对以太坊(Ethereum)交易的数据可视化系统,可以将单笔交易中涉及的函数调用层级关系以树状图的形式展示出来,便于分析人员梳理调用逻辑。
此外,我们正在逐步增加对其他链的支持。
BlockSec TxInfo 可以帮助区块链研究人员了解以太坊交易的详细信息,例如资金流和函数调用流。尤其当出现针对 DeFi 项目的攻击事件时,安全团队为了尽快锁定问题合约和问题函数,首先需要定位攻击交易,而定位了交易之后下一步就是定位该笔交易中的问题合约和问题函数。然而很多攻击事件中涉及到不同的合约,且所调用的函数数量众多。但关键的问题函数可能就那么几个,检查所有涉及的合约代码显然不太合适。在这种情况下,BlockSec TxInfo 就可以协助分析人员根据函数调用流快速定位问题合约及问题函数。
简言之,该系统可以帮助区块链研究人员深入分析以太坊交易中的资金流向和函数调用流的详细信息。
定位到一条以太坊上的攻击交易,获取交易 hash
推荐使用 Chrome 浏览器打开 https://tx.blocksecteam.com/,并在首页搜索框输入上一步得到的交易 hash,并点击Search 按钮进行查询
Customized account map
这是一个为用户设计的自定义地址映射。若用户需要自定义地址(address)到别名(name)之间的映射时,可以点击该按钮进行配置。如下:
配置完成后点击右上角的 Replace 按钮就可以将返回数据中的地址别名替换为用户自定义的别名。此处需要注意的是为了使配置生效,用户在输入数据时必须是如上图所示的 json 数据格式,尤其要注意最后一项末尾是没有 , 的。
Basic Information
该部分罗列了本条交易的基础信息数据,简洁易懂。比如交易所在的区块号(Block number), 交易的发起地址(From)等等。
注意到右上角的两个按钮 Oversea 和 Domestic 。出于方便分析人员进行快速跳转的考虑,对于交易本身以及交易中涉及到的地址,我们在交易返回数据的各个部分均做了相应的 etherscan 的链接。而两个按钮的不同选择就是指向国内或者国外的 etherscan 网址,默认设置为国外网址。
Account Balance
本部分以表格的形式呈现,当所查询的交易涉及到账户之间的 token 转移时,表格中就会将交易结束之后各账户的 token 余额的变化呈现出来。
其中,余额增加时,用绿色数字表示,反之则是红色。因此针对攻击交易的分析,可以初步从这个表格中看出一笔交易过后的获利地址和受害地址。
Invocation Flow
该部分展示的本网站最重要的功能,即一笔交易中合约之间的函数调用关系图。
调用图主要分为三个部分
调用方式
这部分以蓝色或绿色为背景颜色,分别标识这一行数据信息是函数调用还是事件(event)触发。
函数调用分为 CALL,STATICCALL 以及 DELEGATECALL 三种方式。
此外还有最开始的 Launcher,指代的是发起本交易的外部账户(EOA)。
输入
这部分以灰色为背景颜色,用于标识被调用的函数及其输入参数,是核心部分。
如 DVM.getVaultReserve() 就表示上一层函数内调用了 DVM 这个合约的 getVaultReserve() 函数。若被调函数有输入参数,则会将每一项的参数名及其对应的值都显示出来。
若合约未开源,且参数无法解析时,参数部分将显示 raw data, 将鼠标移到该字段上方可以看到以提示框的方式展示的原始数据。
输出
这部分以橙色为背景颜色,标识了输出也即返回值的信息,其展示方式和输入参数的展示方式相似。
为了将函数之间的调用深度关系展示在图上,我们在图中添加了红色数字标识用于展示函数调用层级。数值越大,表明被调用的层级越深。
接下来的实例分析将以DODO安全事件的其中一笔攻击交易为例,交易hash为:
0x395675b56370a9f5fe8b32badfa80043f5291443bd6c8273900476880fb5221e
参考文章为:
DODO事件分析
为了快速定位获利地址和受害地址,首先查看返回数据中的 Account Balance,根据该表格各地址的 Balance 是增加 (数据为绿色) 还是减少 (数据为红色) ,可以初步将其定位为获利地址或是受害地址。
注意到由于同一个项目或者不同项目之间的合约存在代码复用的问题,所以两个合约是可能同名的,但其对应的以太坊地址其实是不一样的。比如上图中红框中的两个 token,虽然其合约名一样,但他们的地址是不一样的。要验证这一点也很简单,因为我们对返回数据中的所有地址都做了 etherscan 上的跳转链接,所以在 Chrome 浏览器下,将鼠标悬浮在该 token 上时可以在屏幕左下角看到对应的链接地址,进而可以发现两个 token 对应的地址 hash 是不一样的。当然,也可以直接点进两个 token 的地址进行比较。
而为了增加数据可读性,此时就可以使用上文介绍过的自定义地址映射功能 (Customized account map)。如下:
替换之后的数据展示如下:
为便于表述,下图只截取了部分函数调用流的信息。
结合前文对 Invocation Flow 部分的介绍,可以看到在该交易中涉及到的各合约之间的函数调用过程如图中箭头所示。
攻击者调用了其部署的恶意合约中的函数 57a41e93 。该恶意合约虽然未开源,但由于后续的调用所涉及到的合约都是开源的,所以也能从后续的分析中基本推断出该合约的代码执行逻辑。
函数 57a41e93 之后又分别调用了 DLP 合约的 getVaultReserve 函数,FDO 的 transferFrom 函数,FUSDT 的 transferFrom 函数以及 DLP 的 flashloan 函数。之所以做出这样的调用判断是基于调用类型(CALL DELEGATECALL STATICCALL)前的数字,该数字标识的是函数调用层级。
DLP 的 flashloan 函数再继续调用 DVM 的 flashloan 函数...
按照这种方式可以简单梳理一笔交易的函数调用流。此外,对于调用流太多的交易,可以将调用流数据按层级不同进行折叠或展开,便于灵活观察函数调用逻辑。
在梳理交易的函数调用流时,我们可以发现 DLP 的 flashLoan 函数在后续执行过程中又调用了它自己的 init 函数。一般来说这个调用关系出现在闪电贷过程中是不正常的,所以我们接下来可以基于此继续分析两个方面的内容。
查看 init 函数的源码,具体分析 init 函数的功能
要查看 init 函数的源码很简单,直接点击该函数就会跳转到该函数所在的合约源码,接下来只要在合约源码中进行查找就行。
细化梳理从 DLP.flashLoan 到 DLP.init 的调用过程
上图中可以看出,从 DLP.flashLoan 到 DLP.init 之间有关键的一环,即 flashLoan 函数调用了攻击者部署的恶意合约里的 eb2021c3 函数。之后再经由 eb2021c3 函数调用了 DLP 的 init 函数,完成调用链。
所以在调用流梳理中的关键发现就在于图中红色方框圈出来的三个函数。
至此,我们通过在 BlockSec TxInfo 中查询交易信息,找到了后续分析相关代码的切入点,极大的提升了攻击分析的效率。
声明:本文由入驻金色财经的作者撰写,观点仅代表作者本人,绝不代表金色财经赞同其观点或证实其描述。
提示:投资有风险,入市须谨慎。本资讯不作为投资理财建议。
Web3前沿
巴伦周刊
CertiK中文社区
W3C DAO