【技术分享】NSA武器库:DoublePulsar初始SMB后门shellcode分析

阅读量291549

|

发布时间 : 2017-05-17 15:42:40

x
译文声明

本文是翻译文章,文章来源:zerosum0x0.blogspot.com

原文地址:https://zerosum0x0.blogspot.com/2017/04/doublepulsar-initial-smb-backdoor-ring.html

译文仅供参考,具体内容表达以及含义原文为准。

http://p7.qhimg.com/t0140d3569451a770ee.png

翻译:myswsun

预估稿费:190RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

传送门


【漏洞分析】NSA Eternalromance (永恒浪漫) 漏洞分析

【漏洞分析】MS 17-010:NSA Eternalblue SMB 漏洞分析

0x00 前言

大约在一个月前,Shadow Brokers(影子经纪人)泄露了方程式组织(为NSA效力的黑客组织)的软件FuzzBunch,一个类似于Metasploit的利用框架。这个框架中有几个针对Windows的未认证的远程利用(如EternalBlue, EternalRomance和 EternalSynergy)。很多利用的漏洞在MS17-010中被修复了,它可能是近十年来最关键的Windows补丁。 

提示:你能使用我的MS17-010 Metasploit auxiliary module来扫描你网络中没有打补丁的系统。如果没有安装补丁,还会检查是否感染DoublePulsar。


0x01 介绍

DoublePulsar是FuzzBunch中SMB和RDP利用中使用的主要的payload。下面分析是在Windows Server 2008 R2 SP1 x64上使用EternalBlue SMBv1/SMBv2 exploit完成的。

Shellcode基本上执行了下面几个步骤:

步骤0:判断x86还是x64。

步骤1:KPCR中定位IDT,从第一个中断处理反向遍历找到ntoskrnl.exe的基址(DOS MZ头)。

步骤2:读取ntoskrnl.exe的导出目录,并使用哈希(和应用层shellcode类似)来找到ExAllocatePool/ExFreePool/ZwQuerySystemInformation函数地址。

步骤3:使用枚举值SystemQueryModuleInformation调用ZwQuerySystemInformation,得到一个加载驱动的列表。通过这个定位到Srv.sys,一个SMB驱动。

步骤4:将位于SrvTransaction2DispatchTable[14]的SrvTransactionNotImplemented()函数指针指向自己的hook函数。

步骤5:使用辅助的DoublePulsar payload(如注入dll),hook函数检查是否正确运行并分配一个可执行的缓冲区来运行原始的shellcode。所有的其他请求直接转发给原始的SrvTransactionNotImplemented()函数。"Burning" DoublePulsar不会完全擦除内存中hook函数,只是休眠它。

在利用后,你能看到缺少SrvTransaction2DispatchTable符号。在这里应该有两个处理程序与SrvTransactionNotImplemented符号。这是DoublePulsar后门(数组索引14):

http://p9.qhimg.com/t0156b5e36a2e8fe6eb.png

我真的很好奇这个payload,在Countercept的DLL注入代码分析之外没有看到很多它的细节。但是我很好奇初始SMB后门是如何安装的,这也是本文的内容。

使用IA32_LSTAR系统调用MSR(0xc000082)和包含FEFE的Srv.sys的区域的EternalBlue利用中有一些有趣的设置,但是我将专注于原始的DoublePulsar的方法…很像EXTRABACON shellcode,这个非常狡猾并不只是产生一个shell。


0x02 shellcode详细分析

在shadow brokers的转储中你能找到DoublePulsar.exe和EternalBlue.exe。当你使用FuzzBunch中的DoublePulsar,有个选项是将它的shellcode输出到一个文件中。我们还发现EternalBlue.exe包含了它自己的payload。

步骤0:判断CPU架构

主payload非常大,因为它包含x86和x64的shellcode。前面一些字节使用操作码技巧来决定正确的架构(参考我之前的文章汇编架构检测)。

下面是x86头几个字节。

http://p8.qhimg.com/t014b5a90146696eaa9.png

你该注意到inc eax意思是je指令不执行。接着是一个call和pop,获取正确的指令指针。

下面是x64的:

http://p4.qhimg.com/t01469a95b715625800.png

其中inc eax由rex替换。因此zf标志寄存器由xor eax,eax操作设置。因为x64有RIP相对寻址,不需要获取RIP寄存器。

X86的payload和x64的基本一样,所以这里只关注x64。

由于NOP在x64中一个真正的NOP,我使用16进制编辑器用CC CC(int 3)覆写40 90。中断3是调试器的软件断点。

http://p9.qhimg.com/t010a1d09443b8dc510.png

现在执行利用,我们附加的内核调试器将自动断点在shellcode开始执行处。

步骤1:找到ntoskrnl.exe的基址

一旦shellcode判断是在x64上面运行,它将开始搜索ntoskrnl.exe的基地址。代码片段如下:

http://p1.qhimg.com/t01197a0adc36415017.png

相当简单的代码。在用户模式下,x64的GS段包含线程信息块TIB),其保存了进程环境块(PEB),该结构包含了当前运行进程的各种信息。在内核模式中,这个段寄存器包含内核进程控制区(KPCR),其中偏移0处包含当前进程的PEB。

该代码获取KPCR的偏移0x38处,是IdtBase并包含一个KIDTENTRY64结构的指针。在x86中很熟悉,能知道这是中断描述符表

在KIDTENTRY64的偏移4,你能得到中断处理的函数指针,其代码定义在ntoskrnl.exe中。从那里按页大小(0x1000)增长反向搜索内存中.exe的DOS MZ头(cmp bx,0x5a4d)。

