【51CTO.com快译】2016年9月份以来,发生了多起大规模DDoS攻击事件。本文针对这些攻击事件中使用的恶意软件“Mirai”的源代码进行分析,进一步介绍Bot(客户端)的结构,以及其应对方法。
2016年9月13日晚,美国著名安全记者Brian Krebs氏的网站“Krebs on Security”被DDoS攻击,mirai Botnet发动了此次攻击。Mirai主要是以网络摄像头、路由器、数码录像机等IoT设备为跳台进行DDoS攻击。
据受到攻击后Krebs氏的博客报道,保护该网站的Akamai观测到在高峰时期受到了有史以来经历的最大规模攻击近2倍的流量访问。
另外,2016年10月21日Twitter、Netflix等利用DNS服务进行的DDoS攻击,也被推断利用了Mirai僵尸网络。
然后在Krebs氏网站受到攻击后,黑客平台上Mirai的源代码被公开成为了很大的话题。随后源代码又在GitHub上被转载,谁都可以看到具体内容。
源代码被公开,Mirai Botnet以出厂设置的密码未被更改的IoT设备为目标,进行一般的字典攻击扩大感染范围。据说在进行前述的攻击时,也有几十万台的设备受到僵尸网络攻击。
近年来各种各样的IoT设备得到普及,存在漏洞的设备也在不断增加,受到大规模的DDoS攻击的可能性也会增大。另外,通常这些设备采用的架构是不同于个人的电脑等的多种多样的,不过,Mirai可应对ARM、ARM 7、MIPS、PowerPC、SH4、SPARC x86等各种各样的架构,这与大规模感染的扩大有一定关系吧。
本稿中,以现在GitHub上被公开的代码为基础,解说Mirai Botnet的运作,并且反思使家庭及企业的设备远离僵尸网络的自卫对策。
被公开的Mirai Botnet的源代码可大致分为以下3个部分:
1. 攻击者操作的C&C(Command and Control)服务器功能
2. C&C服务器中被操作的Bot功能
3. Bot程序发布的Downloader功能
C&C服务器部分为Go语言,Bot、下载部分以及其他的加密工具等主要为C语言。对照被公开存储的目录,Mirai的构成如下(List 1)
List 1 目录构成
Mirai Botnet 是攻击者通过①C&C服务器向②Bot发送指令,形成以大量的Bot为攻击对象的C&C中心型僵尸网络。同时,Bot会扫描可感染的设备,将找到的设备信息发送给Report服务器,由③downloader植入Bot程序。(图1)
(图1.Mirai的动作)
在这里,首先从C&C服务器的代码开始解读Mirai。
◆ Main函数
由于Mirai的C&C服务器部分为Go语言,最初被执行的mirai/cnc目录中main.go文件内的main函数被读取(List 2)。再者,以下代码中虽然有补充的评语,但是,日语之外的评语是原本就记载的内容。
List 2 main.go内的main函数
Mirai的C&C服务器起初是建立在Telne服务器与API服务器之间的。“go~”的部分是利用Go语言degoroutine的非同期被处理的部分。
apiHandler函数中的经由API初期化接受来自攻击者的操作处理程序。initialHandler函数中,初期化向连接Telnet的Bot发送指令的处理程序以及实现C&C服务器上指令行接口的处理程序(List 3)。
List 3 main.go 的initialHandler函数
也就是说,这个C&C服务器的操作可能利用API,也可能通过Telnet连接CLI发送指令。解读源代码的话,无论使用哪个方法都是需要认证的。
◆ 认证部分
从api.go文件种Handle函数内的数据看,送来的要求中含有的apikey没有在C&C服务器内登录的话,能够读取未接收的指令。(List 4)
List 4 api.go中的Handle函数的认证部分
admin.go中实装的处理程序也同样,在CLI上操作时需要使用用户名和密码登录。(List 5)
List 5 admin.go中的Handle函数的认证部分
另外,命令行在登录时要求输入俄罗斯语,因此推断制作者或利用者可能是俄罗斯圈的人。
◆ 用户管理部分
那么,怎样才能把这些信息登记在数据库上呢?读取源代码访问C&C服务器上的CLI时,如果是管理者用户的话可以从CLI注册登录(List 6)。
List 6 admin.go的Handle函数内的用户登录部分
然而,管理员账号本身是预先插入数据库中的,被公开的代码中没有管理员账户登录的相关内容。
另外,数据库的users桌面上,除username及password之外,还有max_bots、last_paid、cooldown、duration_limit等列,这些列被用于创建攻击指令,因此每个用户能够利用的Bot数量、攻击间隔、账号等均受控制。并且,用户向僵尸网络持有者支付金钱的时间等都保存在C&C服务器的数据库中。(List 7)
List 7 database.go内的CreateUser函数
综上所述,是否可以认为Mirai Botnet的所有者使不特定的多数人以金钱等交换利用了僵尸网络呢。
◆ Bot 管理部分
接下来,看看Bot管理部分吧。首先从Bot连接C&C服务器的话,main.go文件中的initialHandler函数中NewBot.Handle函数被唤起,根据Handle函数的处理Bot信息将被添加到列表中(List 8)。
List 8 bot.go内的Handle函数
存储Bot信息的clientList是全球变数,main.go内运行main函数之前就被制作了。另外, clientList在新制作的时候,非同步接收的Worker制作Bot指令,等待Bot指令。
◆ 攻击指令的制作部分
接下来,以攻击者C&C服务器的输入为基础,看看Bot指令的制作部分吧。在API、CLI等输入指定攻击种类·攻击对象的命令,便会在attack.go内的NewAttack函数内完成应对接受指令的Flag设置。在同文件夹中的attackInfoLookup Map内定义了可能利用的攻击种类(表1)(List 9)。
表1 Mirai Botnet可执行的攻击种类
List 9 attack.go内attackInfoLookup Map
从表1了解到,Mirai可使Bot受到各种各样的DDoS攻击。
另外,VSE平台攻击中被瞄准的游戏引起“Source Engine”是非常有人气的一款在线游戏“反恐精英”中使用的引擎。这样被特意定义,由此可见这样的在线游戏可能被作为攻击的目标。利用GRE等次要的协议进行攻击是有可能的,因此Mirai可回避一般的DDoS攻击对策。
然后把这些攻击Falg设定组装后,同文件的Build函数内将这些攻击设定为二进制向Bot发信。这样就可以向Bot完成数据的发送。
◆ 指令发送部分
最后,看看从C&C服务器向Bot发送指令的流程吧。二进制的攻击设定移交至clientList.go文件内的QueueBuf函数,如名字所示保持Bot的指示被放置在缓冲区列队中(List 10)。
List 10 clientList.go的QueueBuf函数
接收信息的atkQueue频道从持有的Bot信息列表到攻击者可利用的Bot上线数为止在Bot单体的缓冲区排列攻击设定。
List 11 clientList.go内的worker函数
然后,排列的攻击设定最终会被发送到Bot单体(List 12)。
List 12 bot.go内的QueueBuf函数
接下来,看看Bot客户端的运作吧。由于客户端是C语言编写的,首先让我们从mirai/bot目录以下的main.c开始解读吧。
◆C&C的连接部分
main.c内的main函数里,启动后本身的过程名伪装成随机的名字,无线循环地呼出establish_connection函数,将加密的C&C服务器的域名和Bot解密后连接在一起(List 13)。
List 13 main.c内的main函数与establish_connection函数
在这里,establish_connection函数里名为resolve_fudc函数被同文件内anti_gdb_entry函数替换,所以实际上也被称作resolve_cnc_addr函数(List 14)。
况且,C&C服务器的域名中,对table.c文件中被定义为“0xdeadbeef”的值实施seed值XOR加密,C&C服务器的解析会变得较困难。
List 14 main.c内的anti_gdb_entry函数与resolve_cnc_addr函数
成功连接后,Bot向C&C服务器中发送二进制“/x00/x00/x00/x01”(List 15)。
List 15 main.c内的第263行
发送这个二进制的话,List 3中if文变为true,被称为NewBot函数,保持C&C服务器与Bot的连接。
转自List 3
◆攻击部分
接下来,我们一起看看Bot如何接收来自C&C服务器的攻击设定,以及实际上是在攻击吗?基本上,Bot是等待来自链接main函数的无限循环C&C服务器发送过来的命令。接收命令后传送attack.c文件内的attack_parse函数,然后运行与attack_start函数内接收命令的攻击设定一致的攻击用函数,开始所指定种类(表1中无论哪个)的DDoS攻击(List 16)。
List 16 attack.c中的attack_start函数
◆感染源扫描部分
Bot在等待来自C&C服务器命令的同时,main函数中被称为scanner_init的函数开始寻找新的可加入Bot的设备。
如何扫描新的感染源呢?生成随机IP(List 17)试图连接,在连上的时候利用字典攻击进行搜索。
List 17 scanner.c中的scanner_init函数的一部分
使用字典攻击从scanner.c文件的第125行定义用户名与密码(List 18)。
List 18 scanner.c中被定义的一部分用户名和密码列表
最初的一行中虽记录着root与xc3511的组合,这是2016年10月21日进行DNS服务攻击的跳台防盗摄像机设定的组合,随后该设备被回收了。随后会给出一份用户名与密码的组合清单,请确认一下您的设备所使用的用户名与密码。
若发现可登录的末端,Adress、Bot、登录信息会发送到服务器(List 19)。
List 19 scanner.c中的scnenner_init函数内的一部分
追踪report_working函数的话,因送信源服务器与C&C服务器是不同的域名(被定义为TABLE_SCAN_CB_DOMAIN域名),Bot是发现的收集新感染源信息的服务器,与C&C服务器是不相同的(List 20)。
List 20 scnaner.c中report_working函数
最后让我们了解一下发布Bot程序的Downloader部分吧。下载Bot运行文件的Downloader部分是由C语言编写的,但是在前面提到的Bot收集的感染源信息的Report服务器的程序存在关于发布的部分,所以也一起了解一下吧。
◆感染源收集的部分
首先,解读一下Report服务器的部分吧。mirai/tools目录下的scanListen.go文件单体拥有Report服务器的作用。main函数中等待来自Bot的连接,连上的话会运行handleConnection函数(List 21)。
List 21 scanListen.go中的main函数
在handleConnection内只是输入从Bot发送来的感染源信息,与其说是收集功能,倒不如说是将发送过来的信息传递给Downloader的简易功能(List 22)。
List 22 scanListen.go内的handleConnection函数
从Bot接收的感染对象的信息,是在loader/main.c文件的main读取,传送给server_queue_telnet函数(List 23)。
List 23 main.c文件中main函数的一部分
随后,将感染源信息从server_queue_telnet传递到server_telnet_probe函数,连接感染源(List 24)。
List 24 server.c文件中server_telnet_probe函数的一部分
连接后进行登录,自主下载(表1中介绍的dlr目录下的东西)、wget、TFTP中,利用任一可能的方法下载Bot的执行文件(List 25)。List 25中只介绍了wget的情况。
List 25 server.c文件中handle_event函数的一部分
在这里,wget执行时虽利用了busybox,但这是组装机器用的Linux也能运行标准UNIX命令的简易设计程序。
接下来,运行下载的Bot(List 26)。按照这样的流程感染存在漏洞的设备,添加新的僵尸网络。
List 26 server.c文件中handle_event函数的一部分
最后,如何才能避免感染这样的僵尸网络呢,重新思考一下应对方法吧。
就像我们了解到的那样,Mirai是将随机生成的IP地址连接Telnet,感染字典攻击可突破的设备。基本上是采用把出厂设置的密码改成较难推断密码的方法,便能有效躲避感染。
以下记载着Mirai使用的用户名与密码的组合列表。再确认一下是否有相同设置的吧。
表2 Mirai利用的用户名与密码一览表
但是,由于Mirai的源代码被公开诞生了亚种,这些亚种未必会使用相关的密码列表。因此,不要因为在公开的密码列表之外就大意,设定不容易被类推的密码等,最好只访问信赖度高的网站。
另外,此次感染了Mirai的设备若是公司内部的连网设备,很有可能作为跳台已经成了入侵的开端,需要十分地注意。
从Krebs氏的网站受害中发觉的一些列由Mirai引起的DDoS攻击渐渐地演变成大规模的攻击。不仅如此,如前所述即使Mirai僵尸网络自身被消灭了,但是不同的Mirai亚种的僵尸网络仍然会出现吧。
实际上,按照黑客平台上投稿的流程进行环境整备,只需要拥有一点知识,短时间内便能完成Bot与C&C服务器的执行文件的建立,利用大部分代码便能制作出亚种。
DDoS攻击对策等更重要的是针对来自Bot的攻击对策,为了彻底消除僵尸网络,尽量减少可支持僵尸网络的设备也同样重要。在正确理解僵尸网络的威胁后采取对策,希望本文能够给大家带来帮助。
原文标题:「Mirai」ソースコード徹底解剖-その仕組みと対策を探る,作者:西脇春名)
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】