0148-恶意程序-分析SYNful Knock 思科植入

# 恶意程序-分析SYNful Knock 思科植入

0x00 综述
=======

* * *

这个植入木马由一个经过篡改的思科IOS镜像组成,能允许攻击者保持匿名性,同时从网络上加载不同的功能模块。这个植入木马还使用了一个秘密的后门密码,能给攻击者提供非限制权限。每个模块都能通过HTTP协议(不是HTTPS)来启用,只需向路由器的接口发送一个特别制作的TCP数据包。这些数据包都使用了非标准的序列号和相应的承认号。而这些模块可以把自己显示成路由器IOS中独立的可执行代码或hook,提供的功能与后门密码类似。后门密码通过控制台,远程登陆协议和权限提升,使用enable命令,能提供对路由器的访问。

图1:模块更新 图2:后门权限

![](http://drops.javaweb.org/uploads/images/bb9aff982a94a9823ca3cf3cc4494383a3ddcfbd.jpg)

已知受影响的路由器:思科1841路由器,思科2811路由器,思科3825路由器

注意:我们在识别之初发现,其他型号的一些路由器可能也受到了影响,因为这些路由器的核心功能、IOS代码都很类似。

0x01 维护
=======

* * *

这个植入木马寄存于一个被篡改过的思科IOS镜像,并且在加载后,植入就能维护自己,系统重启也无法清除。但是,攻击者之后载入的模块就只能储存在路由器的内存中,系统重启后就没有了。从分析的角度看,如果模块是加载到内存中,分析人员就可以通过获取路由器镜像的核心转储来对这些模块进行分析。

0x02 检测方法
=========

* * *

对于能发出命令并接收响应的组织来说,主机标识非常实用。但是只有一小部分的路由器是放置在比较容易接触的网络区域中,在这种情况下,这种方法就是可行的。

对于更分散的组织和不能执行本地命令并接收响应的组织来说,网络标识能起到帮助作用。

最终来看,结合主机标识和网络标识的方法基本上能用于判断底层网络的健康情况。

* **主机标识**

**表1-主机标识命令和预期输出**

![](http://drops.javaweb.org/uploads/images/476275eb87679bf9e3e56c576756693bd963a17c.jpg)

除了表1中的命令,思科的IOS防篡改文档中还提供了其他的一些检测技术:`http://www.cisco.com/web/about/security/ intelligence/integrity-assurance.html`

从文件大小上来看,包含有植入木马的IOS二进制与合法镜像是一样的。所以,从文件大小上无法区别这个镜像有没有遭到篡改。最好的办法之一就是获取思科镜像的哈希,通过比较哈希来检测二进制是不是被篡改过。但是,只有当镜像是在磁盘上,而不是加载到内存上时,这种方法才能发挥作用。

* **网络标识**

曼迪昂特公司提供有主动和被动两种网络检测方法。关于这两种方法的详细介绍请参见下文中的 “网络检测”部分。

0x03 攻击者主要篡改了IOS二进制的下面四个函数:
===========================

* 修改转换后援缓冲器(TLB)读写属性
* 修改一个会被调用的合法IOS函数,并初始化木马
* 使用恶意代码替换合法的协议处理函数
* 使用木马的字符串替换合法函数引用的字符串

1. **TLB读写属性**

木马会强制把TLB的所有与读和写相关的属性都篡改成Read-Write(RW)。我们认为这种篡改是为了让载入模块hook到IOS的函数。如果没有把TLB权限设置成RW,那么缓存页篡改可能就无法影响到内存中的原始页。

遭到篡改的函数可能是IOS中疑似负责配置TLB的函数,攻击者修改了函数中的两个单字节,从而实现了对TLB属性的篡改。在没有篡改时,函数会把寄存器中的前两位设置成1;篡改后,函数会把寄存器的前三位设置成1。曼迪昂特公司认为控制着TLB项写入权限的就是第三位。图3中是遭到篡改的指令。

图3-篡改TLB权限(上为未篡改,下为篡改后)

![](http://drops.javaweb.org/uploads/images/ef12dd2d8312d2f102daf442b1f8abbc1bc816b3.jpg)

这就联系到了我们上面讨论过的主机标识方法。使用enable模式命令 “show platform”就能检查TLB属性。如果IOS映像没有遭到篡改,TLB就会输出图4中的内容。

图4-合法IOS镜像的TLB项

![](http://drops.javaweb.org/uploads/images/208a6025bfcba87a64a5530cc588caa5eb015c05.jpg)

如果路由器中植入了篡改过的IOS镜像,其RW属性就会如下:

图5-篡改后IOS镜像的TLB项

![](http://drops.javaweb.org/uploads/images/22679212e69e9479101f6b5debaf59d2bdfa7728.jpg)

视路由器硬件而定,内存地址的有些特定范围一般是只读的可执行代码部分。检测路由器是否遭篡改的最简单方法就是使用命令“`show platform | include RO, Valid`”。如果没有结果显示,那么,IOS镜像很可能就遭到了篡改,其目的是为了篡改可行代码。

2. **初始化木马**

曼迪昂特公司认为,要想在IOS镜像载入时执行木马,肯定要修改一个与进程调度相关的函数。这是因为,在IOS启动顺序中,遭到篡改的函数会被更早地调用,并且只要IOS启动正确,这个函数就一定会被调用。函数调用的目标地址经过篡改,指向了木马的hook处理函数。我们的研究证明,hook处理函数先会检查被篡改IOS中的调用函数是否是有效的,之后木马就会初始化。现在,木马就上线并运行了,并且会执行原来的IOS函数,这样谁也不会怀疑。

曼迪昂特公司认为,遭到篡改的函数与进程调度任务有关联,当这个函数被调用时,函数就会进入一个无限循环。另外,它的几个子函数也会引用与进程调度相关的字符串,比如 “`Threshold: %s CPU Utilization(Total/Intr):…`”。

3. **替换成木马的可执行代码**

为了防止镜像的文件大小发生变化,木马会使用自己的可执行代码覆盖几个合法的IOS函数。攻击者还会检查当前路由器的功能,然后判断可以覆盖哪些函数而不导致路由器发生问题。所以,在不同的部署中,可能会覆盖不同的函数。

4. **木马的字符串和配置**

承接上文,因为镜像的文件大小没有变化,这个木马还用自己的配置覆盖了一些reporting字符串。这个入侵标识也可以用来检测篡改。图6中是被覆盖的合法字符串。

图6-木马覆盖了这些与一个有效函数相关的字符串

![](http://drops.javaweb.org/uploads/images/983cec16c43ad1fe96d1b57fcdff9a272d25cace.jpg)

木马就是用下面图7中的内容覆盖了图6中的内容。这很明显就是木马的字符串(包括CC中使用的HTTP标头),以及默认的密码-我们故意抹去了。这样,潜在的受害者就有时间来查看自己的网络有没有遭到入侵,从而修复这一问题。如果你怀疑你的系统被入侵了,请联系我们的邮箱`synfulknock [at] fireeye.com`,我们会提供给你密码。

图7-木马字符串

![](http://drops.javaweb.org/uploads/images/f7997a3a15e8e80b4c04bc8a11d9c20d68df4ed4.jpg)

这个主机标识,也可以用于识别植入木马。但是,首先需要找到配置字符串的位置,而在不同的部署中,其位置可能也不同。当运行一个常规的IOS命令时,篡改过的IOS镜像会输出一个非常可疑的结果,如下:

视植入木马而定,在运行了一个合法的IOS命令后,可能会显示后门标头。

![](http://drops.javaweb.org/uploads/images/7e2036af8ecae2adf42e231ec9eb6c840b491e74.jpg)

0x04 后门密码
=========

* * *

攻击者可以在三种不同的认证方案中,利用后门密码。植入木马首先会检查用户输入的是不是后门密码。如果是,则授予权限。否则,植入代码就会传递凭据,以便验证凭据的有效性。这就有些可疑了。在使用后门木马时,下面的三个实例在经过验证后就能启用权限:

![](http://drops.javaweb.org/uploads/images/005e739ed6734cabbd2353fdaba9606a92044afd.jpg)

但是,此次研究表明,SSH或HTTPS会话并不能给后门密码提供权限。这可能是一个配置问题,在不同的入侵中,情况也可能发生变化。

图8-合法密码验证与后门密码验证之间的细微差别(上为合法密码,下位后门密码)

![](http://drops.javaweb.org/uploads/images/bd50ef219081eb8f3c0c2d851f393f5364db00c0.jpg)

0x05 网络命令和控制
============

* * *

植入木马的CC部分是模块化的,并且能在IOS中加载额外的功能。其CC功能是秘密进行的,因为CC功能需要一系列的TCP触发数据包,木马会监视这些数据包,寻找特定的TCP标头值和内容。即使路由器启用了过滤,木马还是能处理TCP触发数据包。木马会响应从3个地址上发出的触发数据包,分别是:路由器接口,广播IP和网络位置(子网中的第一个IP)。

1. 要想初始化进程,必须向植入路由器的端口80发送一个特制的TCP SYN数据包。值得注意的是,序列号和承认号之间的差值必须设置成0xC123D。另外,ACK号不一定必须是0。

图9-TCP SYN序列号和承认号之间的差值是0xC123D

![](http://drops.javaweb.org/uploads/images/cb3e3e56e780be6b3aabe960e7a152cb0c9c2dcb.jpg)

2. 虽然,木马通常有3种握手方式,会响应一个TCP SYN-ACK信息,承认第一个SYN信息。但是,要避免下面的情况:

* 承认号和序列号现在的差值现在是 0xC123E
* 设置下面的这些硬编码选项:`02 04 05 b4 01 01 04 02 01 03 03 05`
* 紧急指针设置到了0x0001,但是没有设置紧急旗帜
* 木马从SYN数据包中复制承认号作为序列号。正常的服务器会生成一个随机序列号,所以说这不是标准的TCP握手

图10-TCP SYN序列号和承认号之间的差值是0xC123E

![](http://drops.javaweb.org/uploads/images/1f450c90c0bb2d0ebb616a4a9a75577ff34373c8.jpg)

3. 当最终的 ACK 完成了3种方式的握手后,控制器接下来会发送下面的 TCP 信息:

* PUSH和 ACK 旗帜已设置
* 从TCP标头开始,在偏移0x62上,写入了字符串“text”
* 下面的命令位于TCP标头的偏移0x67上

命令的格式如下:

`[4字节命令长度][CMD数据][4字节校验和]`

[CMD 数据]使用了一个静态密钥,进行了异或。校验和的算法是对解码后的[CMD数据]进行4字节异或。

图11-控制器命令数据包

![](http://drops.javaweb.org/uploads/images/58daba857d9b39454eda327d5ea64888a1499f0d.jpg)

4. 木马响应就包含在下面的静态HTTP/HTML服务器响应中。

![](http://drops.javaweb.org/uploads/images/2f14e646330bb584ab466c362757c1b0d6d84936.jpg)

图12-受害者响应

![](http://drops.javaweb.org/uploads/images/44d7a67a36782b92f67880b073ff8da4f5fd635c.jpg)

0x06 受支持的命令
===========

* * *

我们之前提到过,这个植入木马是分模块的。下表中的前五个命令是用来在受害者的路由器上加载额外的模块和功能。总共可以加载100个额外模块,但是,这些模块都是储存在内存中,在重启或重载后就没有了。

命令信息会把第一个WORD(4字节大端/大端字节序)设置成0。第二个WORD会识别命令类型(从0-4的值)。所有的信息类型都会以下面的8个字节开头:

`00 00 00 00 00 00 00 [00 – 04] [可选参数]`

表3-受支持的命令

![](http://drops.javaweb.org/uploads/images/5123faccc3d46f11775d7cb169bbfcc70de184c0.jpg)

![](http://drops.javaweb.org/uploads/images/64575e43a52c1d703da3d7d8f664d418c3e004dd.jpg)

![](http://drops.javaweb.org/uploads/images/c2b51b5d91d73a0797c336802e235c304620f173.jpg)

如果信息的第一个WORD不是0,与第一个WORD模块ID相关的代码就会执行。这样没有hook到IOS函数的代码就可以执行了。

网络检测
—-

主动和被动网络检测都可以部署用来检测并防止SYNful Knock的入侵。被动检测可以整合到网络防御传感器上,同时也使用主动技术来猎捕后门。

* **被动网络检测**

被动网络检测的方法有很多。我们的网络检测签名主要集中在CC会话中的四个部分:SYN,SYN-ACK,木马响应信息和控制器命令。IDS必须要能够监控路由器的外部接口,才能有效地检测到网络中的后门。

**1. SYN: **

第一个签名(附录A)是利用TCP序列号和承认号之间的差值来检测SYN数据包。为了降低误报率,签名会假设承认字段不是0。这个签名能检测木马探测,并不一定能说明目的位置被入侵了。

**2.SYN/ACK:**

第二个签名(附录B)会验证TCP序列号和承认号之间的差值和TCP选项来检测木马发出的SYN ACK响应。这个签名假设SYN数据包中的承认字段是0。

**3.木马响应信息:**

当一个命令发出时,下面的签名会检测HTTP服务器响应。下面签名的优势在于,这个签名是一个标准的snort签名;但是,这个签名不能验证TCP序列号和承认号之间的差值。

![](http://drops.javaweb.org/uploads/images/3cdc63e40fa347474707396052999611faf0881c.jpg)

**4.控制器命令**

下面的签名会检测从控制器中发出的命令。它会在木马预期的位置上,使用 “text”字符串,其信息的大小会少于256字节。这个签名还会假设不会呈现TCP标头选项。如果包括了TCP标头选项,签名可能需要转换成经过编译的签名或创建多个变体来处理每个长度。

![](http://drops.javaweb.org/uploads/images/1f2f6e00c1ba1ad96f78cc6eb6ee3af9ca308f9d.jpg)

* **主动网络检测**

* **Nmap 脚本引擎(NSE) **

曼迪昂特公司用LUA语言写了一个NSE脚本来主动扫描这个思科植入木马。

* **要求:**

* Nmap v6.47 或更高版本(也测试了v6.49)
* 修改过的nselib
* **修改过 NSE 库**

NSE数据包库不允许用户修改ack值;所以,曼迪昂特公司修改了这个库来允许这个功能。区别如下:

![](http://drops.javaweb.org/uploads/images/a7629dc87f75d2dea4b53d926d388802bd844e53.jpg)

* **估计最坏情况下的速度()(`THIS FACTORS IN HIGH UNUSED IP SPACE`) **

曼迪昂特公司首先用Nmap的默认扫描速度-T3来运行这个扫描:

`nmap -sS -PN -n -T3 -p 80 –script=”SYNfulKnock” 10.1.1.1/24`

**Class C **- 256 IP 地址 (4 hosts up) – 扫描用时2.29秒

然后曼迪昂特公司用Nmap的默认扫描速度-T4来运行这个扫描:

`nmap -sS -PN -n -T4 -p 80 –script=”SYNfulKnock” 10.1.1.1/24`

**Class C **- 256 IP地址 (4 hosts up) – 扫描用时2.28秒

`snmap -sS -PN -n -T4 -p 80 –script=”SYNfulKnock” 10.1.1.1/16`

**Class B **- 65536 IP 地址(4 hosts up) – 扫描用时2557.50秒 (42 分钟)

`nmap -sS -PN -n -T4 -p 80 –script=”SYNfulKnock” 10.1.1.1/8`

**Class A **- 16,777,216 IP地址 – 预计扫描时间 = 10,752 分钟(179 小时) = 7 天

* **旗帜说明:**

“`
-sS = SYN 扫描
-PN = 不执行主机发现 -n =不执行名称解析 -T4 = 加速到速度4
-p = 端口号
–script = 执行脚本
optional: –scriptargs=”reportclean=1” 也显示洁净设备的seq 和 ack

“`
* **Python 检测脚本**

曼迪昂特公司还写了一个Python脚本来主动扫描这个思科植入木马。这个脚本会发送一个定制的TCP SYN数据包,并分析SYN/ACK响应,查看有没有木马标识。这个脚本需要依赖Scapy数据包操作库 (http:// www.secdev.org/projects/scapy/) 来处理,发送和接收数据包。扫描进程会使用几个扫描线程,和一个独立线程来收集响应。这个脚本比nmap脚本慢20倍;但是,非常适合小规模的扫描和快速扫描验证。

* **要求 **

* Python
* **速度**

**Class C **- 256 IP 地址 (4 hosts up) – 59.26秒 **Class B **- 脚本提早终止

* **命令行**

`python ./SYNfulKnock_scanner.py -D 10.1.1.1/10.1.1.2`

* **旗帜说明:**

`-d = 扫描目标 (IP, IP/CIDR, 第一个 IP/最后一个 IP)`

* **输出**

“`
python ./SYNfulKnock_scanner.py -D 10.1.1.1/10.1.1.2
2015-07-14 12:59:02,760 190 INFO 嗅探器后台程序启动
2015-07-14 12:59:02,761 218 INFO 用10个线程发送2个数据包
2015-07-14 12:59:03,188 110 INFO 10.1.1.1:80 – 发现植入的seq: 667f6e09 ack: 66735bcd
2015-07-14 12:59:03,190 225 INFO 等待完成发送
2015-07-14 12:59:03,190 227 INFO 所有发送的数据包

“`
* **旗帜Nping **

曼迪昂特公司发现,还可以使用nping(或hping)等工具来检测这个思科植入木马变体。

* **要求 **

* nping (用nmap安装)
* **速度**

**Class C **- 256 IP 地址(4 hosts up) – 257.27秒

* **命令行**

`nping -c1 -v3 –tcp -p 80 –seq 791104 –ack 3 10.1.1.1`

* **旗帜说明:**

“`
-c = 计数
-v = 信息级别
–tcp = TCP探测模式
-p = 端口
–seq = 序列号
–ack = 承认号
-H = (可选) 隐藏发送,可以加速扫描

“`
* **输出**

“`
nping -c1 -v3 –tcp -p 80 –seq 791104 –ack 3 10.1.1.1
Starting Nping 0.6.47 ( http://nmap.org/nping ) at 2015-07-14 16:08 EDT
SENT (0.0048s) TCP [10.1.1.3:37895 > 10.1.1.1:80 S seq=791104 ack=3 off=5 res=0 win=1480 csum=0xED6E urp=0] IP [ver=4 ihl=5 tos=0x00 iplen=40 id=8373 foff=0 ttl=64 proto=6 csum=0x4416]
0000 4500002820b50000
0010 0a01010194070050
0020 500205c8ed6e0000
RCVD (0.0092s) TCP [10.1.1.1:80 > 10.1.1.3:37895 SA seq=3 ack=791105 off=8 res=0 win=8192 csum=0x9256 urp=0 ] IP [ver=4 ihl=5 tos=0x00 iplen=52 id=18496 foff=0 ttl=255 proto=6 csum=0x5d7e]
400644160a010103 000c124000000003
E..(….@.D….. …….P…@…. P….n..
0000 45000034 0010 0a010103 0020 80122000 0030 01030305
48400000 ff065d7e0a010101 00509407 00000003000c1241 92560000 020405b401010402
E..4H@….]~…. …..P………A …..V………. ….

“`

高亮区域是序列号和承认号。其差值必须是791102,上述的TCP旗帜选项必须是“`20 04 05 b4 01 01 04 02 01 03 03 05`”。

0x07 应对方法
=========

* * *

在确认遭到入侵后,最有效的应对办法是下载一个干净的镜像,再刷到路由器上。保证新镜像的哈希值,然后加强设备防御攻击的能力。在综述中提到过,初始入侵是由默认凭据或发现的凭据造成的,在修复了路由器后,重点就落在了网路上的其他部分上。如果路由器没有默认的凭据,感染就一定是通过其他方式导致的。接下来就是对入侵进行评估。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容