OKC 项目被攻击事件分析

2024-01-04 09:55 0 比特币

来源:零时科技

事件背景

2023-11-13 18:51:57 (UTC) 链上发生一笔针对 OKC Token 的攻击事件,黑客通过存在缺陷的MinerPool获取了及时收益

黑客攻击交易:

0xd85c603f71bb84437bc69b21d785f982f7630355573566fa365dbee4cd236f08

黑客攻击合约1:

0xD5d8c2fd8A743A89BC497B2F180C52d719a007B9

黑客攻击合约2:

0x617432Fc98c1fFaAB62B8cB94Cef6D75ABD95598

黑客攻击合约3:

0x28e7c8337373C81bAF0A4FE88ee6E33d3C23E974

攻击者地址:

0xbbcc139933D1580e7c40442E09263e90E6F1D66D

漏洞合约:

0x36016C4F0E0177861E6377f73C380c70138E13EE (MinerPool)

攻击分析

通过对链上交易数据分析,我们对其交易进行整理归纳。

黑客首先通过多个闪电贷进行对攻击资金的筹集,共借款 2,753,399 USDT Token。

ZYJ9EJ7zSlQkh42MbEpDrv7Of7hp3mRaKbGn0fX1.png

随后立即将其中 130,000 USDT Token 兑换为一个最小单位的 USDT Token 和 27,264 OKC Token 。

由于 PancakeSwapv2 使用的是AMM(恒定函数做市商),在该模型中,交易池中的两种代币的数量乘积是一个常数。可以用以下公式表示:

FUlnRbhott8oGR5hf8CmOFebMjO6qh72pGKdKsn2.png

其中:

• x是交易池中第一种代币的数量。

• y是交易池中第二种代币的数量。

• k是一个常数,表示池中两种代币数量的乘积。

当一个交易者想要用一种代币兑换另一种代币时,他们会增加交易池中一种代币的数量(dx),同时减少另一种代币的数量(dy),以保持的不变性。这个过程会改变代币的相对价格。

假设交易者想要用代币A兑换代币B,那么在交易前后,恒定乘积公式应该保持成立:

KsCNaoluMDjOCbYz3seW6EWE3ZSsLkutOxr5SUHF.png

由于k是不变的,这意味着x·y在交易前后是相同的。但是,因为交易者增加了代币A的数量(dx)并且减少了代币B的数量(dy),这将导致代币B的价格上升。

代币的即时价格可以通过计算池中两种代币数量的比率来得出。如果代币A是x,代币B是y,则代币B相对于代币A的价格是y/x。在交易之后,代币B的数量减少了,代币A的数量增加了,所以新的价格变成了(y-dy)/(x+dy) 。由于分子减小而分母增大,这个比率变小了,意味着代币B的价格上升。

在大额交易的情况下,dx和dy可能非常大,这会导致价格的显著变动。这是因为为了保持k的不变,必须从池中移除大量的dy来补偿dx的增加。这种大额交易对池中代币数量的巨大影响导致了价格的显著变化。

故攻击者通过使用大额闪电贷资金进行买入OKC,导致 OKC 数量减少,从而拉高了 OKC Token 的价格,将 1 OKC = 0.3 USDT 的价格提升到 1 OKC = 68.9 USDT。

8LlWppuslA8GJKGyBaAX0hbys9bFhOJ46K6Ax8PG.png

后攻击者创建了两个合约地址,并分别向两个地址中发送了 0.01 OKC 和 0.0001 USDT 和 一个最小单位的OKC。

1kxwBOESdIzzvpimwSTBWTFttaSaPjLRjNJXvKSn.png

OG3glLu8jv6WONgSCIikncEqIG5pO5ik19WOc1ni.png

然后黑客使用主要的攻击合约对 PancakePair_USDT_OKC 池子添加流动性操作,得到约 225,705 个LP Token。

