欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

NSA武器库:DoublePulsar初始SMB后门shellcode分析

来源:本站整理 作者:佚名 时间:2017-05-17 TAG: 我要投稿

大约在一个月前,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):

我真的很好奇这个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头几个字节。

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

其中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是调试器的软件断点。

现在执行利用,我们附加的内核调试器将自动断点在shellcode开始执行处。
步骤1:找到ntoskrnl.exe的基址
一旦shellcode判断是在x64上面运行,它将开始搜索ntoskrnl.exe的基地址。代码片段如下:

相当简单的代码。在用户模式下,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能实现。得到所有加载的驱动的列表。

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载