研報丨硬核解析智能合約漏洞原理

2020-12-27 巴比特資訊

撰文:Chen Bo Yu、Hsu Tzu Hsiu

智能合約基礎介紹

在探討智能合約漏洞解析之前,我們先從一個基本的範例來了解一個智能合約會具備哪些元素。

● 變數:即此範例中的 balances,在這個合約中負責存儲使用者地址在合約中對應的存款餘額

● 函數:即此範例中的 getBalance,使用者呼叫此函數時,會回傳使用者在合約中的存款餘額

● 接收函數:即此範例中的 receive,這是一個內建的函數。當合約收到使用者傳入 ETH 且無呼叫其他函示時會觸發,此範例在觸發接收函數時,會變更變數 balances 的狀態,而函數中的 msg.sender 代表的是交易的發送者地址

● 回退函數:即此範例中的 fallback,這也是一個內建的函數。當使用者呼叫了不存在的函數時觸發,可以理解為例外處理函數。在此範例中,觸發時把交易回退,亦即讓交易失效。

常見漏洞解析

了解問題發生的原因,並且歸納問題的類別可以幫助我們更好的防範。DASP(Decentralized Application Security Project)收錄了十種智能合約漏洞,下面我們整理了其中最常見的合約漏洞以及新型態的攻擊模式。

1.重入漏洞

重入漏洞是最著名的智能合約漏洞,先前提到 The DAO 事件中也是為此原因而被駭客攻擊,該漏洞原理是通過循環調用一個函數而達到攻擊目的。

這邊展示的是一個簡單的提款函數,讓使用者可以根據合約裡的餘額(userBalances)取走存款。可以注意到的是,當這個函數的調用者為一智能合約的時候,提款操作(msg.sender.call)將會觸發該智能合約的 receive 函數,並把剩餘的 gas 傳入。而此時還未把使用者在原先智能合約中記錄的餘額歸零(userBalances[msg.sender] = 0),攻擊者即可在 receive 函數裡再次調用 withdrawBalance 函數,並通過餘額狀態尚未修改的漏洞達到重複取款的目的,直到 gas 耗盡或合約被掏空。

攻擊流程圖展示

防範方式也很簡單,只要先把智能合約紀錄的餘額做清空,再做轉帳動作,即可避免攻擊發生。

2.整數溢位漏洞

在以太坊智能合約中,uint256 是常見的整數型別,這意味著此變數可以儲存的整數範圍為 0 ~ 2^256 - 1,存儲上限大約是一個 78 位數的值,你可能會覺得這個數已經夠大了,但它仍然可被用來達成溢位,也就是說當一個變數的值為 2^256 - 1,而對這個變數的值又再進行加一的操作時,他的值會因為超過存儲上限而變為 0。要避免此漏洞,我們需要在整數運算前針對整數的範圍去做檢查,並在偵測到溢位運算時即時拋出異常。

3.阻斷服務攻擊

智能合約服務中斷是一個嚴重的問題,因為有些漏洞造成的服務中斷是永久性的,無法恢復。攻擊原理包括了:意外執行 SELFDESTRUCT 指令、訪問控制權限出錯、Gas limit 達到區塊上限使合約無法正常運作、以及我們這邊展示的利用異常拋出,造成合約永久性癱瘓。

這是一個簡單的拍賣合約示例,出價高者可以成為 currentLeader,並記錄該次競標出價為 highestBid,同時把先前的出價金額還給前一個競標領先者。攻擊者可以部署一個智能合約,在正常出價後讓該合約成為 currentLeader,並在合約內負責收款的 receive 函數中使用 revert 函數來拋出異常,讓交易失效。當其他使用者想出價競標時,會因為合約無法轉錢給 currentLeader(即攻擊者先前部署的合約),而造成交易失敗,拍賣合約的功能也因此永久失效,攻擊者得以贏下此次的拍賣競標。

攻擊者合約示例

4. Tx origin 漏洞攻擊

當開發者利用 solidity 中內建的 tx.origin 變數來驗證權限時,會讓攻擊者有攻擊的機會。在進入示例之前,須先了解 tx.origin 返回的是原始發送交易的地址,而msg.sender 返回的是當前交易的發送者。以下示意圖情景為:

用戶 A 呼叫了合約 B 內部的函數,並在函數內又再呼叫了合約 C。可以觀察 tx.origin 與 msg.sender 的差異。

接下來來看看實際的攻擊場景,上圖智能合約中的 sendTo 函數必須符合 tx.origin 與owner 相等的條件才會被執行,但是攻擊者可以通過下圖的智能合約,利用上述提過 tx .origin 與 msg.sender 的差異,巧妙地繞過驗證,並觸發 sendTo 函數。具體細節是當攻擊者誘導上圖合約的 owner 去觸發了下圖合約的 fallback 函數時,若攻擊合約在 fallback 函數內去調用 sendTo 函數,就可以得到 owner 的權限去執行。