PlObjhXMg6uQSkWWebGu0LCQdoTXgyYIZWLfmUjW.png

随后将 LP Token 全部转移至 攻击者创建的 0x28e7c8337373C81bAF0A4FE88ee6E33d3C23E974 攻击合约中随后立即调用漏洞合约中的 processLPReward 函数,对合约内存储的 lpHolder 地址进行奖励分配。此处虽然攻击者的操作只是向 MinerPool 合约转账,但是该合约在接受转账的回调函数中调用了processLPReward 函数。

vDBl8L0Ifxh6wcGYqQ9dH0vIzYlPDwZf0HWIcwAi.png

Snp2pP8p7JF6WXlIv25g3sxFlLjTGRZqYvhzclH7.png

根据下图,我们得知攻击合约 0x28e7c8337373C81bAF0A4FE88ee6E33d3C23E974 在奖励领取中获得了 77,890 个 OKC Token。

23losGU5d3Jcq6MvkuXZLpjl2P5FvfkZp0H9FwNf.png

然后攻击者转出攻击合约 0x28e7..E974 的的 LP Token 并将其销毁移除流动性,获得了 1,884,223 USDT Token,以及 27,264 OKC Token。

并转移出另外两个攻击合约中的所有的Token至主要攻击合约

0xD5d8c2fd8A743A89BC497B2F180C52d719a007B9 ,分别为:272 个,77,890 个 OKC Token。

SCaR8wzHOTbVnQVaNhz12W38JiHVoO4o1E4SsLOK.png

黑客将所有的OKC ,约 104,610 OKC Token 兑换为约 136,518 USDT Token,此时黑客总持有约 2,759,918 USDT Token。

csLUQVuXBIP0CqcTeOE1Fac0Wzv0z6ke0SiiVWme.png

最后,黑客归还所有闪电贷的本金和利息,最终剩余约 6,268 USDT Token,并全部转移至攻击者地址

0xbbcc139933D1580e7c40442E09263e90E6F1D66D。

EQP3Gepcsoic1TR7xTBvnEdVEnyG9J37niWHoGBD.png

漏洞分析

通过攻击分析得知,黑客主要获利资金是由 MinerPool 合约中 processLPReward 函数,该函数逻辑主要是获取 lpHolder 并根据其 LP 数量直接按比例进行奖励。

我们可以看一下攻击者创建的第三个攻击合约中的执行逻辑:

H4VoWXjmfsqBjvUKP580Y5aOhOdJvCxA7iCyGWhb.png

从该处逻辑可以看出addHolder函数中使用了 extcodesize() 来计算地址当前的大小,用来判断地址是否是合约地址,但是在攻击者通过 CREATE2 创建合约,由于合约在初始化时,该地址大小依然为0,从而来攻击者在其构造函数中调用该函数绕过其中的合约调用限制。

JpTMCfydXfaAj2OhxVZKnC2cr2xTtI04TzTdUiH4.png

其在转账时调用了 addHolder 函数将 合约地址添加到了 lpHolder 名单,所以该合约才可以通过领取奖励获取及时的OKC奖励。

根据对 processLPReward 函数代码逻辑进行分析,可以从下图中看出,虽然设置了领取奖励的锁定时间,但是未设置 LP 持有时间进行校验或限制,导致黑客通过闪电贷获取大量临时资金,并兑换为LP ,并在领取奖励后立即销毁。

ivCDG4ELmDNZTlWMNpCx3PAErY6d3kLNZPmCO7Ut.png

总结

简单来说,黑客通过闪电贷借了大量USDT,并兑换大量OKC,从而拉高了OKC的价格。并且由于OKC项目未设置LP奖励发放的锁仓要求,所以黑客在获取奖励后立刻撤回流动性,从而获取了项目方发放的流动性提供者的奖励。并将OKC项目方奖励的OKC Token出售。最终获利 6,268 USDT。

本站登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不构成投资建议。投资者据此操作,风险自担。