NSA的第七种武器|双脉冲星(DoublePulsar) 后门详细分析

2018-02-28 16:17:30 浏览数 (1)

1. 引言

NSA的一系列SMB 漏洞利用的背后,最后都会使用到双脉冲星(DoublePulsar)后门。双脉冲星后门是一个无文件内核级的SMB后门。

2. 双脉冲星后门的安装过程

双脉冲星后门是通过内核级的shellcode来安装的(在x86 系统上,shellcode一般从地址0xffdff1f1开始)。我们来围观一下这段shellcode.

Shellcode的开始就是很有意思的一段代码:

这段代码咋看有些多余, jz的跳转是永远不会被执行的。事实上,这段代码是用来测试系统是否为64 位系统。

在64 位系统上,上述字节则反汇编为

这样一来, jz 总是会跳转。

这段代码测试CPU是32位还是64位,根据测试结果跳到不同的shellcode代码。

本文以32位系统为例进行分析。

紧接着,进入如下代码:

这段代码又是个什么鬼呢?这段代码的作用是hook SYSENTER, 具体可参见 [1]。下次执行SYSENTER指令的时候,控制会转到ebx 17 的代码,即地址 FFDFF221。

跟进FFDFF221 代码,

这段代码过河拆桥,将上面SYSENTER的Hook摘掉。随后执行

FFDFF39A这个函数正是试图安装双脉冲星后门的函数。这个函数篇幅略长,但目的非常清晰,替换 srv.sys!SrvTracation2DispatchTable 表中 0xe项函数指针 (即表偏移0x38)。替换后的代码即为SMB的后门函数。

在ffdff51e处下断点,就可以非常清楚的观察到:

这里ebx就是srv!SrvTransaction2DispatchTable的地址, ebx 0x38就是0xe项的函数指针。eax为替换后的后门函数地址。

3. 双脉冲星后门功能分析

根据上面的分析,双脉冲星后门被成功的安装到了srv!SrvTransaction2DispatchTable 的0xe项。那么这个后门如何利用呢? 攻击者只需要构造SMB_COM_TRANSACTION2 请求(0x32),并指定Subcommand 为SESSION_SETUP(0xe)这个无效的值,这时,SrvTransaction2DispatchTable的0xe项派遣函数,也就是被替换的后门函数将被调用。SMB 请求报文如下图所示

下面分析一下后门函数的功能。

这个函数可谓整个双脉冲星后门的精华所在,里面使用了一系列令人眼花缭乱的技巧。

函数开始调用了3个不同的函数:

sub_FFDFF930

sub_FFDFF89F

sub_FFDF8E0

下面对这三个函数逐一进行分析

先看第一个函数sub_FFDFF930。

这个函数虽然代码非常简单,但要深入理解却也着实不易,主要是一些用到的数据结构并没有公开,只能靠大量的逆向工作来进行猜测。该函数的参数是传给SrvTransaction2DispatchTable 中Dispatch函数的参数,参数类型没有公开,权且称其为CONTEXT。在经过大量的逆向分析后,结论如下:

CONTEXT的 某个偏移的地方存放着一个指针Ptr (进一步的深入分析发现,这个指针其实是个指向IRP的指针,应该就是SMB请求的IRP),这个指针的值正好是CONTEXT的起始地址 Size。所以只需从CONTEXT的起始地址开始步长为4字节递增搜索,就可以找到这个指针。

如下图所示。

找到这个地址后,就可以在此基础上推算出 SMB响应报文的地址以及SMB请求报文中Parameter存放的地址。

这么看似费了一番周折,但主要目的是为了避免对于不同平台需要对SMB响应和SMB请求报文的Parameter在结构中的偏移进行硬编码。

SMB相应 报文的起始地址存放在ebp 44处,而SMB请求报文的Parameter则存放在ebp 38处。

接下来看第二个函数 sub_FFDFF89F:

这个函数更加简单,用来初始化会话用的密钥运算操作。

最后,看第三个函数,这个函数对SMB 后门请求报文做一些简单的合法性检查,其中又使用了一些技巧来找到内核态的指针,来验证指针的有效性。其次,它对 ParameterCount 和TotalParameterCount值进行检测,二者都必须是0xc。这个函数的存在,体现了这段shellcode在稳定性方面做了一些周全的考虑。

三个函数执行完后,调用了FFDFF88B 这个函数,根据函数的计算结果,会跳到不同的分支。

这个函数伪代码如下:

这个函数就是将dword的四个字节加起来, 结果转化成一个字节。

那么它的输入是什么呢,经调试分析,输入就是SMB请求的 Timeout 字段。

也就是说,后门函数将SMB的Timeout请求字段解码,把解码的结果跟0x23,0x77,0xc8比较作为后门的命令。

当结果为0x23时,后门函数用来检查后门是否已经安装,即PING命令。

当结果为0x77时,后门函数用来进一步执行传入的shellcode。

当结果为0xc8时,后门函数用来卸载后门。

下面看一个具体的例子:

这个请求中Timeout的值为 93 89 07 00: 0x93 0x89 0x07 00= 0x123,取最后一个字节,结果为0x23,根据上面的分析,这是PING命令。

在处理PING 命令时,我们看到,把计算出来的密钥放在了SMB响应报文的Signature中,已备后面发送shellcode时加密使用。

最后一段PING 命令处理代码:

这里会根据不同的状态将响应报文的MID(Multiplex ID) 加上一个值(正常情况下,响应的MID必须和请求中的MID值一致)。MID增量值具体含义见下表:

下图是一个PING命令成功的例子,

请求,

可见,请求中的MID为66(0x0042)

响应:

响应中的MID值为82(0x0052)。两者MID差值为0x0052-0x0042 = 0x10.

在做完这一切后,将控制跳转到原来的派遣函数,以便回复SMB请求。

4. 结束语

本文详细分析了作为NSA第七种武器的双脉冲星后门的代码。该代码构思相当巧妙,隐蔽性很强。作者对Windows 代码, 尤其是SMB部分的代码可谓相当熟悉。整个Shellcode考虑到了通用性,稳定性,犹如做工精良的武器一般。而这样的内核级后门,对入侵者无疑是敞开了一扇大门,几乎可以为所欲为。

5. 参考文献

  1. Rootkits: Subverting the Windows Kernel.(pp94-95)
  2. https://zerosum0x0.blogspot.com.au/2017/04/doublepulsar-initial-smb-backdoor-ring.html
  3. http://blog.checkpoint.com/2017/05/25/brokers-shadows-analyzing-vulnerabilities-attacks-spawned-leaked-nsa-hacking-tools/

0 人点赞