SIM token 自动化薅羊毛攻击分析

链得得APP

发布时间:18-08-0710:30

事件回顾:

前段时间追踪到了以太坊token中的首个自动化薅羊毛攻击事件。被攻击的合约地址已发出。token名称为Simoleon (SIM),截止当时已有接近57万账户持有该合约的token:

经过深入的分析了解,最终发现了攻击者对以太坊的理解非常深刻,其通过部署攻击合约获得了超过700万的token,从57万账户中脱颖而出,一举成为该合约token的第四大持有者:

被攻击的合约Simoleon

在token发行过程中,为增加人气发行方可能会选择空投,即在一定时间窗口和投放总量的条件下免费给参与地址发送一定数量的token。Simoleon合约也加入了空投,在总量发放完之前,任何未接受过该token空投的账户都可以调用本合约的transfer函数给指定账户地址免费转账token:

漏洞分析:

在transfer()中首先调用了initialize():

initialize()作用是判断参与账户是否接收过空投,没有接受过就给参与账户空投一定数量的代币,再标记参与账户以接收空投,以免重复空投被薅羊毛。

看似一段比较正常的代码逻辑,但是开发者忽略了一个问题:钱包账户是可以无条件创建的。

Simoleon合约对已经发放token的地址都进行了记录,因此每个地址只能免费获得1万的token。要获得更多的数量,就需要创建很多新账户,然后利用这些新账户调用Simoleon合约的transfer函数给指定账户来获得大量token。如果通过创建EOA账户来进行薅羊毛,则每个账户都需要一些以太币,否则EOA账户就没有gas去调用Simoleon合约的transfer函数,也就无法薅羊毛。显然,这样不仅步骤繁琐,而且每一笔交易都会产生手续费,增加了不必要的成本。

攻击者在这里采用了一种精妙的攻击手法:首先部署一个恶意合约,在恶意合约中生成临时合约,临时合约调用SIM token中的transfer(),因为临时合约账户没有进行过交易,会触发initialize()进行空投。获得空投后,临时合约账户将空投获得的代币转入攻击者账户,最后临时合约销毁。

这是攻击一次的流程,攻击者一次生成了50个临时合约薅羊毛,效率比手工高太多了。

果然,知识才能解放双手啊。

经过分析,找到原因就在Simoleon合约的transfer函数,合约在空投的时候也会对目标地址进行免费发送token,但是这个发放却没有调用Transfer事件:

于是,攻击合约的token变化过程如下:

攻击合约被创建,token为零。第1个临时合约初始化时调用Simoleon的transfer函数,由空投的1万加上临时合约发送的1万构成。第2个临时合约初始化时调用Simoleon的transfer函数,由先前2万加临时合约发送的1万构成。攻击者从攻击合约提取全部token,提取总量token为3万。

总结

Simoleon合约能被自动化的薅羊毛,最根本的原因在于其合约代码的空投奖励函数没有任何权限控制,任意未领过空投的账户都可以直接调用Simoleon合约来获取。因此,攻击者可以利用攻击合约来创建大量账户来领取。一种缓解办法是给空投奖励函数设置权限控制,比如只有合约创建者才能给目标地址发放token。

区块链的特性决定了合约代码一经部署就无法修改,无论是合约的开发者,还是投资者,还是交易平台,都应当对合约进行多重安全审计,尽量在上链前消除安全风险。

返回顶部