来源 | Hackernoon
编译 | Guoxi
责编 | Aholiab
出品 | 区块链大本营(blockchain_camp)
我们都知道,区块链上的数据是不可篡改且永久存储的,所以有的人将爱慕之情写在区块链上,有的人将产权写在区块链上。
设想一下,如果将恶意软件写在区块链上,那岂不是成千上万的矿工都成了你恶意软件的“播种机”?
使用区块链来传播恶意软件到底可行么?这样做又会存在怎样的限制?
带着这些问题,TowardsBlockchain 公司联合创始人、区块链高级工程师 Vaibhav Saini 做了一个大胆的实验。让我们去他的实验中一探究竟。
以下为他对这个实验的叙述。
自从我 2017 年加入区块链世界以来,有一个问题一直困扰着我,那就是:
比特币这样的公链是向每一个人开放的,在区块链网络中有成千上万个节点,它们都在向网络中广播消息,从黑客的角度来说,这是一个不可多得的诱人场景。那么,从技术上来说我们可以通过感染几个节点来撬动整个区块链网络么?
经过几个月的学习与思考,我熟练地掌握了区块链的工作机制,也得出了这个问题的答案。
不得不说这是一个很有意思的问题,所以我将自己的思考过程凝练成这一篇文章,在文章中你将学到:
- 为什么恶意软件难以感染区块链?
- 我们可以使用区块链这种去中心化系统来传播恶意软件么?
- 使用星际文件系统 IPFS 和以太坊存储网络 Swarm 这两个去中心化系统传播恶意软件的动手实例。
废话不多说,让我们开始吧!相信这将是一段有趣的旅程......
为什么恶意软件难以感染区块链?
为了详细地回答这个问题,在这里我们将讨论的范围缩小到比特币和以太坊这两个公链上。
与其他所有区块链一样,比特币和以太坊区块链中的节点都会与其他节点通信,也会执行共识规则来验证交易,生成区块。
现在我们考虑一下攻击的场景,为了在区块链上传播恶意软件并最终感染区块链,我们需要这样做:
- 第 1 步:在交易中发送恶意软件。
- 第 2 步:利用比特币客户端软件中的漏洞。
看起来这两个步骤都没有什么难度,但在真正实现的时候你就会发现它们都多多少少的存在着一些问题。
比如步骤1中存在的问题是,在交易中我们能发送的数据量非常小。
就拿比特币来说,比特币区块的最大容量才 1MB ,平均下来每笔交易占据的空间很小,大约只有 80 字节。
类似的,对于以太坊来说,区块gasLimit限制了区块的大小以及其中代码的复杂度,换句话说,以太坊对交易的大小也有限制。
或者可以这样说,所有的区块链都是如此。
而步骤2存在的问题是,即使我们发送了恶意软件的代码,但让代码运行起来也是一个很大的问题。
这是因为:
- 交易通常都有着固定的格式。许多区块链客户端都不会接收那些格式不匹配的消息。
- 实际上代码的执行环境(例如以太坊虚拟机)有着很多的限制,它只允许执行区区几种类型的指令。此外,虽说以太坊支持智能合约且拥有号称图灵完备的编程语言 Solidity,但以太坊虚拟机的种种限制(例如非常有限的以太坊指令集和非常有限的区块燃料上限)让代码运行的环境与图灵完备几乎不沾边。
而且大多数区块链系统的代码运行环境都是这样。
此外,由于客户端代码往往都是开源的,因此它在落地之前通常都会经过一个非常大的开发者社区的审查,这使得我们在其中找到漏洞的可能性微乎其微。
当然了我并不是说这些客户端不存在漏洞,只是说要是有漏洞的话,那些靠漏洞吃饭的黑客早用来执行攻击了,能被我们捡漏的机会很少。
恶人可以使用区块链来传播恶意软件吗?
上面说到我们很难用恶意软件来感染区块链,但这并不会阻挡我们实验的脚步。我们退而求其次,只用区块链来传播恶意软件可行么?
虽说感染区块链系统很困难,但就传播恶意软件的有效载荷(代码和文件)而言,区块链完全可以胜任。
你可能会疑惑,我们刚才说到由于交易规模的限制,在单笔交易中打包恶意软件几乎不可能实现,是这样的,但是,谁说我们只能使用一笔交易来传播恶意软件呢?
接下来我们就用 K 元(K-ary)恶意软件来做个实验。
其实 K 元恶意软件并不是什么新鲜事物,如果你之前对恶意软件有过了解,相信你并不会对此感到陌生(反病毒专家一定会说,你不按套路出牌)。
K 元恶意软件自 2007 年出现以来已经感染了很多的系统。去年 4 月,黎巴嫩学者 Joanna Moubarak 发表论文详细论述了如何使用区块链传播 K 元恶意软件,接下来我会以严谨但不失趣味性的表述来介绍这种方法。
与传统恶意软件只能被装载到一个实体中不同,K 元恶意软件可以将有效载荷分成 K 个部分。其中每一个部分看起来都像是一个正常的可执行文件,并不会产生任何入侵感染指标(indication of compromise ,IOC,计算机安全术语)。
从原理上来说,我们有两种划分 K 个部分的方法:
- K 个部分按顺序工作。在这种情况下,没有必要保证恶意软件中的这 K 个部分同时可用且同时被激活;
- K 个部分并行工作(同时工作)。在这种情况下,恶意软件中的这 K 个部分必须在同一时间段内可用且被激活。
当然了,具体怎么划分取决于我们所要执行攻击的环境和系统。
为了使攻击更加隐蔽,我们还可以对每个部分进行加密。不过在这种情况下,我们需要分别传输加密过的有效载荷和用来解密有效载荷的密钥。
此外,如何确保执行恶意软件时各个部分不掉链子呢?在执行之前,我们可以使用有效载荷的哈希值来检验各个部分是否都已加入到网络中。
你可能会问,这么做是为了什么呢?区块链能给 K 元恶意软件的传播带来什么帮助呢?
使用区块链有以下优点:
- 区块链上的数据是不可篡改的,而且区块链并不受任何单一实体的控制。这意味着如果我们将恶意软件加入到区块链中,他人很难将它从区块链中删除。
- 密码学哈希函数的使用让恶意软件可以便捷地验证各组成部分的完整性。由于区块链上的数据使用哈希值(基于内容寻址)而不使用存储位置(基于位置寻址)来进行索引,这种保障交易不被篡改的机制也可以用来保障恶意软件的各个部分不被篡改。
演示:使用IPFS和以太坊存储网络Swarm传播恶意软件
区块链可以传播恶意软件,但具体该怎么操作呢?接下来我们将在星际文件系统上进行演示。
这里的恶意软件选用键盘记录器(Keylogger),首先我们使用杀毒软件扫描检测它,然后我们将使用星际文件系统和以太坊存储网络 Swarm 来存储恶意软件的有效载荷,并验证杀毒软件是否能发现各个部分中的猫腻。
我们先下载一个键盘记录器,我已经将它传到了网盘上,你可以登陆网盘下载。接下来,我们试着用杀毒软件扫描一下。
我们可以看到杀毒软件检测出恶意软件。
现在我们把恶意软件分成 K 个部分。这里我们需要先下载并配置星际文件系统。
安装完成后我们使用以下命令将恶意软件添加到星际文件系统中。
代码语言:javascript复制 ipfs add <path-to-malware-file>
我们会得到这样的输出。
到这里,我们的恶意软件已经被分成 K 个部分并被存储在星际文件系统中了。如上图所示,这个恶意软件的哈希值为:
代码语言:javascript复制QmNuAxMT9pepjZ26yXEk4T8qXofJrHoe7SxpoHa5WJ3T5x
如果要查看这 K 个部分,我们可以使用如下命令:
代码语言:javascript复制ipfs ls QmNuAxMT9pepjZ26yXEk4T8qXofJrHoe7SxpoHa5WJ3T5x
命令的输出如下:
前面的数据是各部分文件的哈希值,我们可以用它来取出对应部分的文件。
代码语言:javascript复制ipfs get <hash-of-chunk>
当我们使用哈希值索引来下载某部分的文件时,我们可以完全确定这些文件没有被篡改。
下载完成后,我们再用杀毒软件扫描一下。这时恶意软件各部分的文件都可以通过检验。
上图表明恶意软件的所有部分都是可用的,也就是说我们可以运行键盘记录器来盗取信息了。
注意:这里并没有将文件永久存储在星际文件系统中。该系统中未被固定( pinned )的内容,会被垃圾收集器( garbage collector,通常简写为 GC )删除。
以太坊存储网络 Swarm 提供永久存储的服务,就这点来看,它可能是一个更好的区块链选择。 而且 Swarm 的工作方式与星际文件系统类似,你可以将恶意软件分成 K 个部分上传然后使用其哈希值作为索引来下载它。
*免责声明:文中演示的技术仅以技术探索与求知为目的,不建议在任何实际的公链中尝试,如果这样操作,则后果自负。