【勒索软件】深入剖析勒索软件传播方式

勒索软件年年有,一年更比一年高。企业在勒索软件防护的道路上是一刻也不能懈怠的。本文分析了近段时间勒索软件的传播功能,详细剖析其从借助漏洞植入后门,驻留维持,到复制传播的实现过程,并给出了对应的防护检测手段。随着勒索软件的不断发展,其在技术上也有了不断创新,危害更大,需要我们全社会不断持续关注并重视。

引言

去年WannaCrypt和Petya的大规模爆发,勒索软件再次重新吸引了大众的关注。早期的勒索软件,无论是CryptoWall、TeslaCrypt还是Locky,多数通过钓鱼邮件、社会工程学等手段诱骗受害者点击,虽也有通过网页挂马的方式执行,但就勒索软件本身个体而言,其不具备主动传播的功能。

而去年爆发的勒索软件同以往最大区别在于开始主动利用漏洞进行传播,通过NSA泄露的永恒之蓝EternalBlue漏洞在用户系统中植入DoublePulsar后门,再通过DoublePulsar复制自身,形成蠕虫式快速传播,在企业内网迅速扩散,加密用户重要文件,给用户信息造成极大损害。

本文主要聚焦于勒索软件的传播功能,将详细剖析其从借助漏洞植入后门,驻留维持,到复制传播的实现过程,并给出对应的防护检测手段。

触发漏洞

WannaCrypt和Petya主要通过永恒之蓝EternalBlue漏洞实现入侵。永恒之蓝漏洞发生在srv.sys模块中的SrvOs2FeaListSizeToNt函数,其在处理SMB_FEA_LIST的长度存在错误,导致后续越界拷贝,覆盖相邻的内核数据结构,从而发生代码执行。

unsigned int __stdcall SrvOs2FeaListSizeToNt(_DWORD *a1)

{

  _DWORD *v1; // eax@1

  char *v2; // edi@1

  char *v3; // esi@1

  int v4; // ebx@3

  unsigned int v6; // [sp+Ch] [bp-4h]@1



  v1 = a1;

  v6 = 0;

  v2 = (char *)a1 + *a1;

  v3 = (char *)(a1 + 1);                       

  if ( (char *)(a1 + 1) < v2 )

  {

    while ( v3 + 4 < v2 )

    {

      v4 = *((_WORD *)v3 + 1) + (unsigned __int8)v3[1];

      if ( &v3[v4 + 5] > v2 )

        break;                              

      if ( RtlSizeTAdd(v6, (v4 + 12) & 0xFFFFFFFC, &v6) < 0 )

        return 0;

      v3 += v4 + 5;

      if ( v3 >= v2 )          

        return v6;

      v1 = a1;

    }

    // 漏洞成因!SMB_FEA_LIST的SizeOfListInBytes值计算错误。

    *(_WORD *)v1 = (_WORD)v3 - (_WORD)v1;   

  }

  return v6;

}

植入后门

漏洞触发后,执行的代码其实是一段内核shellcode,其最终目的是安装DoublePulsar后门。DoublePulsar是美国国家安全局NSA泄露工具中一个危害极大的、无文件型的内核级后门,同时支持SMB和RDP协议。由于其直接在系统内核中运行,不存在对应的文件,所以很难被主机安全防护软件查杀。后续勒索软件正是通过DoublePulsar后门复制自身,形成蠕虫式快速传播。

植入后门的步骤如下:

1) hook sysenter系统调用

之所以在代码一开始就Hook sysenter系统调用,是因为当前运行的中断级别为DISPATCH_LEVEL,在此中断级别上无法使用分页内存的相关函数。此外许多常用的内核函数(如PsLookupProcessByProcessId等),都需在PASSIVE_LEVEL中断级别上运行。

图1 hook 系统调用

因此执行的内核shellcode需要一开始就hook sysenter系统调用,使得后面的代码在进程上下文PASSIVE_LEVEL中断级别中执行(降低中断级别)。

