ZeroNights 2018的EOS区块链漏洞

图片

本文将研究EOS区块链(以太坊的竞争对手之一)中的几个实际漏洞,以及它们如何嵌入在ZeroNights 2018 的新一代安全老虎机竞赛中。如果您有兴趣了解安全状况如何这个区块链网络,然后在猫的欢迎下。

参赛作品


一切始于一个事实,最近,在对Etherium智能合约进行安全性审核期间,我们的一位朋友向我们抛出了一篇有关EOS网络上智能合约漏洞的文章 。 这使我们非常感兴趣,因此我们决定更详细地研究漏洞。

所有这些最终导致了在ZeroNights 2018竞赛中被称为“单臂匪徒”的竞赛,该竞赛存在智能合约中的漏洞。

让我们直接看一下EOS区块链网络,如何使用它以及内部如何安排一切。 互联网上有很多描述该技术的文章,因此很可能没有技术细节,但是我们将尝试传达一般含义,以便普通用户可以初步了解EOS区块链工作机制。

EOS技术说明


EOS.io是Block.one的新一代区块链,基于PoS( 权益证明 )的概念。

从网络创建者自身的描述来看:“ EOS是一个免费的开源区块链网络软件,为开发人员和企业家提供了一个用于创建,部署和运行高性能分散式应用程序(DAPP)的平台。”

简而言之,如果要解释这个概念,那么可以很好地反映出Wikipedia文章的摘录:
权益证明(PoS)的思想是解决与高能耗相关的工作量证明(PoW)的问题。 他们在其帐户中拥有的加密货币数量至关重要,而不是参与者的计算能力。 因此,代替使用大量电力来解决PoW问题,PoS参与者具有有限百分比的可能的交易检查。 该限制对应于参与者账户中的加密货币数量
该网络是全新的,主网络(mainnet)的首次启动于2018年6月10日进行。 主要的加密货币是EOS,开发人员的主要门户网站是developers.eos.io

EOS.io区块链支持用户使用WebAssembly代码(WASM)创建的应用程序,WebAssembly代码是一种新的Web标准,广泛支持Google,Microsoft,Apple等大公司。

目前,用于创建在WASM中编译代码的应用程序的最新工具包是带有C / C ++编译器的clang / llvm。

为了获得更好的兼容性,开发人员建议使用EOSIO CDT(合同开发工具包),这是开发人员自己提供的一组实用程序,用于在创建智能合同时进行方便且正确的工作。

先前的eosiocpp编译器已被弃用且不受支持,因此建议每个人(在撰写本文时)升级到新的EOSIO CDT 1.5。

不像以太


以太在其概念上使用的是PoW(工作量证明),这需要昂贵的计算,并且奖励第一人以解决数学问题。 也就是说,那些并行决定但又没有时间决定的人浪费了精力。 在这种情况下,矿工们之间在争夺更先进的技术和设备。 更快地生成块,从而赚钱。

与以太不同,在EOS网络中,系统将根据PoS概念选择新区块的创建者,这取决于个人身份的数量-占加密货币总数的一小部分。 因此,拥有更多财富的人更有可能被系统选中。 但是与PoW(以太坊)不同,原则上生成新区块没有任何奖励,而矿工的收入仅来自交易的佣金。

结论-基于PoW的加密货币能效高1000倍。

我们开发环境


因此,似乎我们已经完成了理论,然后转向实践。 但是实际上,一切看起来都更加有趣。 当他们试图在夏天弄清楚并开始为ZeroNights 2018做某事时的文档时,一切都非常糟糕,主要的开发门户有很多漏洞,一半都空了,有时甚至无法正常工作。

测试网络尚未真正启动,因此我必须部署节点。 顺便说一下,与Internet上的意见不同,事实证明并不是那么困难。 使用官方文档,我们从docker developers.eos.io/eosio-nodeos/docs/docker-quickstart启动了它

让我们谈谈与EOS区块链一起使用的主要实用程序和程序,我在参加比赛时必须处理这些问题:

  • Nodeos-实际上是EOSIO节点本身的服务; 您可以配置和配置各种插件,例如CORS,历史记录和其他。
  • Cleos是一个控制台实用程序,用于处理节点,调用合同方法以及与电子钱包,密钥和访问进行交互。 使用EOS时最常用的工具。
  • Keosd是一个控制台钱包,或更确切地说,是一个钱包服务,一个私钥存储。
  • Eosio.cdt-合同开发工具包,所谓的开发人员工具集,用于调试和编译合同,生成ABI文件等。
  • Eos.js -Javascript API库,用于通过Web方便地与节点和合同协作 ,并嵌入在站点中。
  • Scatter是用于安全存储帐户密钥的桌面钱包。 有一个Web库scatter.js,可与Web套接字上的Scatter桌面钱包进行交互,从而有助于在浏览器中使用DAPP应用程序。

