关键词:Linux、rootkit、分析、恶意软件

1.背景介绍

rootkit是一种危险的恶意软件,一旦它们被植入主机便难以被检测到。这种软件相比于其他恶意软件更难被编写,因此开发者通常会复用开源rootkit项目进行开发。由于rootkit分析起来较为有趣,Avast研究团队一直在尝试捕获在野利用样本。

Adore-Ng是一类早期、开源且被广泛利用的Linux内核rootkit,它最初是被用来攻击2.x版本的内核,后来逐渐扩展攻击面至3.x版本。由于它具有隐藏进程、文件甚至内核模块的功能,因此更难被检测到。已授权的用户态进程同样可以与之交互从而控制rootkit的运行行为,这使得攻击者在仅使用一个简单rootkit的情况下就能达到隐藏大量自定义恶意组件的目的。

2022年初,Avast研究团队捕获到了一个在野rootkit样本。该样本主要基于Adore-Ng项目并且处在持续开发中。样本.modinfo段中的信息表明它是基于某个特定内核版本进行编译的。

图1: .modinfo段信息

众所周知,即使使用linux命令insmod的—force参数对某个模块进行强制内核载入,这个载入操作仍然可能因为某个版本的系统内核缺失所需的符号而失败。如果载入失败会进一步导致系统崩溃。

通过研究发现这种rootkit能够在Centos 6.10发行版及其相近的内核版本上运行,因为其所需的内核模块可以无需—force参数顺利载入。同时rootkit中有一处特殊的硬编码文件名PgSD93ql。该文件名可能是起到伪装效果,比如说它看起来像合法的PostgreSQL文件。

图2: 只读数据段硬编码字符串

通过硬编码文件名可以分离出被rootkit隐藏的可执行文件。该文件是由C语言编写的一个木马后门,Avast反病毒引擎将其归类成ELF:Rekoob,即Rekoobe恶意软件家族。Rekoobe是一类植入于合法服务器的代码片段。在该案例中,它潜伏在一台伪装的SMTP服务器中。当Rekoobe接收到某条特制命令时它将在主机上开启一个shell。由于特制命令会被写入到文件/proc/syslogk,Avast研究团队将该rootkit称为Syslogk rootkit。

2.Syslogk rootkit分析

Syslogk rootkit的开发主要基于Adore-Ng项目进行,在此基础上开发者还添加了一些新功能使得用户态应用程序和内核rootkit更难以被检测。

2.1 内核模块加载

将Syslogk rootkit载入内核空间需要使用与编译时版本相近的内核。Avast研究团队即在Centos 6.10虚拟机上使用insmod命令成功加载rootkit,值得注意的是载入后使用lsmod命令无法在已加载的内核模块列表中找到恶意驱动。

2.2 Syslogk rootkit发掘

Syslogk rootkit中存在hide_module函数,该函数通过调用Linux内核API中的list_del函数从内核模块的链表中移除模块。下一步它会针对性地更新内部module_hidden标志位。

好消息是Syslogk rootkit有一处功能点实现了proc_write函数,该函数在/proc文件系统中暴露了一个写文件接口。通过向/proc/syslogk文件写入1可以使Syslogk rootkit被发掘出来。

图3:发掘Syslogk rootkit示例

Syslogk rootkit被发掘出来也就意味着可以使用rmmod命令将其从内存中移除。本文的“相关研究工具”部分会给出更多有助于分析Syslogk rootkit的细节。

2.3 Syslogk rootkit特征概览

除了隐藏自身使其难以检测外,Syslogk rootkit还通过以下措施彻底隐藏了恶意载荷:

  • 使用hk_proc_readdir函数隐藏操作系统上包含恶意文件的目录;

  • 通过hk_getpr函数隐藏恶意进程,这是Adore-Ng项目中隐藏进程函数的混合产物;

  • 使用hk_t4_seq_show函数隐藏网络流量。当端口被打开时不会出现在如netstat监控的系统端口列表中;

  • 恶意代码并非持续运行。攻击者通过向受感染的机器发送特制TCP包来调用Syslogk rootkit,此手法通过安装netfilter钩子监听流量完成;

  • 攻击者也可以远程停止载荷的运行。该行为需要使用rootkit中的硬编码键和用于远程唤醒载荷的magic packets知识。

Avast研究团队观察到当Syslogk rootkit(以及Rekoobe payload)与伪造的SMTP服务器共同使用时其功能可以完美地得到展现。即一个后门程序平常表现人畜无害,当某些特制的magic packets请求到来时,它会变成一个隐藏在内存中、磁盘上、网络中且能远程执行的合法服务,甚至在被网络端口扫描时也只是表现得像一个合法的SMTP服务器。

