翻译:myswsun
预估稿费:200RMB(不服你也来投稿啊!)
投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿
0x00 前言
在之前的报告中我已经描述了rootkits是由号称国家发起的用来感染他们的目标的,是用来保持恶意程序潜伏和获取SYSTEM权限的。我曾经提到过Remsec(Cremes)被Strider(ProjectSauron)组织使用、Sedint(Fancy Bear)是被APT28组织使用。Remsec是被用来在内核执行代码绕过SMEP,Sedint是用来隐藏他们的恶意行为和指纹。
最近一个安全公司调查了多个组织的活动,和我分享了rootkits。在分析时我很惊讶,因为rootkit和它的dropper一样有很好的阻止分析的功能。分析这些rootkits花了很多时间,因为它具有多种反分析能力。Rootkit和dropper的文件大小会变大,因为用了代码混淆和花指令。
“目标”的概念总是作为复杂攻击的属性在安全社区被讨论,经常有些国家发起的活动。在过去我们看见很多活动用了特有的可执行文件,这些文件有特定的目标。本文中讨论的恶意程序满足这些特点。这个恶意程序的组织曾被Microsoft MMPC和Security Intelligence报告过。这个组织被称为“NEODYMIUM”,这个恶意程序被称为“Wingbird”。它和之前赛门铁克发现的Finfisher有点相似。
0x01 Dropper1
第一个dropper有以下特点:
有多种反静态和动态分析的手段。包含多种对抗反汇编/调试/虚拟机/转储的特点。
包含跳转到指令中间的混淆代码,花指令,无用的检测,无用的跳转等
由于大量的花指令,dropper大小比较大(1.3MB)
被设计成尽量延迟分析
在系统中安装rootkit
释放的rootkit的名字是logonsrv.dat
只为了释放rootkit
.text节的熵值很高,说明代码被加密和混淆。
Dropper和rootkit的PE头中的时间戳看起来都是合法的。
在dropper中典型的结尾。
所有函数跳转同一代码。
包含无用跳转的混淆代码。
下面是ring0 rootkit的特点。
混淆代码,加大静态和动态分析的难度
包含加密代码和数据
没有创建设备对象,不与应用层通信
在内核中不做任何挂钩
只为了隐藏注入恶意代码到受信任的Winlogon进程
自我修改代码,例如,能用另一个地址或寄存器修改重要的call或jmp指令
设计的尽量隐蔽,在注入Winlogon之后就卸载驱动
检测ESET的驱动(ehdrv.sys),移除挂钩的SSDT
在执行主要功能前,准备了一些工作。
分配两个非分页内存块。一个大小是0x56000,另一个是0x10000.
第一个buffer用来存储新创建的驱动(在内存中),第二个用来存储一些NT内核API的跳板函数
创建0x2F个IAT项,用来存储新创建的驱动的节信息。但是不直接用这个IAT,而是利用这些地址,用它来修改指令和变量
值得注意的是作者做了尽量多的事情来使内存中的rootkit更加复杂。有经验的人用过ARK工具检测也会遇到麻烦。
不用原始的映像(logonsrv.dat)来做主要的事情
不依赖内存连续的IAT
在两个分配的内存块中做主要的事情。一个块用来作为一些NT内核API的跳板函数
在做主要工作前调用KeDelayExecution函数,例如在注入Winlogon之前
下面可以看到第二个分配内存中的代码,包含了一些跳板函数。另一份来自第一个buffer中的代码用来自IAT的地址重写这些跳板函数。
在预备工作最后,rootkit调用ZwOpenKey打开它的注册表键,用ZwQueryValueKey读取ImagePath值。两个调用指令如下:
在调用ZwQueryValueKey之后,代码在次被修改成调用PsCreateSystemThread。
用PsCreateSystemThread创建了两个线程,一个线程用来做主要的恶意的工作。下图中你能看到执行流程。它准备要注入到Winlogon的代码,读取KnownDllsntdll.dll。rootkit也导入KeServiceDescriptorTable变量,获取KiServiceTable地址,恢复ssdt。
似乎只有一个函数没有被混淆。这个函数用来枚举内核模块。这块代码被调用多次,用来获取NT基地址。在上面能看到,作者对NT内核文件感兴趣,因为要恢复SSDT函数。
注意到作者在rootkit用了和dropper一样的混淆。我们在rootkit中发现一些函数的重建。
如上图所见,所有函数都经过花指令混淆,指向同一代码。
有趣的是在dropper和rootkit的启动代码中是没有混淆的。考虑到上述信息和这个事实,似乎是源代码级别的混淆代码的工具。
Rootkit在Winlogon进程中分配了3块内存。大小分别是0x100000,0x3000和0x48000。下面是rootkit用到的Ntoskrnl的函数。
0x02 Dropper2
有以下特点:
和dropper1一样,用了很多反静态和动态分析的方法
有相同的大小1.3MB
释放的rootkit的名字是ndisclient.dat
一些行为如下。
驱动的一些特征:
被设计成与用户通信,设备是DevicePhysicalDrive00,符号链接名为DosDevicePhysicalDrive00。
驱动比第一个dropper的小(43KB和372KB)
注册了3个IRP派遣函数(IRP_MJ_CREATE,IRP_MJ_CLOSE,IRP_MJ_DEVICE_CONTROL)
检测驱动Driverdiskpt(Shadow Defender)和DriverDfDiskLow的驱动DfDiskLow.sys(Deep Freeze Faronics Corp)是否存在
包含用ZwOpenDirectory和ObQueryNameString枚举对象命名空间的代码
包含混淆,自修改代码,加大分析的难度
用来绕过文件系统型沙箱,能在磁盘级别直接操作文件
在DriverEntry中分配内存块,同样是用来放NT内核API的跳板函数。
下面看到的是在DriverEntry中的主要步骤:
IRP_MJ_DEVICE_CONTROL派遣函数中的部分代码如下:
在DriverEntry通过端口驱动(atapi)获取硬盘设备对象的指针。这个信息用来在IRP_MJ_DEVICE_CONTROL的派遣函数中发送同步请求给端口驱动:
MmMapLockedPagesSpecifyCache,IoAllocateMdl处理非分页内存和直接I/O操作
IoBuildSynchronousFsdRequest,IofCallDriver创建一个相应的IRP请求,并发送
MmUnmapLockedPages,IoFreeMdl释放资源
下面能偶看到两个驱动的区别:
0x05 总结
这个恶意程序的作者做了很多努力来防止静态和动态分析。第一个rootkit只用来注入恶意代码到Winlogon系统进程中。它检测ESET的帮助驱动,因为它能阻止rootkit 的恶意行为,攻击者需要确保在安全产品的环境下也能存活。正如你看到的分析,代码高度混淆。只显示rootkit映像的代码是无用的,因为不能帮助重建执行的逻辑关系。恶意程序的作者用了特殊的指令来做混淆。不过不清楚攻击这为什么不关心rootkit的潜伏和为什么不保护自己的注册表键。
两个rootkit的目的只有一个:第一个用来将代码注入Winlogon进程,第二个在底层和硬盘通信。第二个rootkit不关心持久性:一旦rootkit被加载进内存就把rootkit文件删掉。检测安全软件的存在是共同的特点。例如第一个驱动检测AV驱动的存在与否。第二个驱动关心一个系统工具。
安全产品和系统工具能够阻止潜在的恶意威胁。这个就是为什么攻击者需要底层访问磁盘的权限,他们需要绕过文件沙箱和直接修改文件。

评论