背景
北京時(shí)間2022年9月10日,DPC代幣合約遭到黑客攻擊,損失超73,614 BUSD, 零時(shí)科技安全團(tuán)隊(duì)及時(shí)對(duì)此安全事件進(jìn)行分析,詳情可移步至分析文章“零時(shí)科技 || DPC攻擊事件分析”。
DPC合約簡(jiǎn)介
DPC合約是一個(gè)ERC20代幣合約,合約提供兌換、轉(zhuǎn)移代幣等功能。用戶可以使用USDT兌換獲得DPC代幣,將DPC代幣與USDT進(jìn)行質(zhì)押來獲得DPC代幣獎(jiǎng)勵(lì)。
漏洞核心
由于DPC合約中計(jì)算獎(jiǎng)勵(lì)算法存在漏洞,攻擊者通過質(zhì)押流動(dòng)性代幣獲得獎(jiǎng)勵(lì),通過調(diào)用函數(shù)取出代幣時(shí)進(jìn)行獎(jiǎng)勵(lì)累加,在合約中取出任意數(shù)量代幣都會(huì)進(jìn)行獎(jiǎng)勵(lì)累加操作且對(duì)于操作沒有頻率的限制,并且在獎(jiǎng)勵(lì)累加時(shí)會(huì)進(jìn)行兩次累加操作,使得計(jì)算獎(jiǎng)勵(lì)時(shí)會(huì)翻倍增加。
1.通過質(zhì)押代幣將oldClaimQuota[] 與 dpcLp[]賦值
2.調(diào)用claimStakeLp()函數(shù)計(jì)算獎(jiǎng)勵(lì)
3. getClaimQuota()函數(shù)中可以看到再次執(zhí)行了ClaimQuota的加法操作,調(diào)用一次計(jì)算獎(jiǎng)勵(lì)函數(shù)時(shí)會(huì)給獎(jiǎng)勵(lì)進(jìn)行翻倍。
漏洞測(cè)試
攻擊合約核心代碼
測(cè)試結(jié)果
攻擊合約初始資金為204代幣,向被攻擊合約質(zhì)押200代幣后調(diào)用攻擊函數(shù),每調(diào)用一次攻擊函數(shù)向被攻擊合約轉(zhuǎn)移1個(gè)代幣實(shí)現(xiàn)獎(jiǎng)勵(lì)累加,調(diào)用四次攻擊函數(shù)后獲得的獎(jiǎng)勵(lì)為321代幣,將獎(jiǎng)勵(lì)提取至被攻擊合約。
漏洞預(yù)防
在計(jì)算獎(jiǎng)勵(lì)的函數(shù)中設(shè)置獎(jiǎng)勵(lì)計(jì)算的頻率,并且設(shè)置每次調(diào)用函數(shù)時(shí)傳入?yún)?shù)的最小值,避免攻擊者可以通過轉(zhuǎn)移小額代幣就可以實(shí)現(xiàn)獎(jiǎng)勵(lì)的累加。
將計(jì)算獎(jiǎng)勵(lì)函數(shù)中累加計(jì)算改為只進(jìn)行函數(shù)調(diào)用,避免一次調(diào)用函數(shù)實(shí)際進(jìn)行了兩次獎(jiǎng)勵(lì)累加。
修改之后用同樣的攻擊方法獲利只有38代幣,為正常應(yīng)獲得的獎(jiǎng)勵(lì)數(shù)額。