5. 未適當處理external call的回傳值

在智能合約中,使用到低層級調用函數指令時,如:address.call、address.callcode、address.delegatecall 和 address.send 等等,如果調用失敗並不會拋出異常,僅會回傳調用結果的布林值,合約將能繼續往下執行。若未對調用結果的回傳值做檢查,可能將會使智能合約無法正常運作。

我們以一個簡單的取款函數作為示例,當使用一合約呼叫上圖的 withdraw 函數,且若該合約不能接收 ETH 轉入(例如無設置 payable)時,會造成呼叫方無法收到 ETH ,但因合約會繼續往下執行,導致其在合約中 balances 的狀態紀錄被改變。修正寫法如下:

6. 短地址攻擊

此攻擊手法大多出現在 ERC-20 (代幣標準協定)智能合約中,須先了解到,當我們呼叫一個函數時,在 EVM (以太坊虛擬機)裡實際上是在解析一堆 ABI(Application Binary Interface)字符。而一般 ERC-20 標準的代幣都會實現用來轉帳的 transfer 函數,當我們調用 transfer 函數時,交易的調用內容由 3 個部分組成:

● 4 字節,函數名的哈希值,例如:a9059cbb

● 32 字節,以太坊地址(地址為 20 字節,高位補零),例如:

00000000000000000000000011223344556677889900aabbccddeeff11223344

● 32 字節,代表需要轉送的代幣數量:

0000000000000000000000000000000000000000000000000de0b6b3a7640000

若攻擊者地址為:0x1234567890123456789012345678901234567800(尾數為零),且在呼叫 transfer 時刻意捨去尾數零,若合約內沒有對內容格式做檢查,EVM 讀取時會從第三個參數(代幣數量)的高位拿 00 來補充,這將造成實際想要轉送的代幣數量缺少一個字節,即向左移位了 8 個比特,數值瞬間擴大 256 倍,攻擊者成功盜取代幣合約中的代幣。

7.閃電貸攻擊

閃電貸,顧名思義就是快速貸款,那這個速度有多快呢?官方的解釋是,貸款發行和償還的交易必須在以太坊上同一個區塊內完成。可以說閃電貸是一種藉助於區塊鏈技術的顛覆式創新,它與傳統的借貸有兩個主要的差別,一個是它無需抵押品,第二個是它要求要在執行借出的同一筆交易中執行還款操作,因此對於出藉資金的那方來說是不用承擔違約風險的,因為只有當區塊鏈上借貸方執行的借出與還款操作都確實被執行了,這筆交易才有效。也就是說我們可以設計一個智能合約來借出資金,接著執行一些資金操作,最後在將資金歸還,而這些操作都會在同一筆交易中完成。這就給黑客們帶來了利用閃電貸發動攻擊的機會,因為它大大的降低了黑客的攻擊成本,近期在 DeFi 領域的多數攻擊都是使用閃電貸來實現,主要都是黑客通過借出的巨額資金來對協議製造價差並從中套利,還款後再帶著不當獲利逃之夭夭。我們從 bZx 攻擊事件來了解黑客的攻擊思路:

1. 黑客通過閃電貸從去中心化數字資產衍生交易平臺 dYdX 借出了一萬枚 ETH

2. 使用其中的 5000 枚 ETH 抵押在去中心化借貸平臺 Compound 以借出 112 枚 wBTC(Wrapped BTC,即以太坊上的BTC跨鏈資產)

3. 剩下的的 5000 枚 ETH 到去中心化借貸平臺 bZx 上開了 wBTC 的空單

4. 用借出的 112 枚 wBTC 到去中心化交易所 Uniswap 砸盤,讓 wBTC 價格快速下跌

這一系列操作讓黑客在 bZx 上開的空單倉位大賺,接著歸還閃電貸借出的一萬枚 ETH,並在這個過程中獲得了價值 35 萬美元的收益。此次攻擊的主要原因是因為 Uniswap 的價格的劇烈變化最終導致資產的損失,這本該是正常的市場行為,但是黑客通過惡意操縱市場,使項目方造成損失。bZx 合約被操縱一事,開始讓閃電貸進入了更多開發者的視線,一方面許多聰明的開發者開發出了全新的去中心化金融應用,同時也讓開發者更為警惕可能的邏輯攻擊。

結論

