0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

動(dòng)不動(dòng)就出事,智能合約攻擊該怎么辦

電子設(shè)計(jì) ? 來(lái)源:電子設(shè)計(jì) ? 作者:電子設(shè)計(jì) ? 2020-12-25 19:00 ? 次閱讀

如果你在數(shù)字貨幣世界待過(guò)足夠時(shí)間,也許你聽(tīng)說(shuō)過(guò)1或2個(gè)智能合約攻擊時(shí)間,這些攻擊導(dǎo)致了幾千萬(wàn)美元的盜竊損失。最著名的攻擊是DAO事件,這是數(shù)字貨幣世界最受期待的項(xiàng)目之一,同時(shí)也是智能合約的改革。雖然很多人聽(tīng)說(shuō)過(guò)這些攻擊,但是很少人知道到底發(fā)生了什么,是怎么發(fā)生的,以及如何避免這些錯(cuò)誤。

智能合約是動(dòng)態(tài)的,復(fù)雜的以及難以置信地強(qiáng)大。雖然他們的潛力是很難想象,但是也不可能一夜之間就成為了攻擊的對(duì)象。也就是說(shuō),對(duì)于往后的數(shù)字貨幣,我們可以從之前的錯(cuò)誤中學(xué)到經(jīng)驗(yàn),然后一起成長(zhǎng)。雖然DAO是已經(jīng)發(fā)生的事情,但是這對(duì)于開(kāi)發(fā)者,投資者,以及社區(qū)成員對(duì)于智能合約攻擊來(lái)說(shuō),都是一個(gè)很好的例子。

今天,我想和大家聊聊從DAO事件中,我們學(xué)到的3件事。

攻擊#1:重入攻擊

當(dāng)攻擊者通過(guò)對(duì)目標(biāo)調(diào)用提款操作的時(shí)候,重入攻擊就會(huì)發(fā)生,就好像DAO事件一樣。當(dāng)合約不能在發(fā)出資金之前更新?tīng)顟B(tài)(用戶余額),攻擊者就可以連續(xù)進(jìn)行提取函數(shù)調(diào)用,來(lái)獲得合約中的資金。任何時(shí)候攻擊者獲得以太幣,他的合約都會(huì)自動(dòng)地調(diào)用反饋函數(shù),function (),這就再次調(diào)用了提現(xiàn)合約。這時(shí)候,攻擊就會(huì)進(jìn)入遞歸回路,這時(shí)候這個(gè)合約中的資金就會(huì)轉(zhuǎn)入攻擊者。因?yàn)槟繕?biāo)合約都在不停地調(diào)用攻擊者的函數(shù),這個(gè)合約也不會(huì)更新攻擊者的余額。當(dāng)前的合約不會(huì)發(fā)現(xiàn)有任何問(wèn)題,更清楚地說(shuō),合約函數(shù)中包含反饋函數(shù),當(dāng)合約收到以太幣和零數(shù)據(jù)的時(shí)候,合約函數(shù)就會(huì)自動(dòng)執(zhí)行。

攻擊流程

1.攻擊者將以太幣存入目標(biāo)函數(shù)

2.目標(biāo)函數(shù)就會(huì)根據(jù)存入的以太幣而更新攻擊者的約

3.攻擊者請(qǐng)求拿回資金

4.資金就會(huì)退回

5.攻擊者的反饋函數(shù)生效,然后調(diào)用提現(xiàn)功能

6.智能合約的邏輯就會(huì)更新攻擊者的余額,因?yàn)樘岈F(xiàn)又被成功調(diào)用

7.資金發(fā)送到攻擊者

8.第5-7步重復(fù)使用

9.一旦攻擊結(jié)束,攻擊者就會(huì)把資金從他們自己的合約發(fā)送到個(gè)人地址

1*UeDgMZo2n0skHzgkl352zQ

重入攻擊的遞歸回路

很不幸地是,一旦這個(gè)攻擊開(kāi)始,無(wú)法停下。攻擊者的提現(xiàn)功能會(huì)被一次次地調(diào)用,直到合約中的燃料跑完,或者被害者的以太幣余額被消耗光。

代碼

下面就是DAO合約的簡(jiǎn)單版本,其中會(huì)包括一些介紹來(lái)為這些不熟悉代碼/ solidity語(yǔ)言更好地理解合約。

