etherum智慧合約什麼時候變得不“智慧”
一、寫錯建構函式
函式預設屬性為public,變數預設屬性為internal
建構函式拼寫錯誤,導致合約易主,例如
合約ZiberCrowdsale,的建構函式Crowdsale(名稱不一樣)
合約完整code:https://etherscan.io/address/f0a924661b0263e5ce12756d07f45b8668c53380#code
二、fallback函式中易主
fallback函式(沒有函式名)為合約在出現錯誤的情況下預設會執行的函式,如圖
最簡單的fallback函式呼叫方式:(用metamask)直接像合約地址轉賬
以太坊中呼叫函式機制:根據函式ID查詢函式然後執行,若沒有找到,則執行fallback函式
函式ID是用計算函式簽名的keccak256值,取前4位元組。函式transfer(address,uint256)的ID是 0xa9059cbb.(線上計算工具:https://emn178.github.io/online-tools/keccak_256.html)
呼叫函式transfer(0x41414141, 0x42),資料如下(32位/位元組)
0xa9059cbb00000000000000000000000000000000000000000000000000000000414141410000000000000000000000000000000000000000000000000000000000000042
三、整數下溢,充值
無符號整數為“迴圈數”,最大值MAX+1=0,最小值為0,0-1=MAX,下面程式碼
balances[msg.sender] - _value >= 0恆成立,如果balances[msg.sender]=10,則呼叫contract.transfer(0x0, 11)之後,balances[msg.sender] -= _value;將balances[msg.sender]值變為2^256-1
整數上溢情況類似
四、代理呼叫Delegation
如圖,Delegation代理呼叫Delegate中的函式,msg.data傳入pwn()函式ID 0xdd365b8b即可使合約易主
代理呼叫功能強大但也危險,因為外部程式碼可以完全操作自身變數。較為著名的攻擊:The Parity Wallet Hack
參考:
https://ethernaut.zeppelin.solutions/
https://blog.trailofbits.com/2017/11/06/hands-on-the-ethernaut-ctf/
本文持續更新中