在資產管理體系中,常有委託管理的狀況,委託人將資產給受託人管理,委託人支付必定的費用給受託人。這個業務場景在智能合約中也比較廣泛。git
合約設計github
function transferProxy(address _from, address _to, uint256 _value, uint256 _fee, uint8 _v, bytes32 _r, bytes32 _s)web
transferProxy 方法涉及的角色:算法
角色1: 須要轉 Token,但本身錢包地址裏沒有 ETH 的人,即合約中的 _from安全
角色2: 幫助角色1來轉 Token,並支付 ETH 的 gas 費用,即合約中的 msg.sender,也是調用這個合約的人函數
角色3: Token 接收方,即合約中的 _to工具
transferProxy 方法的目的:區塊鏈
角色1想要轉 Token 給角色3,但本身又沒有 ETH 來支付手續費,因而角色1找到有 ETH 的角色2說:我給你一些 Token 當作手續費,你來經過調用 transferProxy 來把個人 Token 轉給角色3,由於你有 ETH。ui
合約實現this
function transferProxy(address _from, address _to, uint256 _value, uint256 _fee, uint8 _v, bytes32 _r, bytes32 _s) public returns (bool){ if(balances[_from] < _fee + _value || _fee > _fee + _value) revert(); uint256 nonce = nonces[_from]; bytes32 h = keccak256(_from,_to,_value,_fee,nonce,address(this)); if(_from != ecrecover(h,_v,_r,_s)) revert(); if(balances[_to] + _value < balances[_to] || balances[msg.sender] + _fee < balances[msg.sender]) revert(); balances[_to] += _value; emit Transfer(_from, _to, _value); balances[msg.sender] += _fee; emit Transfer(_from, msg.sender, _fee); balances[_from] -= _value + _fee; nonces[_from] = nonce + 1; return true; }
函數中關鍵的點是keccak256和ecrecover,即橢圓曲線加密數字簽名(ECDSA)函數和驗籤函數,keccak256等同於sha3。
以下是簽名、驗簽過程:
角色1(_from)先用sha3函數對 _from,_to,_value,_fee,nonce,address(token)進行處理獲得msg值,而後使用web3.eth.sign(address, msg)獲得簽名signature;
將signature取前 0~66 個字節做爲 r, 66~130 之間的字節做爲 s,130~132 的字節做爲 v,而後把 v 轉爲整型,角色1把這些信息告知角色2,角色2調用合約的transferProxy進行轉帳;
合約內ecrecover接收簽名數據的哈希值以及 r/s/v 等參數做爲輸入,返回實施該簽名的帳戶地址;
let msg = web3.sha3(_from,_to,_value,_fee,nonce,address(token)) let signature = web3.eth.sign(_from, msg) let r = signature.slice(0, 66) let s = '0x' + signature.slice(66, 130) let v = '0x' + signature.slice(130, 132) v = web3.toDecimal(v) console.log('r', r) console.log('s', s) console.log('v', v) console.log(msg)
備註
角色一、角色2須要事先溝通好nonce、_fee,其中nonce在合約中定義,從 0 開始自增,可調用合約的getNonce(address _addr)函數查詢。
因爲合約全部的調用數據(函數參數)都在鏈上公開可查,因此可從 Transaction 中提取全部簽名信息。
流程圖
在智能合約重放攻擊中,基於橢圓曲線加密數字簽名(ECDSA)和驗籤的邏輯,可利用不一樣合約中相同的transferProxy實現,把 A 合約 Transaction 中的簽名信息提取出來,在 B 合約中進行重放,因爲涉及簽名的全部參數都是同樣的,因此能夠直接調用 B 合約並廣播到鏈上。
根據議題《Your May Have Paid More than You Imagine:Replay Attacks on Ethereum Smart Contracts》中披露的數據,截止 4 月 27 日統計約有 52 個合約受到重放攻擊的影響,其中 10 個高危、37 箇中危、5 個低危。
從攻擊目標角度分析,有 5 個合約由於沒有 nonce 的設計,可在自身合約內進行重放攻擊;另外 45 個合約可跨合約進行重放攻擊。
nonce 生成算法不採用從 0 開始自增的設計,避免和場景的作法相同;
去除 transferProxy 函數,改爲其餘方式實現代理的需求;
在keccak256函數中增長 address(this) 做爲參數;
慢霧安全團隊合約審計項已加入該類型問題的審計。
演講者開放工具:https://github.com/nkbai/defcon26/tree/master/erc20finder
演講者開放工具:https://github.com/nkbai/defcon26/tree/master/proxytoken
內容來源:慢霧科技
原文做者:慢霧安全團隊
本文來自 360 獨角獸安全團隊(UnicornTeam)的 Zhenzuan Bai, Yuwei Zheng 等在Defcon 26 全球黑客大會分享的議題《Your May Have Paid More than You Imagine:Replay Attacks on Ethereum Smart Contracts》
Blockathon|48小時極客競賽,區塊鏈馬拉松等你挑戰(成都)
時間:2018年9月14-16日
地點:成都高新區天府五街200號菁蓉國際廣場2號樓A座12樓中韓互聯網+新技術孵化器
招募50名開發者(識別下圖二維碼或點擊「閱讀原文」便可報名)
報名費100元爲參賽押金,參賽者我的緣由不能到場參加活動概不退款;參賽者全程參與活動,待活動結束後現場退還。9月14日18:00開始第一次簽到,9月15日和16日天天早上都要記得簽到哦。
主辦方免費提供2天的食物、飲料,併爲每一位參會者準備一件文化衫