Uff!..是的,有很多程序,理解它们也不是一件容易的事。 所有这些的描述都应该单独发布,这不在本文的讨论范围之内。 但是,让我们想象一下,我们在服务器上安装了一个节点,甚至学会了如何使用合约方法调用合约方法(如果有的话)。

是的,最重要的是。 我们需要草绘智能合约本身。 我们将用C ++编写它,并且为了至少做一些明智的事情,我不得不阅读很多文档。

要了解各地的合同,请举一个Hello合同的例子。 主文件是hello.cpp,其中描述了整个合同。

#include <eosiolib/eosio.hpp> using namespace eosio; class hello : public eosio::contract { public: using contract::contract; /// @abi action void hi( account_name user ) { print( "Hello, ", name{user} ); } }; EOSIO_ABI( hello, (hi) ) 

如果简而言之尝试解释,那么这里- 一切都很简单 。 我们加载eosio.hpp库,然后创建hello类(也称为合同)并继承该类合同。 我们创建void hi方法,并在参数中输入account_name类型的用户变量,它也是uint64_t。 在方法中,打印“ Hello”,以及我们在调用该方法时指定的名称。 EOSIO_ABI所在的最后一行是一个辅助宏,该宏接受该类和该类中的公共方法,并且还参与.abi文件的形成,其中指示了合同的所有公共方法。

探索漏洞


因此,在该文章的框架中,描述了几个漏洞-现在让我们更详细地考虑它们。

数值溢出-数值溢出


调用合同时,节点将检查参数的类型,如果我们尝试提供的数据不适合,则该节点将开始宣誓并不会错过这种暴行。 但是! 如果合同内有某种算法可以改变数字,数字的总和或乘,那么数字可以在合同内已经改变。 这意味着您可以指定一个节点将跳过的数字,但是要乘以合同,该数字将超出有效的数据类型,这将导致溢出。

它能给什么? 例如,检查某种数字参数,例如int Number <0,并且已知int y是一个有符号的数字,如果数字溢出,则大数值的数字符号将变为负数。 因此,检查将被溢出。 当然,在这里,这完全取决于此检查的重要性。

例如,在同一篇有关漏洞的文章中,确实存在攻击者能够影响balance参数,从而欺骗系统的真实情况 。 代码注释更详细地描述了与合同交互的机制:

 //      typedef struct acnts { account_name name0; account_name name1; account_name name2; account_name name3; } account_names; //     (   1 EOS) //  ,     , //      «» void batchtransfer( symbol_name symbol, account_name from, account_names to, uint64_t balance ){ //    require_auth(from); //    account fromaccount; //      require_recipient(from); require_recipient(to.name0); require_recipient(to.name1); require_recipient(to.name2); require_recipient(to.name3); // ,       . //   is_balance_within_range   ( eosio_assert(is_balance_within_range(balance), "invalid balance"); // ,      «» //  , «» 1111111111111111  0,     eosio_assert(balance > 0, "must transfer positive balance"); //   amount    4 //     ,  amount   int64_t amount = balance * 4; //     from,    int itr = db_find_i64(_self, symbol, N(table), from); // ,    eosio_assert(itr >= 0, "wrong name"); //    fromaccount   db_get_i64(itr, &fromaccount, (account)); // ,       // ,    0.1 EOS //    ,    amount eosio_assert(fromaccount.balance >= amount, "overdrawn balance"); //   sub_balance(symbol, from, amount); //    4  add_balance(symbol, to.name0, balance); add_balance(symbol, to.name1, balance); add_balance(symbol, to.name2, balance); add_balance(symbol, to.name3, balance); } 

黑客攻击最有可能如下进行。 攻击者预先创建了4个帐户,然后直接调用batchtransfer方法,如下所示:

 cleos push action contractname batchtransfer \'{"symbol ":"EOS", "from":”attacker”, "to":{ “name0”:”acc0”, “name1”:”acc1”, “name2”:”acc2”, “name3”:”acc3”}, "balance":"111111111111111111 EOS"}' -p attacker@active 


图片

我将立即进行保留,这只是一个假设; 他们是如何进行骇客入侵的-我们不知道,如果对这个或更准确的信息还有其他想法,请在评论中写下。

渗碳检查


缺少对用于用户授权的合同方法require_auth()的验证将导致以下事实:没有必要权限的任何人都可以使用合同的特权方法,例如,从合同中提取资金。

缺乏方法调用验证


当向合同(EOS)汇款时,您可以在特殊的宏中指示下一步将发生什么以及该怎么办。 假设您收到付款后,就会调用某种算法,例如,开始轮盘赌或其他事情,以及支票:

 if( code == self || code == N(eosio.token) || action == N(onerror) ) { \ TYPE thiscontract( self ); \ switch( action ) { \ EOSIO_API( TYPE, MEMBERS ) \ } } //    action == N(transfer) 