为了顺利攻击操作系统并放置上述提及的隐藏函数,Syslogk使用已知的rootkit函数set_addr_rw和set_addr_ro,这两个函数可用于在页表项结构中增加或移除写权限。在向页表项中添加写权限后,rootkit能够钩住在hks内部rootkit结构中声明的函数。

页表项钩子

函数类型

偏移量

函数名称

初始函数1

hks+(0x38) * 0

proc_root_readdir

钩子函数1

hks+(0x38) * 0 + 0x10

hk_proc_readdir

初始函数2

hks+(0x38) * 1

tcp4_seq_show

钩子函数2

hks+(0x38) * 1 + 0x10

hk_t4_seq_show

初始函数3

hks+(0x38) * 2

sys_getpriority

钩子函数3

hks+(0x38) * 2 + 0x10

hk_t4_seq_show

放置钩子的手法主要是通过/proc/kallsyms识别可挂钩的内核符号,/proc/kallsyms在rootkit的get_symbol_address函数中被实现。获取符号地址后,Syslogk rootkit使用udis86项目对函数进行挂钩。

2.4 目录隐藏机制分析

虚拟文件系统是一个抽象层,该系统允许用户在非传统文件系统上进行类似FS的操作。由于它是所有文件系统查询的入口点,因此是一个较好的备用rootkit挂钩点。

Syslogk rootkit即通过钩住虚拟文件系统的函数实现隐藏Rekoobe载荷的目的,该载荷存储在/etc/rc-Zobk0jpi/PgSD93ql。

该挂钩点通过hk_root_readdir函数实现,这个函数会调用具有过滤目录功能的nw_root_filldir函数。

图4: 目录隐藏代码的部分反编译结果

函数hk_get_vfs使用内核函数filp_open打开文件系统根目录。以上操作会返回一个指向file结构的指针,该指针包含一个称为f_op的表示文件操作的结构体,其中存储着通过hk_root_readdir函数钩住的readdir函数。

不过这个手法并不是全新的,Adore-Ng的源码即有这样的做法。

2.5 进程隐藏机制分析

在图5右侧控制流中可以看到Syslogk rootkit被用来隐藏一个叫PgSD93ql的进程,因此控制流相较于原版rootkit(图5左侧控制流)更直观。此外,Syslogk还可以更进一步对已授权的进程进行选择性隐藏。

图5: 进程隐藏机制的控制流图

Syslogk rootkit函数hk_getpr是Adore-Ng项目adore_find_task和should_be_hidden两个函数的混合结果,但是它仍然使用相同的机制来隐藏进程。

2.6 网络流量隐藏机制分析

Adore-Ng rootkit允许隐藏指定的监听服务集合,从而逃脱类似Linux程序Netstat的监控。具体实现上是通过Adore-Ng项目中导出的proc_net结构体改变内核tcp4_seq_show句柄的运行逻辑,后者在Netstat请求监听连接时被内核调用。通过结合adore_tcp4_seq_show函数,strnstr函数在seq->buf中查找包含被隐藏端口的十六进制表示子串。如果找到了所需的子串,则该字符串被删除以实现隐藏的目的。

图6: 网络流量隐藏机制的控制流图

通过这种方式可以实现受感染的机器在罗列连接时不显示后门程序。接下来的章节会描述Syslogk rootkit其他有趣的功能。

2.7 magic packets分析

Syslogk rootkit可以通过接收特制网络流量包实现远程启动或者终止,而非持续运行。

由于流量包具有特殊格式和特殊用途,这种手法被称为magic packets。在Syslogk rootkit的实现中,攻击者可以无需感染机器开启监听端口即可触发Syslogk rootkit的相关行为,从而使命令魔术般地运行在系统之中。

2.7.1启动Rekoobe载荷

Syslogk rootkit中启动Rekoobe伪造SMTP服务器的magic packet校验逻辑较简洁:首先校验流量包是否是TCP协议的,如果是则校验源端口是否是59318。

如果magic packet满足上述两个条件Rekoobe伪造SMTP服务器将会启动。

7: 启动Rekoobe payload的条件校验

在启动伪造服务前,Syslogk rootkit会调用rootkit函数pkill_clone_0终止所有rootkit实例。该函数的中止范围包括硬编码进程PgSD93ql和Rekoobe进程,中止方式是调用send_sig发送KILL信号。

为了在用户态执行启动Rekoobe伪造服务的命令,Syslogk rootkit通过结合内核API执行以下命令:call_usermodehelper_setup,call_usermodehelper_setfns和 call_usermodehelper_exec。

本文的“相关研究工具”部分给出如何通过Python特制TCP magic packet启动Rekoobe载荷。下一节将给出magic packet更复杂的形式。

2.7.2 终止Rekoobe载荷

