首页
社区
课程
招聘
[翻译]Windows内核ShellCode的动态加载和调试
发表于: 2017-6-26 19:39 8284

[翻译]Windows内核ShellCode的动态加载和调试

2017-6-26 19:39
8284

在本篇文章中,我将分享一个可以从文件中加载一段shellcode到内核空间并且建立内核线程运行它的windbg脚本。由于我玩过的脚本并不是很多,所以如果有一些bug请告知我。

你可以从我的github上找到这段脚本:

load_code_to_kernel_memory.wdbg

脚本的运行参数:

$$>a<load_code_to_kernel_memory.wdbg <src code> <mem size> <offset start routine>

第一个参数是含有shellcode的文件的路径。第二个参数是申请的内存大小(足够分配shellcode即可)。第三个参数是被执行的shellcode的起始偏移。

注意:包含shellcode的文件的大小应该被填充至内存分页的大小。我们是使用.readmem命令来加载shellcode,该命令将会读取一个0x1000字节大小的区块。举个例子,若你的shellcode有0x2800字节,那么.readmem将只会加载0x2000字节。所以你需要使用0x800附加的垃圾数据来补全文件以便加载完整的代码。

我们需要劫持一个正在运行的线程一小会。将该线程的执行重定向到ExAllocatePool来为shellcode申请内存(同时需要操作被劫持线程的栈来完成这个过程,之后再来恢复)

为此,我们需要在NtCreateFile中设置一个断点(非常频繁使用的一个API)。当线程停在该断点上的时候,就可以进行操作了:

一旦建立线程之后,修改EIP以及栈信息来执行ExAllocatePool

此时,我们已经为shellcode分配了足够的内存空间,加载它吧:

现在,我们希望在shellcode + arg3处创建一个线程:

最后,我们恢复堆栈和eip以在NtCreateFile正确地继续执行被劫持的线程,否则系统将崩溃:

在此之后,windbg应该在线程启动的shellcode的偏移处的断点处停止。

我们将使用从一个worm/ransom 恶意软件 i don’t want to remember的中提取的DoublePulsar Shellcode来测试脚本。

你可以在此处下载shellcode here (rar password: infected).

文件的大小是0x3000。我并没有深入的逆向shellcode,但开始调试的好起点看起来应该是0x221偏移处(稍后我们将会知道why)。

执行脚本,下变是打印的调试跟踪:

可以看见新线程停在了我们指定的位置:

在0x20B偏移处可以看见shellcode hook了SYSENTER_EIP。

shellcode使用了地址0xFFDFFFFC来存储 MSR[0x176]。可以执行下边的命令:

Nt!_kuser_shared_data结构位于0xFFDF0000处,所以我猜测shellcode是使用了和nt!_kuser_shared_data的结构之后的位于同页的内存空间来存储其需要的临时变量。

关于通过MSR来HOOK系统调用可以参考下边这篇文章(非常有趣哦):

http://resources.infosecinstitute.com/hooking-system-calls-msrs

所以,0x221偏移是HOOK SYSENTER_EIP,因此,我认为这里是一个好的调试点。

然我们继续逆向 SYSENTER_EIP HOOK的代码:

在内核领空中,FS:[0]指向_KPCR结构。在这里,可以看见shellcode是如何从_KPCR中获取一些它所需要的值以及其他的结构体指针的过程。

fs:0x40 -> _KTSS

_KTSS + 4 -> Esp0  (correct Esp for continue executing in kernel)

nt!kuser_shared_data+0x304 -> SystemCallReturn


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 7012
活跃值: (4222)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2017-6-26 20:14
0
游客
登录 | 注册 方可回帖
返回
//