您的位置 首页 > 腾讯云社区

智能合约安全审计之路-拒绝服务漏洞---字节脉搏实验室

描述:拒绝服务漏洞(DOS)智能合约无法按照设定的方式被调用

核心问题:智能合约中的拒绝服务是一个致命的漏洞,因为漏洞导致的拒绝服务一般为永久性的,无法恢复

拒绝服务的原因意外执行了SELFDESTRUCT指令访问控制策略出错Gas达到区块上限非预期的异常抛出漏洞分析selfdestruct()合约自毁函数指令执行后,合约将拒绝服务,地址对应的字节码将被标注为删除合约地址中所有的ETH将被发送到指定的新地址进行ETH转移时,即使目标地址为一个合约地址,也不会触发该地址的fallback函数,因此不需要该合约有任何的payable函数如果selfdestruct函数被非预期的执行,则整个合约会拒绝服务selfdestructGame合约分析pragma solidity ^0.4.24; contract selfdestructGame{ address owner; constructor() payable { owner = msg.sender; } function ownedEth() public constant returns(uint256){ return this.balance; } function destruct(address _who) public { selfdestruct(_who); } }

漏洞点:在address owner处发送地址到_who处,由于调用了selfdestruct()函数对selfdestructGame合约进行自毁,将selfdestructGame合约balance发送到攻击者地址处。

访问控制策略错误

onwer权限变更不需要确认,因此若owner被设置为一个错误地址,合约将彻底失去管理员权限

onwerGame合约分析pragma solidity ^0.4.24; contract ownerGame{ address owner; constructor() { owner = msg.sender; } function changeOwner(address _new) public { owner = _new; } }

漏洞点:由于owner没有权限控制,导致可以任意调用成为管理员,如果owner地址为无效地址,就会导致合约作废

Gas达到区块上限

对于每一个区块来说,有一个区块的GasLimit,任何交易的gas花费都不超过这个上限,否则无法被打包

GaslimitGame合约分析pragma solidity ^0.4.24; contract gaslimitGame{ mapping (uint => uint) count; event GasLog(uint gas); function gasUse(uint n) public { uint gastmp = gasleft(); for(uint i=0;i<n;i++) { count[i]=i; emit GasLog(gastmp-gasleft()); gastmp = gasleft(); } } }非预期的异常导致拒绝服务

在竞拍合约中,竞拍进行时,每个人向合约发送自己的竞拍出价对应ETH

如果有人出价高于当前最高出价者,则合约退还当前最高出价者的出价,并且此人成为新的最高出价者

攻击者构造一个fallback函数一定会抛出异常的合约,并将合约地址成为最高出价者,则其他人将永远不能成为新的最高出价者

Auction合约分析pragma solidity ^0.4.24; contract Auction { address public topBidder; uint256 public topBid; constructor() public payable { require(msg.value > 0); topBid = msg.value; topBidder = msg.sender; } function bid() payable { require(msg.value > topBid); topBidder.transfer(topBid); topBidder = msg.sender; topBid = msg.value; } // finish the auction function auction_end() { // ... } } contract revertContract{ function testBid(address _addr) public payable{ bytes4 methodHash = bytes4(keccak256("bid()")); _addr.call.value(msg.value)(methodHash); } function ownedEth() public constant returns(uint256){ return this.balance; } function() public payable{ revert(); } }

漏洞点:topBidder的攻击者合约在竞拍成功后的上一个最高价格时候,当后面的竞拍者出更高价格的时候,会触发topBidder.transfer(topBid),然而攻击者合约内使用了fallback函数,在经过transfer函数的时候会发生异常,导致交易回滚,从而使bid()函数拒绝服务。使整个合约没办法正常进行。

漏洞预防严格限制selfdestruct指令的权限限制设置完善合理的访问控制策略如果目标地址可以是一个合约,需要考虑合约的特性 ---来自腾讯云社区的---字节脉搏实验室

关于作者: 瞎采新闻

这里可以显示个人介绍!这里可以显示个人介绍!

热门文章

留言与评论(共有 0 条评论)
   
验证码: