分析HNS僵尸网络
Hide and Seek(HNS)是一种恶意蠕虫,主要感染基于Linux的物联网设备和路由器。此类恶意软件会通过暴力破解SSH / Telnet凭证以和利用一些已知的CVE进行传播。HNS的独特之处在于没有命令和控制服务器,而是使用从受感染设备创建的自定义的P2P网络接收更新。
僵尸网络的连通性
每个受HNS感染的设备会在端口上运行一个UDP服务器,该端口要么在感染时提供要么随机分配。新感染的设备会被给予IP和端口组合的列表,对应于其他的HNS感染设备(称为对等点)。受感染的设备会保有一个包含其他对等设备的列表,这些对等点的大小基于可用的RAM(通常在512左右)。
在对等点列表已满之前,设备将向列表中的对等点发送请求消息,收到对等请求后,接收方会做两件事:首先,它会将发件人的IP和端口添加到自己的对等列表中;其次,它从自己的列表中回复一个对等点。使用此技术,受感染的设备将发现其他受感染的设备并保持与它们的连接。
为了接收更新,每个bot会定期向其列表中的对等点询问配置版本号,当发现某一个点的版本号高于自身时,它会从该对等点下载新的配置。要执行更新,僵尸网络的操作人员只需要上传一个新的配置到一个受感染的设备,接着设备就能把更新后的配置分发给所有的对等点,这些对等点也将执行相同的操作。
跟踪对策
通常,跟踪P2P僵尸网络会非常简单:通过向已知的对等点发送对等点请求,可以找到新的对等点,因此,只要递归地向所有对等点发送对等请求最终应会发现整个僵尸网络。但出人意料的是,HNS有一些应对跟踪的对策。
上面这段代码是负责处理传入的对等请求的代码。如果接收方的对等列表已满(几乎总是满的),则使用发送方的IP作为列表索引[第7行]。本质上,当从同一个IP向同一个目标发出多个对等请求时,总是得到相同的响应。
我们可以通过查询一个对等点来找到一个新对等点,再通过这个新对等点来找到另一个对等点,以此类推……但是,只有有对等点返回的是我们已经找到的对等点,或者返回一个已失效的对等点,这个找寻过程将逐渐停止。
在测试中,我从每个起始对等点开始获得大约4个新对等点后,就会返回一个无响应的对等点。
对等点列表的滚动
上图是负责更新对等列表的代码片段。如果接收到来自尚未在对等点列表中的对等点的请求,但列表已满,则会按上述代码执行。
这段代码会检查时间戳的7位低位字节是否为零(每128秒发生一次)。如果是,则用新对等点覆盖列表中的随机对等点,并设置互斥锁。
由于对等点的数量超过了列表条目的上限,因此代码几乎每隔128秒就会使列表覆盖1个对等点。假设对等列表限制为512个对等点,则照理说每隔约18个小时,所有的对等点条目都会被替换。
因此,随着名单的不断变动,我们可以慢慢建立一个更长的名单。首先,我们递归地发送对等请求,直到我们得到一个失效对等点(通常在4次迭代之后)。现在我们等待几个小时,然后再递归地查询以前找到的所有对等点,这样,我们在完善列表上所花费的时间应是18小时*4。
新挑战出现
一位研究的同行向我提供了一个可以逆向的样本,并表示想知道我的爬虫要多久会被他们发现,我说大约是5分钟,因为UDP允许使用一些简单的技巧来加速传播。
在他们的一篇关于爬虫程序的文章中有介绍说,他们花了几天的时间才积累了1000个对等点。为了在5分钟内引起他们的注意,我需要发现足够多的对等点,并让自己进入足够多的对等点列表,这样才能将我的IP转发给他们。
对等点的快速发现
首要任务是在18小时内从同一对等点处得到一个以上的回应。在前文中我曾说过,一个对等点会对用同一IP使用相同的响应。但是多个IP呢?
发送方IP会被用作对等列表的索引,每个对等列表条目都是唯一的。如果我们从两个不同的IP地址发送一个请求,我们将得到两个不同的对等点。对等点列表没有设置顺序,因此我们查询的每个对等点可以返回两个不同的对等点。
我的服务器最多允许3个IP地址,所以我可以从每个对等点得到3个不同的响应,并可以以3n的最大速率进行查询,但是已失效的对等点,以及跑到后期出现同一对等点的概率将大大增加,会极大减慢查询的速度。
测试运行
为了测试,我给爬虫一个单一的对等IP,并设置它每秒钟查询所有已知的对等。下图是展示的结果。
对等点发现的速度呈指数级增长,直到数量上涨至约500个后开始迅速减少。这可能是由于许多对等点列表都被限制在512个条目左右。较高的正常运行时间的对等点传播得更远,因此大多数较小的对等点列表由相同的正常运行时间较高的对等点组成。
为了促进对等点的发现,我们需要进入一些对等点列表。通过存在于多个对等点列表中,我们将被较新的对等点发现,从而使它们与我们连接。
对等点代码修改
如果一个对等点的列表没有填满,将添加请求接收的每个对等点。我们所需要做的就是映射我们发送请求的端口,接着就能看到传入的请求。
如果目标的对等点列表已满,那么我们必须处理那段每128秒只能覆盖1个对等点的代码。
按照代码的工作方式,当时间戳的7位低位字节为0时,我们需要能比bot更快地发送请求,虽然我们发送请求的速度已经远远超过了正常的机器,但我们仍然可以通过在时间戳的7位低位字节为0时,正确的安排发送请求的时间来让机会更有利于我们,这样,我们就能做到比bot更快。
由于高请求量、一些机智的时间安排,加上一点运气,我们可以在整个僵尸网络中快速传播IP。
最终测试
在这个测试中,我让爬虫运行5分钟,然后禁用所有传出请求。因此,只有包含爬虫IP的对等点列表的对等点才会继续与我们通信。
这是禁用传出请求后5分钟内的唯一IPs图。
Total表示唯一IP地址的总数;Responsive意味着在60秒滚动窗口内发送请求的唯一IP地址。
正如你所看到的,我们在5分钟内就完成了450个对等点列表(约占所有在线机器的35%)。随着总计数继续攀升,其他在线对等点会将我们的IP传播得更远。Responsive计数的突然下降,是因为爬虫IP最终会因为不活跃而从对等列表中删除。
我认为这足以让其他爬虫注意到我,但我们可以做得更好。
可能的改进
这一切都是在5美元的云VPS上完成的,但是裸机服务器会更理想。更大的带宽、更高的吞吐量、更低的延迟和更多的IP,将允许我们在不到5分钟的时间内传播到整个僵尸网络。
也有更有侵略性的爬行技术可以利用,然而,一些受感染的设备非常脆弱,可能会在压力下崩溃。
判定
在我跟踪P2P僵尸网络的这些年里,流传着这么一个事实:你无法阻止一个意志坚定的安全研究人员绘制出整个僵尸网络。在过去的几十年里,有许多P2P僵尸网络试图阻止爬虫,但都失败了。简单地说,对爬虫的任何限制也会限制bot程序发现新对等点的能力。僵尸网络操作人员必须在“让对等点难以被发现”和“拥有一个稳定的僵尸网络之间”做选择。
Hide and Seek阻止爬虫的手段也导致了一些情况——bot很大程度上都会感到“困惑”并“迷路”(我想这是Hide and Seek躲避爬虫的一种方法)。
许多物联网设备在ram磁盘上运行,这意味着系统重启后感染也就失效了。缺乏持久性会导致对等点的快速消亡,且由于发现的对等点是有限的,bots可能最终会得到一个满是失效的对等点的列表。实际上,根据Virus Bulletin的演示文稿,僵尸网络的前一次迭代在其自身的重压下完全崩溃了。
统计数据
截至今天,HNS拥有大约6,000个受感染设备,同时在线约有1300个。
有关更深入的统计信息,请查看我的僵尸网络跟踪器。
参考材料
1. https://blog.avast.com/hide-n-seek-botnet-continues
2. https://www.virusbulletin.com/uploads/pdf/magazine/2018/VB2018-Sendroiu-Diaconescu.pdf
3. https://intel.malwaretech.com/botnet/hns/
特别感谢AdolfStředa和VessOnSecurity提供的样本和进行分析的对等点列表。