2)寻找内核的基地址,根据其导出表,找到所需函数地址

根据KPCR内核结构中的中断描述符表IDT,取得第一个中断处理函数的地址。由于该地址一定在系统内核模块中,所以反向遍历,寻找PE文件头。

图2 遍历寻找内核模块

然后根据其导出表,分别找到ExAllocatePool、ExFreePool、ZwQuerySystemInformation函数的地址。

图3  寻找内核函数地址

3)定位Srv.sys驱动模块的SrvTransaction2DispatchTable表的地址。

通过调用ZwQuerySystemInformation函数得到所有加载的驱动模块,找到srv.sys的地址。

图4  定位Srv.sys驱动模块

在找到Srv.sys驱动模块后,又根据特征在其“.data”节中找到SrvTransaction2DispatchTable表的地址。

4)替换SrvTransaction2DispatchTable表中的第0x0E项,安装DoublePulsar后门。

SrvTransaction2DispatchTable表是srv.sys驱动模块处理SMB Transaction请求的分发表。

图5  调用SrvTransaction2DispatchTable分发表

通过替换该表中的第0x0E项的函数地址,实现DoublePulsar后门的安装。图6(a),(b)分别为正常的和被替换后的SrvTransaction2DispatchTable表。

图6(a) 正常的SrvTransaction2DispatchTable表

图6(b) 被修改后的SrvTransaction2DispatchTable表

被替换后的第0x0E项函数地址指向内核shellcode自己分配的DoublePulsar后门的处理函数。至此,后门植入完毕,由于其直接在系统内核中运行,不存在对应的文件,因此非常隐蔽,很难被主机安全防护软件查杀。

传播扩散

在向内网其他主机植入DoublePulsar后门之后,勒索软件就可以通过DoublePulsar的RunDLL功能将自身传播到内网的其他机器上,从而在内网中不断扩散。

图7 DoublePulsar后门的主要功能

勒索软件借助DoublePulsar后门传播扩散的主要流程如下:

1)将自身作为资源附加在一个DLL后。通过RunDLL功能,由DoublePulsar负责执行该DLL,而该DLL又将勒索软件从资源节中提取出来释放在主机上运行。

图8  RunDLL产生的网络流量

2)DoublePulsar在接受到RunDLL的命令后,首先根据hash获得一些内核函数地址。

图9  RunDLL所需的内核函数

然后通过内核APC方式将用户态shellcode和DLL注入到用户态指定进程中运行。

图10  内核APC方式注入用户态进程

3)被注入到用户态进程的shellcode负责在内存中直接加载附加在最后的DLL。

图11  用户态shellcode负责加载DLL

4)被加载的DLL从自身的资源节中提取出勒索软件本体,将其释放到受害者主机上执行。

图12  从资源节中提取勒索软件

运行后的勒索软件遍历用户重要文件,通过RSA+AES算法加密,造成用户数据损失。同时不断通过漏洞继续向内网其他传播扩散,形成闭环不断循环,从而快速在内网中传播,形成几何级增长。

检测防护

1) 企业网络管理员可使用绿盟入侵防御系统NIPS,对网络中的攻击报文和Doublepulsar后门连接报文进行阻断,防范勒索软件进一步扩散,如下图:

图13  绿盟NIPS防护勒索软件

2)个人用户及时更新Windows安全补丁,重点检查MS17-010补丁安装情况。及时更新终端安全防护软件。定期备份重要文件。养成良好的网络安全意识,避免打开未知邮件中的链接或附件,谨慎从网络下载各类可执行程序。

总结

本文主要分析了近期勒索软件的传播功能,详细剖析其从借助漏洞植入后门,驻留维持,到复制传播的实现过程,并给出了对应的防护检测手段。随着勒索软件的不断发展,其在技术上也有了不断创新,危害更大,需要我们全社会不断持续关注并重视。

 

Spread the word. Share this post!

Meet The Author

Leave Comment