以太坊蜜罐智能合約之神奇的邏輯漏洞區(qū)塊鏈
細(xì)數(shù)在以太合約里的神奇邏輯漏洞
神奇的邏輯漏洞
該類蜜罐合約用2012年春晚小品《天網(wǎng)恢恢》中這么一段表現(xiàn)是及其合適的:
送餐員: 外賣一共 30 元
騙子 B: 沒(méi)零的,100!
送餐員: 行,我找你 ......70!(送餐員掏出 70 給騙子 B)
騙子 A: 哎,等會(huì)兒等會(huì)兒,我這有零的,30 是吧,把那 100 給我吧!給,30!(騙子 A 拿走了 B 給送餐員的 100 元,又給了送餐員 30 元)
送餐員: 30 元正好,再見(jiàn) !該類漏洞也是如此,在看起來(lái)正常的邏輯下,總藏著這樣那樣的陷阱。
1.天上掉下的餡餅:Gift_1_ETH
合約關(guān)鍵代碼如下:
三個(gè)關(guān)鍵函數(shù)功能如下:
SetPass(): 在轉(zhuǎn)賬大于 1ether 并且 passHasBeenSet 為 false (默認(rèn)值就是 false), 就可以設(shè)置密碼 hashPass。
GetGift(): 在輸入的密碼加密后與 hashPass 相等的情況下,就可以取走合約里所有的以太幣。
PassHasBeenSet():如果輸入的 hash 與 hashPass 相等,則 passHasBeenSet 將會(huì)被設(shè)置成 true
如果我們想取走合約里所有的以太幣,只需要按照如下流程進(jìn)行操作:
推特用戶 Alexey Pertsev 還為此寫(xiě)了一個(gè)獲取禮物的 EXP。
但實(shí)際場(chǎng)景中,受害者轉(zhuǎn)入一個(gè)以太幣后并沒(méi)有獲取到整個(gè)智能合約的余額,這是為什么呢?
這是因?yàn)樵诤霞s創(chuàng)立之后,任何人都可以對(duì)合約進(jìn)行操作,包括合約的創(chuàng)建者:
合約創(chuàng)建者在合約 被攻擊 前,設(shè)置一個(gè)只有創(chuàng)建者知道的密碼并將 passHasBeenSet 置為 True,將只有合約創(chuàng)建者可以取出智能合約中的以太幣。與之類似的智能合約還有 NEW_YEARS_GIFT:
2.合約永遠(yuǎn)比你有錢(qián)
合約關(guān)鍵代碼如下:
對(duì)于 multiplicate() 而言,只要你轉(zhuǎn)賬的金額大于賬戶余額,就可以把 賬戶余額 和 你本次轉(zhuǎn)賬的金額 都轉(zhuǎn)給一個(gè)可控的地址。在這里我們需要知道:在調(diào)用 multiplicate() 時(shí),賬戶余額 = 之前的賬戶余額 本次轉(zhuǎn)賬的金額。所以 msg.value >= this.balance 只有在原余額為 0,轉(zhuǎn)賬數(shù)量為 0 的時(shí)候才會(huì)成立。也就意味著,賬戶余額永遠(yuǎn)不會(huì)比轉(zhuǎn)賬金額小。
3.誰(shuí)是合約主人:TestBank
關(guān)鍵代碼如下:
根據(jù)關(guān)鍵代碼的內(nèi)容,如果我們可以通過(guò) useEmergencyCode() 中的判斷,那就可以將 owner 設(shè)置為我們的地址,然后通過(guò) withdraw() 函數(shù)就可以取出合約中的以太幣。
如果你也有了上述的分析,那么就需要學(xué)習(xí)一下 Solidity 中繼承的相關(guān)知識(shí):Solidity 的繼承原理是代碼拷貝,因此換句話說(shuō),繼承的寫(xiě)法總是能夠?qū)懗梢粋€(gè)單獨(dú)的合約。
情況五:子類父類有相同名字的變量。 父類 A 的 test1 操縱父類中的 variable,子類 B 中的 test2 操縱子類中的 variable,父類中的 test2 因?yàn)闆](méi)被調(diào)用所以不存在。 解釋:對(duì) EVM 來(lái)說(shuō),每個(gè) storage variable 都會(huì)有一個(gè)唯一標(biāo)識(shí)的 slot id。在下面的例子說(shuō),雖然都叫做 variable,但是從 bytecode 角度來(lái)看,他們是由不同的 slot id 來(lái)確定的,因此也和變量叫什么沒(méi)有關(guān)系。
根據(jù)樣例中的代碼,我們將合約的核心代碼修改如下:
變量 owner1 是父類 Owner 中的 owner 變量,而 owner2 是子類 TestBank 中的變量。useEmergencyCode() 函數(shù)只會(huì)修改 owner2,而非 owner1,自然無(wú)法調(diào)用 withdraw()。 由于調(diào)用 useEmergencyCode() 時(shí)需要轉(zhuǎn)作者設(shè)置的 evalue wei 的以太幣,所以只會(huì)造成以太幣白白丟失。
1.TMT觀察網(wǎng)遵循行業(yè)規(guī)范,任何轉(zhuǎn)載的稿件都會(huì)明確標(biāo)注作者和來(lái)源;
2.TMT觀察網(wǎng)的原創(chuàng)文章,請(qǐng)轉(zhuǎn)載時(shí)務(wù)必注明文章作者和"來(lái)源:TMT觀察網(wǎng)",不尊重原創(chuàng)的行為T(mén)MT觀察網(wǎng)或?qū)⒆肪控?zé)任;
3.作者投稿可能會(huì)經(jīng)TMT觀察網(wǎng)編輯修改或補(bǔ)充。