由于攻击者并不希望网络中的其他人停止Rekoobe,用于停止Rekoobe的magic packet需要匹配上先前启动Rekoobe的某些magic packet字段。此外流量包还需满足额外的要求:包含一个在rootkit中硬编码且有动态偏移量的键。终止操作之前会首先检查以下情况:

1. 检查某个标志位是否启用。该标志位会在rootkit通过magic packet启动Rekoobe时被启用。

2. 检查TCP头部的Reserved字段是否是0x08。

3. 源端口必须在63400至63411之间。

4. 目标端口和源地址需要与启动Rekoobe时使用的magic packet对应字段相同。

5. 查询有无硬编码键。在本案例中硬编码键为D9sd87JMaij。

硬编码键的偏移量同样在TCP包头的data offset字段中被设置。该偏移量不是固定的,而是被计算出来的。将值右移4位并乘以4之后,它会指向键预期位置的偏移量(如图8所示,Syslogk rootkit以倒序比对键)。

图8: 终止Rekoobe payload的条件校验

在Avast研究团队的实验中,他们采用0x50作为data offset字段的值。原因是该值经过右移4位和乘4的操作后等于20。20正好是TCP头的大小,这样能够在流量包数据段的起始处设置硬编码键。

如果读者好奇如何实现终止Rekoobe payload的magic packet,可以参考本文的“相关研究工具”部分。

3. Rekoobe分析

当受感染的机器接收到特制的magic packet,Syslogk rootkit将在用户模式空间中启动隐藏的恶意软件Rekoobe。

它看上去像一个无害的SMTP服务器,但是当接收到starttls命令时一个后门命令将会被执行。在合法服务的场景下,starttls命令是由客户端发送给服务端用于请求TLS握手的。

图9: TLS握手请求的建立过程

为了触发Rekoobe后门命令,攻击者需要通过TLS协议发送字节0x03,之后跟着Tag Length Value(TLV)编码数据。其中Tag是符号%,Length由四位数字字符组成以及值(注意length和value不能为0)。

图10: 触发Rekoobe后门命令的攻击模拟

此外如果想建立TLS连接需要使用内嵌在Rekoobe中的证书。

如果有兴趣可以看一下“相关研究工具”部分的证书以及用来与Rekoobe建立连接的Python脚本。

4. Rekoobe与Syslogk溯源

Rekoobe很显然是基于TinyShell开源项目开发的。因为其中一些字符和变量的声明顺序与TinyShell项目中的声明顺序保持高度一致。

图11: Rekoobe与TinyShell的源码比对

另一方面,Syslogk rootkit中也包括对TinyShell的引用,该引用可追溯到2018年12月13日。

图12: Syslogk rootkit中存在TinyShell引用

以上证据表明,威胁实施者同时开发了Rekoobe和Syslogk并使两种工具协同运作。Avast研究团队希望这项研究有助于保护其用户和其他人。

5. 总结

安全软件的架构优势之一通常是具备在不同权限层上运行的组件在较低权限层上运行的恶意软件不能轻易地干扰在较高权限层上运行的进程,因此安全软件能够更直接地处理恶意软件。

另一方面,因为这些恶意软件运行在高权限层导致内核rootkit可能很难检测和清除。系统管理员和安全公司必须意识到这种恶意软件的存在,并尽快为他们的用户制订相应的保护措施。

6. 研究工具库及攻击指标

6.1 Syslogk研究工具

unhide_rootkit.c

https://github.com/avast/ioc/blob/master/SyslogkRootkit/Research Tools/unhide_rootkit.c

magic_packet_start_rekoobe.py:

https://github.com/avast/ioc/blob/master/SyslogkRootkit/Research Tools/magic_packet_start_rekoobe.py

magic_packet_kill_rekoobe.py:

https://github.com/avast/ioc/blob/master/SyslogkRootkit/Research Tools/magic_packet_kill_rekoobe.py

remove_syslogk_from_memory.sh:

https://github.com/avast/ioc/blob/master/SyslogkRootkit/Research Tools/remove_syslogk_from_memory.sh

6.2 Rekoobe研究工具

rekoobe_backdor_client.py

https://github.com/avast/ioc/blob/master/SyslogkRootkit/Research Tools/rekoobe_backdoor_client.py

cert.pem:

https://github.com/avast/ioc/blob/master/SyslogkRootkit/Research Tools/cert.pem

6.3 攻击指标(IoCs)

攻击指标可在Avast研究团队的github项目中获取。

项目地址为:

https://github.com/avast/ioc/tree/master/SyslogkRootkit

参考链接:https://decoded.avast.io/davidalvarez/linux-threat-hunting-syslogk-a-kernel-rootkit-found-under-development-in-the-wild/

编辑|倪锴

审校|何双泽、金矢

监制|姜政伟

本文为CNTIC编译整理,不代表本公众号观点,转载请保留出处与链接。

声明:本文来自国家网络威胁情报共享开放平台,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。