步骤2:定位必要的函数指针

一旦你知道了PE文件的MZ头的位置,你能定位到导出目录,并得到你想要的函数的相对虚拟地址。用户层的shellcode一直能做到这个,通常是找到ntdll.dll和kernel32.dll的一些必要的函数。只需要和用户层shellcode一样,ring0 shellcode也使用哈希算法代替硬编码字符串,以便找到必要的函数。

下面是要找的函数:

ZwQuerySystemInformation

ExAllocatePool

ExFreePool

ExAllocatePool能用来创建可执行内存区域,并且ExFreePool能用来清理内存区域。这些是重要的,因此shellcode能为它的hook函数和其他函数分配空间。ZwQuerySystemInformation在下一步中是重要的。

步骤3:定位SMB驱动Srv.sys 

使用SystemQueryModuleInformation(0xb)调用ZwQuerySystemInformation能实现。得到所有加载的驱动的列表。

http://p3.qhimg.com/t01dd804c3ed58f2da5.png

Shellcode在这个列表中搜索两个不同的哈希,定位到Srv.sys,这是SMB运行的主要驱动。

http://p8.qhimg.com/t01b8620386347a0cc2.png

过程和用户层一样,通过PEB->Ldr得到,遍历搜索加载的DLL。这里要查找的是SMB驱动。

步骤4:Patch SMB的trans2派遣表

现在DoublePulsar已经有了主要的SMB驱动,它遍历.sys的PE节,直到找到.data节。

http://p1.qhimg.com/t016e5ed34e8b079be6.png

.data节中通常是全局读写内存,在这里存储着SrvTransaction2DispatchTable,一个处理不同的SMB任务的函数指针数组。

Shellcode分配一些内存并实现函数hook。

http://p1.qhimg.com/t01cfa683edd97692ba.png

接下来shellcode存储派遣函数SrvTransactionNotImplemented()的函数指针(以便能在hook函数中调用)。然后使用hook覆盖SrvTransaction2DispatchTable中的这个成员。

http://p7.qhimg.com/t018f21722c4d8a6722.png

后门完成了。现在它返回到它自己的调用栈,并做一些小的清理操作。

步骤5:发送“Knock”和原始的shellcode

当DoublePulsar发送了指定的“knock”请求(被视为不可靠的SMB调用),派遣表调用hook的假的SrvTransactionNotImpletemented()函数。能观察到奇怪的行为:正常的SMB响应MultiplexID必须匹配SMB请求的MultiplexID,但是增加了delta作为一个状态码。

操作能够隐身,在Wireshark中没有合适的解析。

http://p0.qhimg.com/t015c4f52c1ef6fe675.png

状态码(通过MultiplexID delta):

0x10 = 成功

0x20 = 不可靠的参数

0x30 = 分配失败

操作列表:

0x23 = ping

0xc8 = exec

0x77 = kill

你能使用下面的算法得到操作码:

http://p2.qhimg.com/t017dad9a2061368141.png

反之,你能使用这个算法制作包,其中k是随机生成的:

http://p2.qhimg.com/t01895001c16c06a50d.png

在一个Trans2 SESSION_SETUP请求中发送一个ping操作将得到一个响应,其中包含需要为exec请求计算的XOR密钥的一部分。

“XOR密钥”的算法是:

http://p4.qhimg.com/t0109e5bba1fcd17691.png

更多的shellcode能使用Trans2 SESSION_SETUP请求和exec操作发送。使用XOR密钥作为基本流密码,一次性在数据包4096字节的“数据payload”部分中发送。后门将分配一块可执行内存区域,解密复制shellcode并运行。注入dll的payload能注入你想要的DLL。

我们能看见hook被安装在SrvTransaction2DispatchTable+0x70 (112/8 = index 14)处:

http://p1.qhimg.com/t010999c70824909b01.png

全部的汇编在这里


0x03 总结

这是一个复杂的多平台的SMB后门。它是一个非常酷的payload,因为你能感染一个系统,驻留,并能在你想要的时候做更多的事。它在系统中找到了一个很好的隐藏位置,并且不会触PatchGuard

通常我们只能在本地漏洞利用看到内核shellcode,因为它会变换进程令牌以便提权。然而,微软在内核中做了很多网络相关的事,例如Srv.sys和HTTP.sys。所描述的技术在很多方式完全符合远程利用中用户模式的shellcode的操作方式。

当它移植到Metasploit中,我可能不会逐字节复制,而是跳过后门的想法。它不是最安全的,因为它不再是秘密,任何人都可以使用你的后门。

下面是可以代替做的事:

1. 和DoublePulsar相同的方式获得ntoskrnl.exe地址,并读取导出目录获得必要的函数。

2. 启动一个隐藏的进程(如notepad.exe)

3. 使用Meterpreter payload插入APC

4. 恢复进程,退出内核

5. ???

6. 收获


传送门


【漏洞分析】NSA Eternalromance (永恒浪漫) 漏洞分析

【漏洞分析】MS 17-010:NSA Eternalblue SMB 漏洞分析


本文翻译自zerosum0x0.blogspot.com 原文链接。如若转载请注明出处。
分享到:微信
+10赞
收藏
root
分享到:微信

发表评论

内容需知
  • 投稿须知
  • 转载须知
  • 官网QQ群8:819797106
  • 官网QQ群3:830462644(已满)
  • 官网QQ群2:814450983(已满)
  • 官网QQ群1:702511263(已满)
合作单位
  • 安全客
  • 安全客
Copyright © 北京奇虎科技有限公司 360网络攻防实验室 安全客 All Rights Reserved 京ICP备08010314号-66