以太坊智能合约重放攻击细节剖析

来源:区块链社区HiBlock 作者:慢雾安全团队 08-31 12:00

iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

内容来源:慢雾科技iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

原文作者:慢雾安全团队iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

本文来自 360 独角兽安全团队(UnicornTeam)的 Zhenzuan Bai, Yuwei Zheng 等在Defcon 26 全球黑客大会分享的议题《Your May Have Paid More than You Imagine:Replay Attacks on Ethereum Smart Contracts》iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

1iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

攻击背景


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

在资产管理体系中,常有委托管理的情况,委托人将资产给受托人管理,委托人支付一定的费用给受托人。这个业务场景在智能合约中也比较普遍。iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

合约设计iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

function transferProxy(address _from, address _to, uint256 _value, uint256 _fee, uint8 _v, bytes32 _r, bytes32 _s)iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

transferProxy 方法涉及的角色:iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

  • 角色1: 需要转 Token,但自己钱包地址里没有 ETH 的人,即合约中的 _fromiPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

  • 角色2: 帮助角色1来转 Token,并支付 ETH 的 gas 费用,即合约中的 msg.sender,也是调用这个合约的人iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

  • 角色3: Token 接收方,即合约中的 _toiPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

transferProxy 方法的目的:iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

角色1想要转 Token 给角色3,但自己又没有 ETH 来支付手续费,于是角色1找到有 ETH 的角色2说:我给你一些 Token 当做手续费,你来通过调用 transferProxy 来把我的 Token 转给角色3,因为你有 ETH。iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

合约实现iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

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;
}iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

函数中关键的点是keccak256和ecrecover,即椭圆曲线加密数字签名(ECDSA)函数和验签函数,keccak256等同于sha3。iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

如下是签名、验签过程:iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

  1. 角色1(_from)先用sha3函数对 _from,_to,_value,_fee,nonce,address(token)进行处理得到msg值,然后使用web3.eth.sign(address, msg)得到签名signature;iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

  2. 将signature取前 0~66 个字节作为 r, 66~130 之间的字节作为 s,130~132 的字节作为 v,然后把 v 转为整型,角色1把这些信息告知角色2,角色2调用合约的transferProxy进行转账;iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

  3. 合约内ecrecover接收签名数据的哈希值以及 r/s/v 等参数作为输入,返回实施该签名的账户地址;iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

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)iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

备注iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

角色1、角色2需要事先沟通好nonce、_fee,其中nonce在合约中定义,从 0 开始自增,可调用合约的getNonce(address _addr)函数查询。iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

2iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

攻击过程


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

由于合约所有的调用数据(函数参数)都在链上公开可查,所以可从 Transaction 中提取所有签名信息。
iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

流程图iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

在智能合约重放攻击中,基于椭圆曲线加密数字签名(ECDSA)和验签的逻辑,可利用不同合约中相同的transferProxy实现,把 A 合约 Transaction 中的签名信息提取出来,在 B 合约中进行重放,由于涉及签名的所有参数都是一样的,所以可以直接调用 B 合约并广播到链上。iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

3iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

漏洞影响


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

根据议题《Your May Have Paid More than You Imagine:Replay Attacks on Ethereum Smart Contracts》中披露的数据,截止 4 月 27 日统计约有 52 个合约受到重放攻击的影响,其中 10 个高危、37 个中危、5 个低危。iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

从攻击目标角度分析,有 5 个合约因为没有 nonce 的设计,可在自身合约内进行重放攻击;另外 45 个合约可跨合约进行重放攻击。iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

4iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

预防建议


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

nonce 生成算法不采用从 0 开始自增的设计,避免和场景的做法相同;iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

去除 transferProxy 函数,改成其他方式实现代理的需求;iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

在keccak256函数中增加 address(this) 作为参数;iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

慢雾安全团队合约审计项已加入该类型问题的审计。iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

5iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

参考资料


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

演讲者 PDF:https://media.defcon.org/DEF CON 26/DEF CON 26 presentations/Bai Zheng and Chai Wang/DEFCON-26-Bai-Zheng-Chai-Wang-You-May-Have-Paid-more-than-You-Imagine.pdfiPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

演讲者开放文档:https://github.com/nkbai/defcon26/blob/master/docs/Replay Attacks on Ethereum Smart Contracts.mdiPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

演讲者开放工具:https://github.com/nkbai/defcon26/tree/master/erc20finderiPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

演讲者开放工具:https://github.com/nkbai/defcon26/tree/master/proxytokeniPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

Blockathon|48小时极客竞赛,区块链马拉松等你挑战(成都)iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

时间:2018年9月14-16日iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

地点:成都高新区天府五街200号菁蓉国际广场2号楼A座12楼中韩互联网+新技术孵化器iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

  • 招募50名开发者(识别下图二维码或点击“阅读原文”即可报名)iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

  • 报名费100元为参赛押金,参赛者个人原因不能到场参加活动概不退款;参赛者全程参与活动,待活动结束后现场退还。9月14日18:00开始第一次签到,9月15日和16日每天早上都要记得签到哦。iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

  • 主办方免费提供2天的食物、饮料,并为每一位参会者准备一件文化衫iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么


iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

iPiBCfans | 区块链爱好者_区块链技术_区块链开发_区块链是什么

最新技术进阶