智能合約的運作為被動的,所有的合約動作均須由使用者發起交易、呼叫合約中的函數函數才會執行動作,而合約執行基於區塊鏈的特性是不可逆的,且當合約部署上區塊鏈後,所有資料都是公開透明的,即便代碼不開源,也可利用反組譯工具回推合約內容。因此,開發者需熟悉漏洞原理並避免之,使用者也應了解合約安全議題,維護自身權益。

相關焦點

  • ERC20智能合約又現大量整數溢出漏洞
    今日塊訊(Chinaz.com) 6 月 13 日消息    近期,智能合約漏洞頻頻發生,繼EDU、BAI智能合約存漏洞可轉走任意帳戶Token 、EOS高危漏洞可完全控制虛擬貨幣交易等事件後,今天ERC20 智能合約又被爆出現大量整數溢出漏洞。
  • 零時科技丨CTF技能寶典之智能合約 整數溢出漏洞
    前言近年來,各個大型CTF(Capture The Flag,中文一般譯作奪旗賽,在網絡安全領域中指的是網絡安全技術人員之間進行技術競技的一種比賽形式)比賽中都有了區塊鏈攻防的身影,而且出現的題目絕大多數都是區塊鏈智能合約攻防。此系列文章我們主要以智能合約攻防為中心,來剖析智能合約攻防的要點,前兩篇我們分享了合約反編譯,反彙編的基礎內容。
  • 兩大智能合約籤名驗證漏洞分析
    可重入(Reentrancy)或整數溢出漏洞,是大多數開發人員知道或者至少聽說過的,關於智能合約當中容易出現的安全問題。另一方面,在考慮智能合約的安全性時,你可能不會立即想到針對密碼籤名實現的攻擊方式。它們通常是與網絡協議相關聯的。
  • EDU出現漏洞,火幣Pro:對ERC20智能合約代碼進行覆審
    EDU出現漏洞,火幣Pro:對ERC20智能合約代碼進行覆審 今日塊訊(Chinaz.com) 5 月 24 日消息    針對EduCoin智能合約出現的新型漏洞相關問題
  • CTF技能寶典之智能合約 重入漏洞
    前言近年來,各個大型CTF(Capture The Flag,中文一般譯作奪旗賽,在網絡安全領域中指的是網絡安全技術人員之間進行技術競技的一種比賽形式)比賽中都有了區塊鏈攻防的身影,而且出現的題目絕大多數都是區塊鏈智能合約攻防。此系列文章我們主要以智能合約攻防為中心,來剖析智能合約攻防的要點,前兩篇我們分享了合約反編譯,反彙編的基礎內容。
  • 危及ERC20智能合約、讓代幣價值歸零的溢出漏洞到底是什麼?
    7月8日下午,降維安全實驗室(johnwick.io)監控到,以太坊智能合約AMR存在高危風險交易。團隊對代碼進行分析,發現其中存在的整數溢出漏洞已被人惡意利用,導致AMR大量增發。今年4月份,攻擊者也曾利用該漏洞攻擊美圖合作的美鏈BEC,導致市場上頓時出現海量BEC,貨幣價值幾乎歸零。 那麼,整數溢出漏洞是什麼?可以從我們熟悉的登陸密碼說起。 程序怎麼判斷用戶輸入密碼的正誤呢?後臺的操作是這樣的,先讓用戶輸入密碼,然後再調取真正的密碼,與之對比,如果差異為0,則輸出密碼正確,否則錯誤。
  • Hardcore|以太坊中智能合約攻擊和漏洞百科全書
    作為一種新興的、實驗性的技術,智能合約當然也受到了相當多的攻擊。為了防止進一步的攻擊,我列出了幾乎所有已知的攻擊和漏洞的列表。儘管此列表可能包含已知的攻擊,但新的漏洞仍在定期發現,因此,這應該只是您作為工程師研究智能合約安全性的開始。攻擊在本節中,我們將介紹可用於利用智能合約漏洞的已知攻擊。
  • Hardcore | 以太坊中智能合約攻擊和漏洞百科全書
    作為一種新興的、實驗性的技術,智能合約當然也受到了相當多的攻擊。為了防止進一步的攻擊,我列出了幾乎所有已知的攻擊和漏洞的列表。儘管此列表可能包含已知的攻擊,但新的漏洞仍在定期發現,因此,這應該只是您作為工程師研究智能合約安全性的開始。攻擊在本節中,我們將介紹可用於利用智能合約漏洞的已知攻擊。
  • 首發| SushiSwap仿盤 YUNO與KIMCHI智能合約漏洞或存安全隱患
    北京時間8月31日和9月1日,CertiK安全研究團隊發現Sushiswap仿盤的兩個項目YUNo Finance (YUNO)與KIMCHI.finance (KIMCHI),其智能合約均存在漏洞。如果利用該漏洞,智能合約擁有者可以無限制地增發項目對應的代幣數目,導致項目金融進度通脹並最終崩潰。
  • 多個ERC20智能合約被曝出新的allowAnyone漏洞(CVE-2018-11397,CVE...
    PeckShield公司的漏洞掃描系統迄今為止已經發現了多種高危的智能合約漏洞(batchOverflow[1],proxyOverflow[2],transferFlaw[3],ownerAnyone[4],multiOverflow[5]),burnOverflow[6]),ceoAnyone
  • EDU 智能合約出現重大漏洞,可轉走任意帳戶的 EDU Token
    又雙叒叕有智能合約曝出漏洞了。據慢霧區最新消息,EDU 智能合約出現重大漏洞,可轉走任意帳戶的 EDU Token。目前已經發現有黑客的大量洗劫行為,攻擊者不需要私鑰即可轉走你帳戶裡所有的 EDU,並且由於合約沒有 Pause 設計,導致無法止損。
  • 受太坊智能合約漏洞影響,OKEx暫停所有ERC-20 Tokens充值
    受太坊智能合約漏洞影響,OKEx暫停所有ERC-20 Tokens充值 今日塊訊(Chinaz.com) 4 月 25 日消息    今日早間,因SMT的以太坊智能合約存在漏洞
  • 慢霧區:EDU、BAI智能合約存漏洞,可轉走任意帳戶Token ​​...
    首頁 > 塊訊 > 關鍵詞 > EDU最新資訊 > 正文 慢霧區:EDU、BAI智能合約存漏洞,可轉走任意帳戶Token ​​​​
  • 首發| CertiK:我們每天遇到有漏洞的DeFi合約概率是多少 審計後又...
    智能合約當中,任何一個小bug,都可能會給項目或者投資者造成無法挽回的損失。受此警示之下,CertiK安全團隊利用CertiK天網系統 (Skynet),對自北京時間2020年12月4日0時至24時之間,新加入Uniswap的代幣智能合約進行了監控分析。在本次分析的時間段內,一共產生了29個智能合約代幣項目。
  • TRONCOIN波場幣智能合約怎麼樣
    目前市面上有很多智能合約的盤: troncoin波場幣智能合約跟其他項目如何對比 ①合約佔比率:就是手續費能量消耗的那個合約佔比率,一般很多的智能合約,能量消耗的:合約佔比率0%,或者是只有1%。而用戶佔比率100%,甚至99%‼️ 第一點:為什麼查詢合約地址,我們要先看這一點呢?
  • 波場鏈Tronchain智能合約是真的嗎?真實性怎麼查詢
    關于波場鏈Tronchain智能合約的真實性,它的合約地址是真的嗎?它的真實性怎麼查詢?我是阿諾(V 34524631),再這裡,我教大家怎麼去求證場鏈Tronchain智能合約的真實性。本著對團隊和市場負責,更有公信力,除了波場鏈自己找的第三方審查系統,我們自掏腰包,也找了國內的區塊鏈合約審計公司,四川知道創宇雲安全進行審計,確保萬無一失。
  • 常見的三種智能合約攻擊手法介紹
    智能合約 Smart Contract 智能合約(Smart Contract)並不是一個新的概念,早在 1995 年就由跨領域法律學者 Nick Szabo 提出:智能合約是一套以數字形式定義的承諾(Promises),包括合約參與方可以在上面執行這些承諾的協議。
  • 美國安全審計公司CERTIK完成去中心化借貸協議TLC智能合約代碼審計
    CERTIK官網公告信息:美國當地時間11月6日,美國區塊鏈安全審計公司CERTIK完成Super Trister去中心化借貸協議TLC智能合約代碼審計,並發布安全審計報告,審計結果未發現重大或關鍵或主要漏洞。
  • 美國安全審計公司CERTIK完成去中心化借貸協議TLC智能合約代碼審計...
    CERTIK官網公告信息:美國當地時間11月6日,美國區塊鏈安全審計公司CERTIK完成Super Trister去中心化借貸協議TLC智能合約代碼審計,並發布安全審計報告,審計結果未發現重大或關鍵或主要漏洞。
  • 智能合約開發solidity程式語言開發一個以太坊應用區塊鏈投票實例
    智能合約開發用solidity程式語言部署在以太坊這個區塊鏈平臺,本文提供一個官方實戰示例快速入門,用例子深入淺出智能合約開發,體會以太坊構建去中心化可信交易技術魅力。智能合約其實是「執行合約條款的計算機交易協議」。區塊鏈上的所有用戶都可以看到基於區塊鏈的智能合約。