零时科技:DeFi 项目 Lendf.Me 遭黑客攻击复盘分析

事件摘要

北京时间 4月18日 08:58,黑客利用Uniswap和ERC777的兼容性问题,在进行 ETH-imBTC 交易时,利用ERC777中的多次迭代调用tokensToSend来实现重入攻击,将Uniswap上的imBTC(imBTC是一个1:1锚定比特币的ERC-20代币)池耗尽。

4月19日 09:28,Lendf.me 遭遇类似 Uniswap 事件的重入攻击,出现大量异常借贷行为,攻击者利用重入漏洞覆盖自己的资金余额并使得可提现的资金量不断翻倍,黑客以滚雪球的方式多笔转走imBTC,且每一笔都比上一笔翻倍,最终将Lendf.Me账户资产盗取一空。

随后Lendf.Me官方在 Lendf.Me 用户界面用红字提醒,呼吁用户目前不要向合约存款,截至发稿, Lendf.Me 已经停止服务,正在调查处理中。

image

此次黑客攻击,共累计的损失约24,696,616美元,具体盗取的币种及数额为:

WETH:55159.02134,
WBTC:9.01152,
CHAI:77930.93433,
HBTC:320.27714,
HUSD:432162.90569,
BUSD:480787.88767,
PAX:587014.60367,
TUSD:459794.38763,
USDC:698916.40348,
USDT:7180525.081569999,
USDx:510868.16067,
imBTC:291.3471

攻击成功后,攻击者不断通过OneInchExchange、AugustusSwapper、Tokenlon等去中心化交易平台以及Compound 借贷平台将盗取的币进行兑换和转移。

攻击过程复盘

本次针对 Lendf.Me 实施攻击的攻击者地址为: 0xa9bf70a420d364e923c74448d9d817d3f2a77822,攻击者的合约地址为: 0x538359785a8d5ab1a741a0ba94f26a800759d91d ,攻击者通过此合约对 Lendf.Me 进行攻击。如下图所示:

image

下面我们以攻击者盗取 Lendf.Me 账户中的 imBTC 资产为例,详细分析黑客攻击过程。

第一笔攻击交易

发起的第一笔交易是:https://cn.etherscan.com/tx/0xe49304cd3edccf32069dcbbb5df7ac3b8678daad34d0ad1927aa725a8966d52a

image

通过bloxy查看调用过程,https://bloxy.info/tx/0xe49304cd3edccf32069dcbbb5df7ac3b8678daad34d0ad1927aa725a8966d52a

image

第一次调用supply函数攻击者存入0.00021594,正常执行调用过程

第二次调用supply函数攻击者存入0.00000001,此时进行重入攻击,合约执行流程进入withdraw函数,攻击者调用withdraw函数取出攻击者的余额记录0.00021594,然后合约执行流程在回到supply函数,完成存入操作

最后交易持续完成,攻击者的余额记录为0.00021594 + 0.00000001 = 0.00021595,手中已取走的0.00021594,可以看到这里攻击者已经获利,资产总和已经翻倍

第二笔攻击交易

继续看第二笔交易,交易hash为:https://cn.etherscan.com/tx/0xae7d664bdfcc54220df4f18d339005c6faf6e62c9ca79c56387bc0389274363b

image

通过bloxy查看调用过程,https://bloxy.info/tx/0xae7d664bdfcc54220df4f18d339005c6faf6e62c9ca79c56387bc0389274363b

image

第一次调用supply函数攻击者存入0.00021593,正常执行调用过程

第二次调用supply函数攻击者存入0.00000001,此时进行重入攻击,合约执行流程进入withdraw函数,攻击者调用withdraw函数取出攻击者的余额,第一笔交易的余额0.00021595 + 第一次调用supply存入的 0.00021593 = 0.00043188,然后合约执行流程在回到supply函数,完成存入操作

最后交易持续完成,攻击者的余额记录为0.00021595 + 0.00021593 + 0.00000001 = 0.00043189,手中已取走的0.00043188,可以看到到这里,攻击者取出的金额和总资产数量都已经翻倍

第三笔攻击交易

继续看第三笔交易,交易hash为:https://cn.etherscan.com/tx/0xa0e7c8e933be65854bee69df3816a07be37e108c43bbe7c7f2c3da01b79ad95e

image

通过bloxy查看调用过程,https://bloxy.info/tx/0xa0e7c8e933be65854bee69df3816a07be37e108c43bbe7c7f2c3da01b79ad95e