contract babyDAO {

/* assign key/value pair so we can look up

credit integers with an ETH address */

mapping (address => uint256) public credit;

/* a function for funds to be added to the contract,

sender will be credited amount sent */

function donate(address to) payable {

credit[msg.sender] += msg.value;

/*show ether credited to address*/

function assignedCredit(address) returns (uint) {

return credit[msg.sender];

/*withdrawal ether from contract*/

function withdraw(uint amount) {

if (credit[msg.sender] >= amount) {

msg.sender.call.value(amount)();

credit[msg.sender] -= amount;

如果我們看下函數(shù)withdraw(),我們可以看到DAO合約使用address.call.value()來(lái)發(fā)送資金到msg.sender。不僅如此,在資金發(fā)出后,合約會(huì)更新credit[msg.sender]的狀態(tài)。攻擊者在發(fā)現(xiàn)了合約代碼中的問(wèn)題,就能夠使用類似下面的ThisIsAHodlUp {}來(lái)將資金轉(zhuǎn)入contract babyDAO{}合約。

import ‘browser/babyDAO.sol’;

contract ThisIsAHodlUp {

/* assign babyDAO contract as "dao" */

babyDAO public dao = babyDAO(0x2ae...);

address owner;

/*assign contract creator as owner*/

constructor(ThisIsAHodlUp) public {

owner = msg.sender;

/*fallback function, withdraws funds from babyDAO*/

function() public {

dao.withdraw(dao.a(chǎn)ssignedCredit(this));

/*send drained funds to attacker’s address*/

function drainFunds() payable public{

owner.transfer(address(this).balance);

需要注意地是,這個(gè)后退函數(shù),function(),會(huì)調(diào)用DAO或者babyDAO{}的提現(xiàn)函數(shù),來(lái)從合約中盜取資金。從另個(gè)方面來(lái)說(shuō),當(dāng)攻擊者想要把所有偷竊來(lái)的資金賺到他們的地址,drainFunds()功能會(huì)被調(diào)用。

解決方案

現(xiàn)在,我們應(yīng)該清楚重放攻擊會(huì)利用兩個(gè)特別的智能合約漏洞。第一個(gè)是當(dāng)合約的狀態(tài)在資金發(fā)出之后,而不是之前進(jìn)行更新。由于在發(fā)出資金前無(wú)法更新合約狀態(tài),函數(shù)就會(huì)在中間計(jì)算的時(shí)候被打斷,合約也認(rèn)為資金其實(shí)還沒(méi)有發(fā)出。第二個(gè)漏洞就當(dāng)合約錯(cuò)誤地使用address.call.value()來(lái)發(fā)出資金,而不是address.transfer() 或者 address.send()。這兩個(gè)都受限于2300gas,只記錄一個(gè)事件而不是多個(gè)外部調(diào)用。

contract babyDAO{

....

function withdraw(uint amount) {

if (credit[msg.sender] >= amount) {

credit[msg.sender] -= amount; /* updates balance first */

msg.sender.send(amount)(); /* send funds properly */

攻擊2:下溢攻擊

雖然DAO合約不會(huì)讓受害者掉入下溢攻擊,我們能夠通過(guò)現(xiàn)有的babyDAO contract{}來(lái)更好地理解這些攻擊為什么會(huì)發(fā)生。

首先,我們需要理解什么是256單位制。一個(gè)256單位制是由256個(gè)字節(jié)組成。以太坊的虛擬機(jī)是使用256字節(jié)來(lái)完成的。因?yàn)橐蕴惶摂M機(jī)受限于256字節(jié)的大小,所以數(shù)字的范圍是0到4,294,967,295 (22??)。如果我們超過(guò)這個(gè)范圍,那么數(shù)字就會(huì)重置到范圍的最底部(22?? + 1 = 0)。如果我們低于這個(gè)范圍,這個(gè)數(shù)字就會(huì)重置到這個(gè)范圍的頂端(0–1= 22??)。

當(dāng)我們從零中減去大于零的數(shù),就會(huì)發(fā)生下溢攻擊,導(dǎo)致一個(gè)新的22??數(shù)集。現(xiàn)在,如果攻擊者的余額發(fā)生了下溢,那么這部分余額就會(huì)更新,從而導(dǎo)致整個(gè)資金被盜。

攻擊流程

攻擊者通過(guò)發(fā)出1Wei到目標(biāo)合約,來(lái)啟動(dòng)攻擊。

合約認(rèn)證發(fā)出資金的人

隨后調(diào)用1Wei的提現(xiàn)函數(shù)

合約會(huì)從發(fā)送者的賬戶扣除的1Wei,現(xiàn)在賬戶余額又是零

因?yàn)槟繕?biāo)合約將以太幣發(fā)給攻擊者,攻擊者的退回函數(shù)被處罰,所以提現(xiàn)函數(shù)又被調(diào)用。

提現(xiàn)1Wei的事件被記錄

攻擊者合約的余額就會(huì)更新兩次,第一次是到零,第二次是到-1。

攻擊者的余額回置到22??

攻擊者通過(guò)提現(xiàn)目標(biāo)合約的所有資金,從而完成整個(gè)攻擊

代碼

/*donate 1 wei, withdraw 1 wei*/

function attack() {

dao.donate.value(1)(this);

dao.withdraw(1);

/*fallback function, results in 0–1 = 2**256 */

function() {

if (performAttack) {

performAttack = false;

dao.withdraw(1);

/*extract balance from smart contract*/

function getJackpot() {

dao.withdraw(dao.balance);

owner.send(this.balance);

解決方案

為了防止受害人陷入下溢攻擊,最好的方法是看更新的狀態(tài)是否在字節(jié)范圍內(nèi)。我們可以添加參數(shù)來(lái)檢查我們的代碼,作為最后一層保護(hù)。函數(shù)withdraw()的首行代碼是為了檢查是否有足夠的資金,第二行是為了檢查超溢,第三個(gè)是檢查下溢。

contract babysDAO{

....

/*withdrawal ether from contract*/

function withdraw(uint amount) {

if (credit[msg.sender] >= amount

&& credit[msg.sender] + amount >= credit[msg.sender]

&& credit[msg.sender] - amount <= credit[msg.sender]) {

credit[msg.sender] -= amount;

msg.sender.send(amount)();

需要注意,就像我們之前討論,我們上面的代碼是在發(fā)出資金之前更新用戶的余額。

審核編輯:符乾江
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4816

    瀏覽量

    68863
  • 智能計(jì)算
    +關(guān)注

    關(guān)注

    0

    文章

    179

    瀏覽量

    16520
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    盛顯科技:拼接處理器串口不受控制,怎么辦?

    我們?cè)谑褂闷唇犹幚砥鞯倪^(guò)程中,因種種原因,有時(shí)候會(huì)出現(xiàn)串口不受控制的情況發(fā)生。當(dāng)出現(xiàn)這種情況時(shí),用戶將無(wú)法通過(guò)串口對(duì)拼接處理器進(jìn)行有效的控制或指令傳輸。那么您知道拼接處理器串口不受控制,怎么辦
    的頭像 發(fā)表于 11-15 11:56 ?211次閱讀
    盛顯科技:拼接處理器串口不受控制,<b class='flag-5'>該</b><b class='flag-5'>怎么辦</b>?

    盛顯科技:投影融合處理器連接出現(xiàn)超時(shí),怎么辦?

    了連接嘗試的失敗。這樣的情形無(wú)疑會(huì)給我們的使用帶來(lái)諸多不便與困擾。那么您知道投影融合處理器連接出現(xiàn)超時(shí),怎么辦嗎?下面盛顯科技小編為您介紹: 投影融合處理器連接出現(xiàn)超時(shí),可采取以下處理措施: 1、檢查網(wǎng)絡(luò)連接
    的頭像 發(fā)表于 11-06 10:58 ?208次閱讀
    盛顯科技:投影融合處理器連接出現(xiàn)超時(shí),<b class='flag-5'>該</b><b class='flag-5'>怎么辦</b>?

    盛顯科技:投影融合處理器兼容性出現(xiàn)問(wèn)題,怎么辦?

    ,解決這些兼容性問(wèn)題顯得尤為重要。那么您知道投影融合處理器兼容性出現(xiàn)問(wèn)題,怎么辦嗎?下面盛顯科技小編為您介紹: 當(dāng)投影融合處理器出現(xiàn)兼容性問(wèn)題時(shí),可以采取以下措施來(lái)解決: 一、檢查與確認(rèn) (1)確認(rèn)設(shè)備兼容性: 需要確
    的頭像 發(fā)表于 10-16 12:11 ?255次閱讀
    盛顯科技:投影融合處理器兼容性出現(xiàn)問(wèn)題,<b class='flag-5'>該</b><b class='flag-5'>怎么辦</b>?

    信號(hào)噪聲太大怎么辦

    我用一個(gè)TMR磁場(chǎng)傳感器,后面接一個(gè)儀表放大器,測(cè)出來(lái)的信號(hào)的噪聲特別大,如圖所示。這種情況怎么辦
    發(fā)表于 09-06 11:09

    ddos造成服務(wù)器癱瘓后怎么辦

    在服務(wù)器遭受DDoS攻擊后,應(yīng)立即采取相應(yīng)措施,包括加強(qiáng)服務(wù)器安全、使用CDN和DDoS防御服務(wù)來(lái)減輕攻擊的影響。rak小編為您整理發(fā)布ddos造成服務(wù)器癱瘓后怎么辦
    的頭像 發(fā)表于 08-15 10:08 ?322次閱讀

    盛顯科技:投影融合處理器畫(huà)面出現(xiàn)閃爍或抖動(dòng),怎么辦?

    采取一系列專業(yè)而周密的處理措施來(lái)解決問(wèn)題。那么您知道投影融合處理器畫(huà)面出現(xiàn)閃爍或抖動(dòng),怎么辦嗎?下面盛顯科技科技小編為您介紹: 投影融合處理器畫(huà)面出現(xiàn)閃爍或抖動(dòng),可采取以下措施進(jìn)行處理: 一、檢查電源與連接
    的頭像 發(fā)表于 08-14 17:00 ?425次閱讀
    盛顯科技:投影融合處理器畫(huà)面出現(xiàn)閃爍或抖動(dòng),<b class='flag-5'>該</b><b class='flag-5'>怎么辦</b>?

    盛顯科技:投影融合處理器出現(xiàn)顏色失真或偏色,怎么辦?

    我們?cè)谑褂猛队叭诤咸幚砥鞯倪^(guò)程中,因種種原因,有時(shí)候會(huì)遇到出現(xiàn)顏色失真或偏色的情況。此種情況的出現(xiàn),會(huì)對(duì)視覺(jué)效果、信息傳遞和設(shè)備性能產(chǎn)生負(fù)面影響。因此,需要我們及時(shí)采取措施解決問(wèn)題,以確保投影設(shè)備的正常運(yùn)行和良好的展示效果表現(xiàn)。那么您知道投影融合處理器出現(xiàn)顏色失真或偏色,怎么辦
    的頭像 發(fā)表于 07-31 17:09 ?310次閱讀
    盛顯科技:投影融合處理器出現(xiàn)顏色失真或偏色,<b class='flag-5'>該</b><b class='flag-5'>怎么辦</b>?

    大電流一體成型電感有噪音怎么辦

    電子發(fā)燒友網(wǎng)站提供《大電流一體成型電感有噪音怎么辦.docx》資料免費(fèi)下載
    發(fā)表于 07-30 12:30 ?0次下載

    KT142C-sop16語(yǔ)音芯片,插上usb,出不來(lái)虛擬U盤怎么辦

    KT142C-sop16語(yǔ)音芯片的芯片,我直接焊到我的板子上面,插上usb,但是出不來(lái)虛擬U盤怎么辦?
    的頭像 發(fā)表于 05-23 10:50 ?509次閱讀
    KT142C-sop16語(yǔ)音芯片,插上usb,出不來(lái)虛擬U盤<b class='flag-5'>怎么辦</b>

    LIN的UART接收沖突怎么辦?

    LIN的UART接收沖突怎么辦?貌似不加LIN的berak和分界符也能被從節(jié)點(diǎn)的UART收到
    發(fā)表于 05-09 08:12

    工控主板發(fā)生故障怎么辦

    工控主板發(fā)生故障怎么辦?前幾天有個(gè)客戶問(wèn)了我這個(gè)問(wèn)題,大部分情況下出現(xiàn)的故障并不可怕,主要是用戶粗心大意造成的。那今天小編就來(lái)講解一下工控主板一般會(huì)出現(xiàn)故障的主要原因及判斷方法:
    的頭像 發(fā)表于 04-11 18:19 ?915次閱讀

    電容負(fù)極熔斷怎么辦

    在現(xiàn)代科技發(fā)展的時(shí)代,電容器在各個(gè)領(lǐng)域都扮演著重要的角色。然而,由于各種原因,電容器的負(fù)極可能會(huì)發(fā)生熔斷的情況。那么,當(dāng)電容器的負(fù)極熔斷時(shí),我們應(yīng)該怎么辦呢?
    的頭像 發(fā)表于 04-10 14:15 ?562次閱讀
    電容負(fù)極熔斷<b class='flag-5'>怎么辦</b>

    UCB states切為CONFIRMATION狀態(tài)后,UCB區(qū)域就不能被擦寫了怎么辦

    芯片手冊(cè)中UCB states有四個(gè)狀態(tài)UNLOCKED, CONFIRMATION, ERASED, ERRORED。我發(fā)現(xiàn)切為CONFIRMATION狀態(tài)后,UCB區(qū)域就不能被擦寫了,這怎么辦?
    發(fā)表于 02-01 08:15

    晶振輸出頻率異常怎么辦?

    晶振輸出頻率異常怎么辦? 晶振輸出頻率異常是指晶振輸出信號(hào)的頻率與預(yù)期不符。晶振作為一種常見(jiàn)的時(shí)鐘源,廣泛應(yīng)用于各種電子設(shè)備中,包括計(jì)算機(jī)、手機(jī)、通信設(shè)備等。因此,當(dāng)晶振輸出頻率異常時(shí),會(huì)導(dǎo)致設(shè)備
    的頭像 發(fā)表于 01-24 16:11 ?975次閱讀

    修復(fù)輥壓機(jī)軸承位磨損怎么辦

    電子發(fā)燒友網(wǎng)站提供《修復(fù)輥壓機(jī)軸承位磨損怎么辦.docx》資料免費(fèi)下載
    發(fā)表于 01-23 09:52 ?0次下載