隨著越來越的人參與到區(qū)塊鏈這個行業(yè)中來,為行業(yè)注入新活力的同時也由于相關知識的薄弱以及安全意識的匱乏,給了攻擊者更多的可乘之機。面對頻頻爆發(fā)的安全事件,慢霧特推出區(qū)塊鏈安全入門筆記系列,向大家介紹區(qū)塊鏈安全相關名詞,讓新手們更快適應區(qū)塊鏈危機四伏的安全攻防世界。
短地址攻擊 Short Address Attack短地址攻擊(Short Address Attack)是針對以太坊上ERC20智能合約的一種攻擊形式,利用的是EVM中的對于輸入字節(jié)碼的自動補全機制進行攻擊。
一般而言,針對 ERC20 合約中的 transfer 函數(shù)的調(diào)用,輸入的字節(jié)碼位數(shù)都是 136 字節(jié)的。當調(diào)用 ERC20 中的 transfer 函數(shù)進行 ERC20 Token 轉(zhuǎn)賬時,如果攻擊者提供的地址后有一個或多個 0,那么攻擊者就可以把地址后的零省去,提供一個缺位的地址。當對這個地址轉(zhuǎn)賬的時候,比方說轉(zhuǎn)賬 100 的 A Token,然后輸入的地址是攻擊者提供的缺位地址,這時候,經(jīng)過編碼輸入的數(shù)據(jù)是 134 字節(jié),比正常的數(shù)據(jù)少了 2 字節(jié),在這種情況下,EVM 就會對缺失的字節(jié)位在編碼數(shù)據(jù)的末尾進行補 0 湊成 136 字節(jié),這樣本來地址段缺失的 0 被數(shù)據(jù)段的 0 補齊了,而由于給地址段補 0,數(shù)據(jù)段會少 0,而數(shù)據(jù)段缺失的 0 由 EVM 自動補齊,這就像數(shù)據(jù)段向地址段移動補齊地址段缺失字節(jié)位,然后數(shù)據(jù)段缺失的字節(jié)位由 EVM 用 0 補齊。這種情況下,轉(zhuǎn)賬金額就會由 100 變成 100 * 16 的 n 次方,n 是地址缺失的 0 的個數(shù)。通過這種方式,攻擊者就能對交易所或錢包進行攻擊,盜竊交易所和錢包的資產(chǎn)。
慢霧安全團隊建議交易所和錢包在處理轉(zhuǎn)賬的時候,要對轉(zhuǎn)賬地址進行嚴格的校驗,防止短地址攻擊的發(fā)生。詳情可參考:遺忘的亞特蘭蒂斯:以太坊短地址攻擊詳解
假幣攻擊 Fake Token Attack假幣攻擊(Fake Token Attack),是針對那些在創(chuàng)建官方 Token 時采用通用創(chuàng)建模版創(chuàng)建出來的代幣,每個 Token 的識別僅根據(jù)特定的標記進行識別,如 EOS 官方 Token 的識別標記是 “eosio.token”合約,波場的 TRC10 的識別標記是 tokenid,以太坊的 ERC20 是用合約地址作為識別標記。那么這樣就會出現(xiàn)一個問題,如果收款方在對這些 Token 進行收款的時候沒有嚴格校驗這些 Token 特有的標記,攻擊就會發(fā)生,以 EOS 為例子,由于 EOS 官方 Token 采用的是合約來發(fā)行一個名為 EOS 的 Token,標記 EOS 本身的標識是 “eosio.token” 這個發(fā)行帳號,如果在接受轉(zhuǎn)賬的時候沒有校驗這個標識,攻擊者就能用其他的帳號同樣發(fā)行一個名為 EOS 的 Token,對交易所或錢包進行假幣充值,換取真的代幣。
2019 年 4 月 11 日,波場 Dapp TronBank 1 小時內(nèi)被盜走約 1.7 億枚 BTT(價值約 85 萬元)。監(jiān)測顯示,黑客創(chuàng)建了名為 BTTx 的假幣向合約發(fā)起“ invest ”函數(shù),而合約并沒有判定發(fā)送者的代幣 id 是否與 BTT 真幣的 id 1002000 一致。因此黑客拿到真幣 BTT 的投資回報和推薦獎勵,以此方式迅速掏空資金池。對此,交易所和錢包在處理轉(zhuǎn)賬的時候,切記要嚴格檢驗各種代幣各種標識,防止假幣攻擊。
整型溢出攻擊 Integer Overflow Attack數(shù)據(jù)的存儲是區(qū)塊鏈上重要的一環(huán)。但是每個數(shù)據(jù)類型本身是存在邊界的,例如以太坊中 uint8 類型的變量就只能存儲 0~255 大小的數(shù)據(jù),超過了就存不下了。那么如果要放一個超過數(shù)據(jù)類型大小的數(shù)字會怎樣呢?例如把 256 存進 uint8 的數(shù)據(jù)類型中,數(shù)據(jù)顯示出來會變成 1,而不是其他數(shù)值,也不會報錯,因為 uint8 本身能存一個 8 位二進制數(shù)字,最大值為 11111111,如果這個時候加 1,這個二進制數(shù)就變成了 100000001,而因為數(shù)據(jù)邊界的關系,只能拿到后 8 位,也就是 00000001,那么數(shù)字的大小就變成 1 了,這種情況我們稱為上溢。有上就有下,下溢的意思就是一個值為 0 的 uint8 數(shù)據(jù),如果這個時候?qū)λM行減 1 操作,結果會變成該數(shù)據(jù)類型所能存儲的最大值加 1 減去被減數(shù),在這個例子中是 255,也就是該數(shù)據(jù)類型所能存儲的最大值。那么如果上述兩種情況發(fā)生在智能合約當中的話,惡意用戶通過下溢的操作,操縱自己的帳號向其他帳號發(fā)送超過自己余額數(shù)量的代幣,如果合約內(nèi)沒有對余額進行檢查,惡意用戶的余額就會下溢出變成一個超大的值,這個時候攻擊者如果大量拋售這些代幣,就能瞬間破壞整個代幣的價值系統(tǒng)。
慢霧安全團隊建議所有的智能合約開發(fā)者在智能合約中對數(shù)據(jù)進行操作的時候,要嚴格校驗數(shù)據(jù)邊界,防止整形溢出攻擊的發(fā)生。詳情可參考:BEC 智能合約無限轉(zhuǎn)幣漏洞分析及預警。
條件競爭攻擊 Race Condition條件競爭(Race CondiTIon)攻擊的方式很多樣,但是核心的本質(zhì)無非是對某個條件的狀態(tài)修改的競爭,如上期介紹的重入漏洞,也是條件競爭的一種,針對的是用戶余額這個條件進行競爭,只要用戶的余額沒有歸零,用戶就能一直提走智能合約的錢。這次介紹的條件競爭的例子是最近發(fā)生的著名的 Edgeware 鎖倉合約的拒絕服務漏洞,詳情可參考:關于 Edgeware 鎖倉合約的拒絕服務漏洞。這個漏洞問題的本質(zhì)在于對新建的鎖倉合約的余額的這個條件進行競爭。攻擊者可以監(jiān)控所有鏈上的鎖倉請求,提前計算出鎖倉合約的地址,然后向合約地址轉(zhuǎn)賬,造成鎖倉失敗。在官方?jīng)]有修復之前,要防止這種攻擊,只能使用比攻擊者更高的手續(xù)費讓自己的鎖倉交易先行打包,從而與攻擊者形成競爭避免攻擊。最后,官方修復方案為不對鎖倉合約的余額進行強制性的相等檢查,而是采用大于等于的形式,避免了攻擊的發(fā)生。
慢霧安全團隊建議智能合約的開發(fā)者在智能合約中對某些狀態(tài)進行修改的時候,要根據(jù)實際情況充分考慮條件競爭的風險,防止遭受條件競爭攻擊。