image

第一次调用supply函数攻击者存入0.00043187,正常执行调用过程

第二次调用supply函数攻击者存入0.00000001,此时进行重入攻击,合约执行流程进入withdraw函数,攻击者调用withdraw函数取出攻击者的余额,第二笔交易的余额0.00043189 + 第一次调用supply存入的 0.00043187 = 0.00086376,然后合约执行流程在回到supply函数,完成存入操作

最后交易持续完成,攻击者的余额记录为0.00043189 + 0.00043187 + 0.00000001 = 0.00086377,手中已取走的0.00086376

从上面的联系三笔交易已经可以很清楚的看到,攻击者的每一次攻击,资产总和都是翻倍的,利用滚雪球的方式不断进行攻击,盗取 imBTC 的最后一笔交易如下图:

image

从上图可以看到,最终在交易 https://cn.etherscan.com/tx/0xced7ca813081fb594181469001a6aff629c5874bd672cca44075d3ec768db664 中,基本已达到 imBTC 的最大存量,此时将 Lendf.Me 账户中的 imBTC 资产盗取一空。

整个攻击过程原理图如下:

image

漏洞代码分析

下面我们分析一下 Lendf.Me 合约代码,攻击者是如何达到上面的攻击效果的。

首先看看 Lendf.Me 合约代码,合约地址:0x0eee3e3828a45f7601d5f54bf49bb01d1a9df5ea

看一下 Lendf.Me 合约的supply函数,在supply函数的开头,申请了临时变量localResults,然后将用户的余额保存在 localResults.userSupplyCurrent中,如下图所示:

image

在supply函数的最后,用户存入成功后,将用户的余额进行更新,此时最后用户的余额为localResults.userSupplyUpdated,如下图所示:

image

在更新用户余额之前,supply调用了 doTransferIn 函数,跟进 doTransferIn 函数:

image

在 doTransferIn 函数中,调用了imBTC合约的transferFrom函数,imBTC合约地址:0x3212b29e33587a00fb1c83346f5dbfa69a458923,跟进imBTC合约的 transferFrom 函数:

image

imBTC合约的 transferFrom 函数中,接着调用 _callTokensToSend 函数,跟进:

image

在 _callTokensToSend 函数中,通过ERC1820 注册 了ERC777Sender 实现接口, 因此这里必须调用用户的 tokensToSend 钩子函数,这里就是攻击者重入漏洞发生的地方,攻击者在这里调用了 Lendf.Me 合约的 withdraw() 函数,此时合约执行流程从 supply 进入到了 withdraw 函数中。

在 withdraw() 函数执行完后,继续回到supply调用了 doTransferIn 函数的后面继续执行,虽然在 withdraw() 函数中,用户取出余额之后,进行了余额数量更新,但是回到supply之后,继续执行后面的内容,那么在supply的最后再次更新了用户的余额,导致覆盖了用户 withdraw 之后余额数量的值。

具体合约代码进行重入攻击的流程如下图:

image

通过上面的攻击过程我们可以看到,攻击者的 withdraw() 调用是发生在第二次supply调用的 transferFrom 函数中,也就是在 Lendf.Me 合约中通过 transferFrom 调用用户的 tokensToSend() 钩子函数的时,攻击者在这里通过重入的方式调用了withdraw函数,造成了重入攻击。

事件总结

DeFi由于其高收益,去中心化等优势目前比较火爆,但仍处于发展初期,还有很多机制仍需不断去完善,DeFi项目很多,但是质量都是参差不齐,而且生态中组件众多,只要有一个模块出了问题,可能就会拖垮整个项目。

零时科技安全团队针对本次攻击事件,在此建议:

  1. 遵守严格的合约安全开发规范,在进行外部调用时先修改合约变量状态再进行外部调用;

  2. 项目上线前可通过专业的第三方安全团队进行全面的安全审计,尽可能的发现潜在的安全问题;

  3. 合约中加入风控体系,比如设置暂停开关,出现不可控问题时可及时止损;

发展后续

截止发稿,借贷平台Lendf.Me的攻击者(0xa9bf70a420d364e923c74448d9d817d3f2a77822),向借贷平台Lendf.Me的admin账户(0xa6a6783828ab3e4a9db54302bc01c4ca73f17efb)转回了126,014枚PAX,320枚HBTC, 381,162枚HUSD。

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容