写在前边
7. 显示设备树
我们可以使用volatile中的devicetree插件以与devicetree工具相同的格式显示设备树。以下突出显示的条目显示了与volmgr.sys相关联的HarddiskVolume1的设备堆栈:
$ python vol.py -f win7_x86.vmem
--profile=Win7SP1x86 devicetree
DRV 0x05329db8 DriverWMIxWDM
---| DEV 0x85729a38 WMIAdminDevice FILE_DEVICE_UNKNOWN
---| DEV 0x85729b60 WMIDataDevice FILE_DEVICE_UNKNOWN
[REMOVED]
DRV 0xbf2e0bd8 Drivervolmgr
---| DEV 0x868e7e20 HarddiskVolume1 FILE_DEVICE_DISK
------| ATT 0x868e7b28 - Driverfvevol FILE_DEVICE_DISK ---------| ATT 0x868e78c0 - Driverrdyboost FILE_DEVICE_DISK ------------| ATT 0x85707658 - Drivervolsnap FILE_DEVICE_DISK [REMOVED]
*左右滑动查看更多
|
为了帮助大家理解devicetree插件在司法调查中的使用,让我们来看看一个恶意软件,它创建自己的设备来存储恶意二进制文件。
在下面的ZeroAccess rootkit示例中,笔者使用了cmdline插件,它显示进程命令行参数。这在确定进程的完整路径时很有用(您也可以使用dlllist插件)。从输出中可以看到最后一个svchost.exe进程在可疑的命名空间中运行:
svchost
.exe
pid
: 624
Command
line
:
C
:
Windows
system32
svchost
.exe
-k
DcomLaunch
svchost
.exe
pid
: 712
Command
line
:
C
:
Windows
system32
svchost
.exe
-k
RPCSS
svchost
.exe
pid
: 764
Command
line
:
C
:
Windows
System32
svchost
.exe
-k
LocalServiceNetworkRestricted
svchost
.exe
pid
: 876
Command
line
:
C
:
Windows
System32
svchost
.exe
-k
LocalSystemNetworkRestricted
[REMOVED]
svchost
.exe
pid
: 1096
Command
line
: "\.
globalroot
Device
svchost
.exe
svchost
.exe
"
*左右滑动查看更多
在之前的讨论中,如果你还记得,.<symbolic link name>是从用户模式访问设备的约定的名称。当一个驱动程序为设备创建一个符号链接时,它会被添加到GLOBAL??在对象管理器名称空间中的目录(可以使用WinObj工具查看,正如我们前面讨论的那样)。
在本例中,globalroot是符号链接的名称。那么,问题是,什么是.globalroot? 结果是 .globalroot查询global??命名空间。换句话说,.globalrootDevicesvchost.exesvchost.exe路径与Devicesvchost.exesvchost.exe相同。
在这个阶段,我们知道ZeroAccess rootkit会创建它自己的设备(svchost.exe)来隐藏它的恶意二进制文件svchost.exe。要识别创建该设备的驱动程序,可以使用设备树插件。从下面的输出中,可以看出svchost.exe设备是由00015300创建的。sys司机:
$ python vol.py -f zaccess1.vmem
--profile=Win7SP1x86 devicetree [REMOVED]
DRV 0x1fc84478 Driver0015300
---| DEV 0x84ffbf08 svchost.exe FILE_DEVICE_DISK
*左右滑动查看更多
在下面的BlackEnergy恶意软件的例子中,它取代了合法的aliide。使用恶意驱动程序来劫持现有服务。当服务启动时,恶意驱动程序创建一个设备来与恶意用户模式组件(DLL注入到合法的svchost.exe进程中)通信。以下设备树输出显示了恶意驱动创建的设备:
python vol.py -f be3_big_restart.vmem --profile=Win7SP1x64 devicetree | grep -i aliide -A1
Volatility
Foundation Volatility Framework 2.6
DRV
0x1e45fbe0 Driveraliide
DEV 0xfffffa8008670e40 {C9059FFF-1C49-4445-83E8-4F16387C3800} FILE_DEVICE_UNKNOWN
*左右滑动查看更多
了解恶意驱动程序支持的操作类型,我们可以使用挥发的驱动程序插件,因为它显示了与特定驱动程序或所有驱动程序相关的主要IRP函数。
从下面的输出中,可以看出恶意aliide驱动程序支持IRP_MJ_CREATE(打开)、IRP_MJ_CLOSE(关闭)和IRP_MJ_DEVICE_CONTROL(DeviceIoControl)操作。驱动程序不支持的操作通常在ntoskrnl.exe中指向IopInvalidDeviceRequest,这就是为什么我们在ntoskrnl.exe中看到所有其他不支持的操作指向0xfffff80002a5865c的原因:
python vol.py -f be3_big_restart.vmem --profile=Win7SP1x64 driverirp -r aliide
Volatility
Foundation Volatility Framework 2.6 --------------------------------------------------
DriverName
:
aliide
DriverStart
:
0xfffff88003e1d000
DriverSize
:
0x14000
DriverStartIo
:
0x0
0
IRP_MJ_CREATE
1
IRP_MJ_CREATE_NAMED_PIPE
2
IRP_MJ_CLOSE
3
IRP_MJ_READ
4
IRP_MJ_WRITE
[REMOVED]
12
IRP_MJ_DIRECTORY_CONTROL
13
IRP_MJ_FILE_SYSTEM_CONTROL
14
IRP_MJ_DEVICE_CONTROL
15
IRP_MJ_INTERNAL_DEVICE_CONTROL 0xfffff80002a5865c ntoskrnl.exe [REMOVED]
*左右滑动查看更多
|
8.检测内核空间挂钩
当讨论钩子技术时,在钩子技术一节中,我们看到了一些恶意程序如何修改调用表(IAT钩子)和一些修改API函数(内联钩子)来控制程序的执行路径,并将其重新路由到恶意代码。目标是阻止对API的调用,监视传递给API的输入参数,或过滤从API返回的输出参数。在该章节,代码注入和hook,主要关注用户空间中的hook技术。
如果攻击者设法安装内核驱动程序,在内核空间中也可能有类似的功能。与在用户空间中挂接相比,在内核空间中挂接是一种更强大的方法,因为内核组件在整个系统的操作中扮演着非常重要的角色。它允许攻击者以较高的权限执行代码,使他们能够隐藏恶意组件的存在、绕过安全软件或拦截执行路径。在本节中,我们将了解内核空间中的不同挂钩技术,以及如何使用内存取证来检测这些技术。
8.1 检测SSDT挂钩
内核空间中的系统服务描述符表(SSDT)包含内核执行程序(ntoskrnl.exe、ntkrnlpa.exe等)导出的系统服务例程(内核函数)的指针。当应用程序调用WriteFile()、ReadFile()或CreateProcess()等API时,它会调用ntdll.dll中的存根,它会将线程切换到内核模式。在内核模式下运行的线程会查询SSDT以确定要调用的内核函数的地址。下面的截图用一个WriteFile()的例子说明了这个概念(这个概念和其他api类似):
通常,ntoskrnl.exe导出核心内核API函数,例如NtReadFile()、 NtWrite()File等等。在x86平台中,指向这些内核函数的指针直接存储在SSDT中,而在x64平台上,SSDT不包含指针。
相反,它存储一个经过编码的整数,该整数被解码以确定内核函数的地址。无论实现是什么,概念都是相同的,并且要咨询SSDT来确定特定内核函数的地址。Windows7 x86平台下的WinDbg命令会显示SSDT的内容。
表中的条目包含指向ntoskrnl.exe (nt)实现的函数的指针。条目的顺序和数量因操作系统版本而异:
dps nt!KiServiceTable
82a8f5fc
82c8f06a nt!NtAcceptConnectPort
82a8f600
82ad2739 nt!NtAccessCheck
82a8f604
82c1e065 nt!NtAccessCheckAndAuditAlarm
82a8f608
82a35a1c nt!NtAccessCheckByType
82a8f60c
82c9093d nt!NtAccessCheckByTypeAndAuditAlarm
82a8f610
82b0f7a4 nt!NtAccessCheckByTypeResultList
82a8f614
82d02611 nt!NtAccessCheckByTypeResultListAndAuditAlarm [REMOVED]
*左右滑动查看更多
还有第二个表,类似于SSDT,称为SSDT影子。该表存储了指向win32k.sys导出的gui相关函数的指针。要显示这两个表的条目,可以使用ssdtVolatility插件,如下所示。SSDT[0]为本机SSDT表,SSDT[1]为SSDT影子:
$ python vol.py -f win7_x86.vmem --profile=Win7SP1x86 ssdt Volatility Foundation Volatility Framework
2.6
[
] Gathering all referenced SSDTs
from
KTHREADs... Finding appropriate address space
for
tables...
SSDT[
0
] at
82
a8f5fc with
401
entries
Entry
0x0000
:
0x82c8f06a
(NtAcceptConnectPort) owned
by
ntoskrnl.exe
Entry
0x0001
:
0x82ad2739
(NtAccessCheck) owned
by
ntoskrnl.exe
Entry
0x0002
:
0x82c1e065
(NtAccessCheckAndAuditAlarm) owned
by
ntoskrnl.exe
Entry
0x0003
:
0x82a35a1c
(NtAccessCheckByType) owned
by
ntoskrnl.exe
[
]
SSDT[
1
] at
96
c37000 with
825
entries
Entry
0x1000
:
0x96bc0e6d
(NtGdiAbortDoc) owned
by
win32k.sys
Entry
0x1001
:
0x96bd9497
(NtGdiAbortPath) owned
by
win32k.sys
Entry
0x1002
:
0x96a272c1
(NtGdiAddFontResourceW) owned
by
win32k.sys
Entry
0x1003
:
0x96bcff67
(NtGdiAddRemoteFontToDC) owned
by
win32k.sys
*左右滑动查看更多
要检测SSDT挂钩,可以在SSDT表中查找不指向ntoskrnl.exe或win32k.sys中的地址的条目。以下代码是一个示例:
Mader rootkit,它钩住各种与注册表相关的函数,并将它们指向恶意驱动程序core.sys。在这个阶段,我们可以确定核心的基址。Sys使用模块、modscan或驱动程序,然后使用moddump插件将其转储到磁盘上进行进一步分析:
$ python vol.py -f mader.vmem --profile=WinXPSP3x86 ssdt | egrep -v
"(ntoskrnl|win32k)"
Volatility Foundation Volatility Framework
2.6
[
] Gathering all referenced SSDTs
from
KTHREADs...
Finding appropriate address space
for
tables...
SSDT[
0
] at
80501b
8c with
284
entries
Entry
0x0019
:
0xf66eb74e
(NtClose) owned
by
core.sys
Entry
0x0029
:
0xf66eb604
(NtCreateKey) owned
by
core.sys
Entry
0x003f
:
0xf66eb6a6
(NtDeleteKey) owned
by
core.sys
Entry
0x0041
:
0xf66eb6ce
(NtDeleteValueKey) owned
by
core.sys
Entry
0x0062
:
0xf66eb748
(NtLoadKey) owned
by
core.sys
Entry
0x0077
:
0xf66eb4a7
(NtOpenKey) owned
by
core.sys
Entry
0x00c1
:
0xf66eb6f8
(NtReplaceKey) owned
by
core.sys
Entry
0x00cc
:
0xf66eb720
(NtRestoreKey) owned
by
core.sys
Entry
0x00f7
:
0xf66eb654
(NtSetValueKey) owned
by
core.sys
*左右滑动查看更多
对攻击者使用SSDT挂接的缺点是它很容易被检测到,而且Windows的64位版本由于内核补丁保护(KPP)机制,也被称为PatchGuard,阻止了SSDT挂接。由于SSDT中的条目在不同版本的Windows中有所不同,并且在较新的版本中可能会发生变化,因此恶意软件作者很难编写可靠的rootkit。
PatchGuard:
https:
//en.wikipedia.org/wiki/Kernel_Patch_ Protection
*左右滑动查看更多
8.2 检测IDT挂钩
中断描述符表(IDT)存储了ISR(中断服务例程或中断处理程序)函数的地址。这些函数处理中断和处理器异常。与挂接SSDT一样,攻击者也可以挂接IDT中的条目,将控制权重定向到恶意代码。
要显示IDT条目,你可以使用IDTVolatility插件。一个与IDT挂钩的恶意软件的例子是Uroburos (Turla) rootkit。这个rootkit钩住了位于0xc3 (INT C3)索引的中断处理程序。在一个干净的系统上,0xC3处的中断处理程序指向ntoskrnl.exe内存中的一个地址。以下输出显示了来自clean系统的条目:
python vol.py -f win7.vmem --profile=Win7SP1x86 idt Volatility Foundation Volatility Framework 2.6
CPU
Index Selector Value Module Section
------ ---------- ---------- --------- ------------
0 0
0
1
0
2
0
3
[REMOVED]
0
C1 0x8 0x8282f3f4 hal.dll _PAGELK
0
C2 0x8 0x8288eea4 ntoskrnl.exe .text
0
C3 0x8 0x8288eeae ntoskrnl.exe .text
*左右滑动查看更多
|
下面的输出显示钩住的条目。可以看到IDT中的0xC3条目指向UNKNOWN模块中的一个地址。换句话说,被钩入的条目位于ntoskrnl.exe模块的范围之外:
python vol.py -f turla1.vmem --profile=Win7SP1x86 idt Volatility Foundation Volatility Framework 2.6
CPU
Index Selector Value Module Section
------ ---------- ---------- --------- ------------
0
0
0
1
0
2
0
3
[REMOVED]
0x8
0x82890200 ntoskrnl.exe .text
0x8
0x82890390 ntoskrnl.exe .text
0x58
0x00000000 NOT USED
0x8
0x82890800 ntoskrnl.exe .text
0
C1 0x8 0x8282f3f4 hal.dll _PAGELK
0
C2 0x8 0x8288eea4 ntoskrnl.exe .text
0
C3 0x8 0x85b422b0 UNKNOWN
*左右滑动查看更多
|
关于Uroburos rootkit的详细分析,并了解rootkit用于触发挂钩中断处理程序的技术,请参阅以下博客文章:
https:
/
/www.gdatasoftware.com/blog
/2014/
06
/
23953
-analysis-of-uroburos-using-windbg
*左右滑动查看更多
(未完待续)
原文始发于微信公众号(安恒信息安全服务):九维团队-青队(处置)| 使用内存取证检测高级恶意软件(六)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论