在此检查中,对调用转移方法没有任何限制,因此您可以直接调用转移方法,而无需向合同中汇款。 这意味着无需花一角钱就可以进一步获得收益。

ZeroNights 2018竞赛


竞赛的想法是独立产生的:由于一切都与游戏和三个漏洞有关,因此,我们将在EOS.io区块链的智能合约机制上进行游戏。 游戏应该尽可能简单,但有趣。

老虎机“单臂匪”! 渴望轻松​​赚钱的人总是让我感到惊讶-请记住,世界上没有免费赠品,或者几乎没有。 顺便说一句,它就在那儿,或者说,当使用漏洞时,它就会出现。

前端


他们决定使前端游戏变得时尚,美观和三维。 谢谢vtornik23没有拒绝参加,并帮助我们充分利用了Unity3d引擎。

图片

三维游戏机“单臂匪”; 发送1个EOS并拉动智能杠杆,玩家就有机会启动命运之轮并赢得大奖!

合同漏洞


根据游戏的想法,获胜被认为是损失了三个ZeroNights玩偶,其数字系数为777或0。获胜的机会等于0.02%,并且一些不专心的程序员尝试通过向其添加仅乘法溢出来使随机算法复杂化发送的金额,并且懒得更详细地考虑条件,因此我只写了if(结果== 777 ||结果<1),这使得可以将其变为负值。

  int rnd = random(999); int result = rnd * price.amount; uint64_t prize = 0; print("Result:", result); // BINGO 777 or 000 !!! ~ 0.02% if(result == 777 || result < 1 ) { prize = 100; sendtokens(from); } 

智能合约本身放置在github上 ,因此每个人都可以从各个角度仔细查看它并确定其他漏洞。 关于它们的内容已经有较高的记载,因此找到它们应该没有任何困难。

参加规则


参与规则非常简单:有必要尝试赢得或破解系统的机制。 当3个matryoshkas掉下来时-大奖!!! 系统收取100个单位的加密货币。 如果参与者连续3次获得大奖,他将成为赢家并从组织者那里获得奖品-品牌帽衫,徽章,各种商品。

当然,您可以通过长时间拉杆并希望运气来赢得胜利,但是运气是不可预测的,获胜的百分比很小,因此更容易破解。

比赛结果


因此,我们认为竞争是完美的。 计划为3个人提供奖励,只有3个人在预定的结束日期之前成功应对了比赛。 比赛进行了2天,在此期间,参赛者必须解决任务。 在2018年ZeroNights的主要阶段会议的闭幕式上,正式颁发了礼物并赠送了礼物。

主要重点放在了EOS区块链技术的知识上,我们留下了一些技巧,其中一个没人能找到。 我们将把这个谜语留待以后...

参加者评论


阿列克谢 (1个地方)
ZeroNights是我最喜欢的会议之一,从第一次会议开始,在圣彼得堡我从未错过任何一个会议。 肯定会给人六个月的热情,在春季PHDays :)。 最近三年我一直在进行区块链开发。 今年,区块链进入了ZeroNights(在过去,事实似乎是一样的,它在被黑客入侵,但我错过了)。 首先,在注册会议后,我去看看区块链的内容和方式。 我以为会是PHDays,某种曲线随机性或空中竞速条件。 但是这里是EOS,在第一次EOS hackathon上我和他有一些熟识,但是时间不长,而且所有开发环境都丢失了。 战斗精神下降了,我去等待会议开始。 但是,好奇心变得更好了,毕竟,EOS出了什么问题!

斯坦尼斯拉夫·波沃洛茨基 (2名)
对我来说,这是一场漫长而有趣的比赛。 这是认识EOS区块链架构的绝佳机会。 比赛始于您仅凭$$就不会进入EOS网络(主网)的惊喜。 在提示将合同部署到测试网络,在该网络上注册,设置分散性并查看游戏合同的交易历史之后,立即清楚了如何欺骗老虎机(合同的作者在测试期间做了几次)。 但是,只要广告网络未批准我的所有交易的参数都与获胜的交易相同,就可以轻松快速地管理比赛,这种信心很快就消失了。

伊琳娜 (第三名)
在参加比赛之前,她仅在理论上介绍了智能合约的工作,因此“现场交流”,查看源代码,试用工具(并再次确保python是最好的)非常有趣。 事实证明,这项任务非常激动人心。 谢谢你

最后


并不是说每个人都轻松应对。 对于某人来说,这是一个艰难的2天,只有到最后,幸运的人才能利用任何区块链的缺点来取胜-如果信息进入了区块链,那么所有人都可以访问,如果有人已经入侵了某个东西,那么其他人就可以观看它的方式。

我们感谢所有参与者以及协助组织竞赛的人们。
在ZeroNights 2019见,新的冒险等待着您!

Source: https://habr.com/ru/post/zh-CN433552/


All Articles