老牌C网交易所遭到黑客恶意攻击且获利

原创
2294 天前
14641

事件

降维安全实验室(johnwick.io)在以太坊智能合约监控系统监控到多笔"短地址"攻击交易(https://etherscan.io/tx/0x08401b6ccc5ca4762d82fb5875b66d70c3fc82e55d4e21d66482474a05aadef1).

  • 被攻击地址 0x304cc179719bc5b05418d6f7f6783abe45d83090
  • 被攻击数字货币 Veros
  • 攻击者收币地址 0x01d497724945b54ba85b9c16319b90dd47b95d00 通过分析发现,被攻击者地址属于C-CEX(c-cex.com),俗称C网,是美国老牌数字代币交易平台. 攻击者已经成功实施多笔针对此交易所不同种类数字货币的此类攻击,截至发稿前为止,攻击者账户仍有现值约5万美金的窃取数字货币尚未洗走.

意识到事态严重程度,降维安全(johnwick.io)第一时间通过twitter和email等渠道对C-CEX发送了威胁预警通知,但截至本文发稿前,未收到官方的明确回复.

##分析

"短地址"攻击是以太坊智能合约中的经典攻击方式之一,我们知道在合约方法调用中,以太坊虚拟机EVM是通过解析收到的msg.data数据来获取调用函数和与之对应的参数数值. 具体到此次交易,

  {
   "action": {
     "callType": "call",
     "from": "0x304cc179719bc5b05418d6f7f6783abe45d83090",
     "gas": "0x4fd5c",
     "input": "0xa9059cbb00000000000000000000000001d497724945b54ba85b9c16319b90dd47b95d0000000000000000000000000000000000000000000000000000000009e4f580",
     "to": "0xedbaf3c5100302dcdda53269322f3730b1f0416d",
     "value": "0x0"
  },
   "blockHash": "0xbb4f2b9a4e74b026608077d6880c5695253b87aeb45ac8e76a58c911f2a3717e",
   "blockNumber": 6273007,
   "result": {
     "gasUsed": "0x4d80",
     "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
  },
   "subtraces": 0,
   "traceAddress": [],
   "transactionHash": "0x08401b6ccc5ca4762d82fb5875b66d70c3fc82e55d4e21d66482474a05aadef1",
   "transactionPosition": 11,
   "type": "call"
}

其中input解析为

a9059cbb 00000000000000000000000001d497724945b54ba85b9c16319b90dd47b95d00 00000000000000000000000000000000000000000000000000000009e4f580 开头为方法选择器(method selector), 即通过keccak256("transfer(address,uint256)")计算得到的哈希 a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b前4字节a9059cbb. 根据ABI编码规则可知,后续32字节为转账地址address _to, 之后32字节为转账数目uint256 _value. 但是我们发现最后的uint256 _value只有31字节,不到规定的32字节,以太坊虚拟机EVM遇到此类长度不足数据的处理机制是在短数据后面直接补0,这样就导致了把攻击者提供的0x9e4f580(10进制数: 166000000)放大256倍,成为0x9e4f58000(10进制数: 42496000000),转出了远远超过攻击者拥有数量的数字货币.

那么攻击者是如何实现此类攻击的呢? 原来攻击者精心选择了一个"靓号",结尾为00的以太坊地址`1d497724945b54ba85b9c16319b90dd47b95d00`,但是只将其前19字节提供给交易所,**交易所未对用户输入的提现地址做有效的长度验证**,直接使用此**短地址**参与拼接交易数据,在交易数据里后续的00从而导致了"短地址"攻击的发生.

总结

为了避免此类事件再次发生,我们建议在以下几个层面做好安全防御建设:

  • 数字货币交易平台: 在生成交易数据前,交易所应在后端对用户提供的以太坊地址进行检查,确保其长度为20字节.
  • 智能合约: 在部署上链前,应对此类攻击做出防御检测. 实例代码:
      function transfer(address _to, uint _value) public returns (bool) {
        require(msg.data.length >= 4 + 32*2); // 检测input参数长度是否合法
        // 可写成个function modifier
        // ...
    }

  • 实时监控: 如果存在问题的合约已经部署并且已投入应用,那么就需要通过建立实时交易监控系统,对各类恶意交易进行及时发现,及时预警,将安全威胁造成的损害控制在最小范围.