聊聊慢雾VETH 合约被黑分析

前言然而换言之,我们应该深入了解数字货币交易所代理返佣的发展规律,为整个行业带去新的生机,让市场焕发生机。
2020 年 7 月 1 日,veth 合约遭遇黑客攻击。慢雾安全团队在收到情报后对本次攻击事件进行了全面的分析,下面为大家就这次攻击事件展开具体的技
前言
2020 年 7 月 1 日,veth 合约遭遇黑客攻击。慢雾安全团队在收到情报后对本次攻击事件进行了全面的分析,下面为大家就这次攻击事件展开具体的技术分析。
攻击细节
本次攻击交易如下 0xdd1120a90ed4112b634266d6a244b93ca86785317bc75f0e170ab0cd97c65224
通过交易概览可以看到攻击者在 uniswap 中使用 09 eth 兑换成 veth,然后使用 veth 在 vether 合约中进行操作,最终盗走巨额的 veth。
现在使用 oko 合约浏览器对具体的攻击细节进行分析(下图只展示一部分)okopalkeocom0xdd1120a90ed4112b634266d6a244b93ca86785317bc75f0e170ab0cd97c65224
通过分析交易内具体的细节可以发现:攻击者先创建了一个合约0x47ed415006c6f8052fff05fe983f31d6d24b8fdb 通过此合约对 vether 合约中的 changeexcluded(unknown37217349) 函数与 transferfrom 函数进行了调用。
接下来对这两个函数的具体代码进行分析:
function transferfrom(address from, address to, uint value) public override returns (bool success) {
if(!mapaddress_excluded[msgsender]){
require(value <= _allowances[from][msgsender], 'must not send more than allowance');
_allowances[from][msgsender] -= value;
}
_transfer(from, to, value);
returntrue;
}
可以看到在 transferfrom 函数中,先对 mapaddress_excluded[msgsender] 进行了 if 判断,具体逻辑是mapaddress_excluded[msgsender]为 false 时,将会检查对攻击者合约的授权额度,然后调用_transfer函数进行转账。而这个逻辑显然走不通,攻击者合约是没有任何授权额度的。因此mapaddress_excluded[msgsender]只能为 true ,然后直接调用_transfer函数进行转账。
接下来具体分析该如何将mapaddress_excluded[msgsender]设置为 true:
通过查看合约可以发现:
合约在初始化时只将address(this)和burnaddress的mapaddress_excluded置为 true,那么可以肯定还有其他逻辑可以设置mapaddress_excluded,通过分析 vether 合约可以发现changeexcluded函数可以实现对mapaddress_excluded的设置。
function changeexcluded(address excluded) external {
if(!mapaddress_excluded[excluded]){
_transfer(msgsender, address(this), mapera_emission[1]16);
mapaddress_excluded[excluded] = true;
excludedarraypush(excluded); excludedcount +=1;
totalfees += mapera_emission[1]16;
mapaddress_blockchange[excluded] = blocknumber;
} else {
_transfer(msgsender, address(this), mapera_emission[1]32);
mapaddress_excluded[excluded] = false;
totalfees += mapera_emission[1]32;
mapaddress_blockchange[excluded] = blocknumber;
}
}
通过分析changeexcluded函数可以发现其可见性为external,因此攻击者合约可以直接调用changeexcluded函数,此时攻击者合约的mapaddress_excluded为 false,所以会进入 if 的逻辑中。
接下来对 if 逻辑内的代码进行具体分析:
在进行 if 逻辑后需要先支付手续费,具体为上方代码块中的第 3 行,那这个手续费是从哪里来呢?答案就是攻击者最初转入合约中的 09 eth。
图中可以看到,通过 09 eth 兑换成约 138 veth。
通过计算代码中的mapera_emission[1]16我们可以得到攻击者需要支付的手续费:我们读取合约中的 mapera_emission可以知道 mapera_emission[1]为 2048。
此时计算mapera_emission[1]16可得手续费为 204816 = 128 veth,而攻击者兑换了约138 veth 是足够用来支付手续费的,因此便可以通过上方代码块中的第 4 行将攻击者合约的mapaddress_excluded置为 true。
完整的攻击流程如下:
1 创建攻击合约,通过 uniswap 将 09 eth 兑换成约138 veth(此处换币为了后续支付手续费)
2 调用 vether 合约中的changeexcluded函数并利用先前在 uniswap 兑换的约 138 veth 支付 128 veth 的手续费,然后将mapaddress_excluded置为 true
3 调用 transferfrom 函数,利用mapaddress_excluded为 true,直接进行转账操作
4 拿钱走人
黑客地址:
0xfa2700e67065bc364136b5e7f57112083cb2a0cd
攻击交易:
0xdd1120a90ed4112b634266d6a244b93ca86785317bc75f0e170ab0cd97c65224
veth 合约地址
0x75572098dc462f976127f59f8c97dfa291f81d8b
修复建议
此次攻击主要利用 vether 合约中changeexcluded函数的可见性为external且未有权限限制,用户可以直接进行外部调用为攻击创造了必要的条件。因此应做好对changeexcluded函数的权限或可见性的限制,从而避免任意用户可以直接外部调用changeexcluded函数。