EN
lanyun
technologies
银河实验室 深谙安全之道,热衷技术创新
LABORATORIES 银河实验室

检测

兰眼下一代威胁检测系统告警截图。

图片

概述

HANCITOR是一款成熟的商业化恶意软件下载器,此样本以Word文档为载体,该文档中包含恶意宏代码,恶意宏代码执行后会在主机上释放最终的DLL文件(HANCITOR),该DLL文件的功能包括为每个受害者生成唯一GUID,以及根据相关指令,从指定URL中下载后续的恶意样本以及shellcode并执行。

分析

1、基本流程

图片

2、关键行为

2.1 0929_966655534820.doc

图片

打开文档后,office会出现关于宏的安全警告,证明此文档中包含了宏代码。

图片

通过oleid查看该文档的一些基本信息,并确定了存在宏指令。

图片

通过olevba快速查看其中的宏指令及关键信息。

图片

发现了存在类型AutoExec其中包含Document_open函数,如果受害者按“启用内容”按钮,则会自动执行该函数以及其他的一些可疑函数,我们接下来对宏指令(从Document_Open开始)进行进一步分析。

图片

可以看到大多数变量声明和函数调用只使用了简单的混淆技术,将一个分解字符串分解为多个部分使其隐藏。将第一个if语句的内容进行还原。其中kytrewwf是用户模板文件的路径,拼接后可以看出是在判断文件zoro.doc是否存在。若不存在则会调用bvxfcsd函数。

图片

图片

我们看到其利用Selection属性执行方法进行了一系列操作。光标文档的开头,连续做了两次向下三行,向右两个字符的操作,后删除了一个字符。此操作本是无害的,但它是一种有效的方法,可以将VBA对象载入到文件系统中。如果我们根据上述步骤移动光标,会看到光标停止在一个不可见的插件上。

图片

当触发Selection.Copy时,攻击者将需要的对象存储到Temp文件夹下,以便在需要时调用,我们可以看到这个对象所在的具体位置

图片

在载入文件后会将Temp文件夹的路径作为参数传递给hdhdd函数。而函数功能只是将Temp文件夹的路径传递给Search函数

图片

Search函数中第一个循环TEMP路径中的所有子文件夹进行查找,判断是否存在zoro.kl的对象,如果找到此对象,将函数的第二个参数设置为此文件对象随后删除此对象,并将此对象的路径赋值给全局变量nccx(见hdhhd函数中对Search的调用)。

图片

接下来回到Document_open中,去执行nam。

图片

可以发现nam也被轻微混淆了,我们对其做一些处理,经处理后可以看到这个函数将zoro.kl重新命名,并将其存到用户模板文件夹下,接下来将zoro.doc的完整路径作为参数,传到pppx中

图片

此函数将使用密码“doyouknowthatthegodsofdeathonlyeatapples?”来打开zoro.doc来执行宏指令,进行下一步操作。

图片

2.2 zoro.doc

图片

接下来分析zoro.doc,通过oleid查看其基本信息,发现其确实被加密了。

图片

通过olevba查看其中宏指令,需要用到之前得到的密码doyouknowthatthegodsofdeathonlyeatapples?

图片我们还是从Document_Open入手开始分析。此文件中的宏代码未被混淆,采用了和第一个样本中相同的手法,先判断gelforr.dap在用户模板文件夹中是否存在,不存在会调用bvxfcsd函数。

图片

发现和第一个样本的操作基本没有差别,也是借用Temp目录作为中转站,我们不再进行赘述。

图片

在用户模板文件夹中创建gelforr.dap后回到Document_Open中,执行。

图片

可以知道将要利用rundll32.exe去执行gelforr.dap(dll)中的BNJAFSRSQIX函数。

图片即:

图片

可以看到gelforr.dap的基本信息如下。

图片

2.3 gelforr.dap

图片通过x32对其进行调试,发现其中存在PE文件。

图片

2.4 final.mem

图片我们将其dump下来并进行分析,可以得到如下函数。

图片

通过x32得到了功能函数的名称为BNJAFSRSQIX。

图片

Ghidra解析到了下面两个函数。

图片

可以通过此函数分析后续流程,首先不断跟进如下函数。

图片

首先,恶意样本会为每一个受害者创建一个GUID。其通过调用GetAdaptersAddress来检索受害者的网络适配器相关联的地址,并将获取到的结果与MAC地址进行XOR操作,随后调用函数GetVolumeInformationA来检索受害者的音量序列号,并再次进行XOR异或操作,最终得到受害者的GUID。

图片

随后恶意样本通过调用GetComputerNameA函数获取受害者的计算机名称,并在FUN_10002df0中获取explorer.exe的进程ID,并通过调用函数GetTokenInformation以及LookupAccountSidA来获取当前的受害者主机当前的账户名和域名信息。

图片

且恶意样本通过调用lstrcpyA函数将获取到的受害者信息拼接为如下格式:<Computer name> @ <Domain name> \ <Account name>

随后,恶意样本通过向“http://api.ipify.org”发送一个GET请求数据包来获取受害者的IP地址信息,若恶意样本无法成功访问此网站,就会将受害者的IP地址信息记为0.0.0.0。在FUN_10001fe0中,恶意样本调用函数InternetConnectA对目标服务器进行连接,随后调用函数HttpOpenRequestA来创建GET请求,再调用HttpSendRequestA将创建的GET请求发送给目标服务器,最后通过调用函数InternetReadFile来检索服务器响应信息。在后续过程中,该函数还被用于连接攻击者C2服务器下载恶意软件以及shellcode。

图片

恶意样本调用了函数DsEnumerateDomainTrustsA来获取受害者的NETBIOS信息以及DNS域名信息。

图片

通过调用函数GetSystemInfo来判断受害者主机操作系统是32位还是64位。

图片

恶意样本呢进行了解密操作,其中FUN_10002cd0中调用了解密相关API。

图片

将获取到的受害者信息进行汇总,并按照如下格式进行拼接。

图片

GUID=<Victim’s GUID>&BUILD=<Build ID>&INFO=<Machine Information>&EXT=<Network domain names>&IP=<Victim’s IP address>&TYPE=1&WIN=<Windows major version>.<Windows minor version>(x64)

 

GUID=<Victim’s GUID>&BUILD=<Build ID>&INFO=<Machine Information>&EXT=<Network domain names>&IP=<Victim’s IP address>&TYPE=1&WIN=<Windows major version>.<Windows minor version>(x32)

 

随后,函数FUN_10002660中,又调用了函数FUN_100025b0来对相关配置进行解密,根据动调发现为攻击者的C2服务器URL列表,每个URL之间用“|”分隔开来,以方便区分。

图片

跟进函数FUN_100028d0,发现其整体和上文中提及的获取受害者IP地址所用的手法基本一致,只是将其中的GET请求更换为了POST请求,目标地址更换为攻击者的C2服务器URL地址,其目的便是获取恶意软件以及shellcode。

图片

在相关样本网站获取到了样本通讯的流量包,并在其中发现了受害者主机的相关信息,以及攻击者C2服务器返回请求包信息。

图片

根据格式初步判断,响应包中的信息为Base64编码,对其进行解码。但发现解码出来为乱码,继续回到样本之中,发现恶意样本判断了响应包的前四个字符是否都是大写字符,如果不是则退出程序,反之则继续运行。

图片

再跟进函数FUN_10001000,在其中发现了DAT_10007058,更加印证了其是Base64编码,且发现其舍弃了响应包中的前4位后,再进行Base64解码,并将解码后的字符与0x7a异或得到最终的明文。

图片

写个脚本将响应包解码,得到的内容如下。

图片

图片

回到样本,其通过“{”和“}”来划分每一段指令信息。

图片

其中“n”,“c”,“d”,“r”,“l”,“e”,“b”,为样本中可利用的指令参数,根据不同的参数进行不同的后续操作,并且每条指令中的命令和参数值,用“:”进行分割。

图片

当命令参数为“b”时,恶意样本将从指定的URL中下载指定文件,并通过注入的方式将下载的恶意样本进行启动。若存在多个URL,函数Partition_10002880中,通过识别“|”字符,来将这些URL分隔开来;利用函数download_10001fe0下载指定URL中的样本;随后调用函数decrypt_10001d40对下载的文件进行解密以及解压操作,其将下载到的内容的前八个字节进行XOR异或操作,得到解压密码,随后调用RtlDecompressBuffer函数利用解密得到的密码,解压出对应的可执行文件。

图片

随后恶意样本将下载并完成解压的可执行文件,注入到svchost.exe进程中。其首先使用CreateProcessA创建新的进程,随后恶意样本调用VirtualAllocEx函数在被注入进程中分配相应的缓冲区,为后续payload载入做准备,随后调用HeapAlloc函数为恶意程序分配堆区,并将可执行文件载入其中,随后通过WriteProcessMemory将payload从堆区写入svchost的内存中,最后通过调用ResumeThread来启动注入后的线程。

图片

图片

 

当命令参数为“e时,恶意样本将从指定的URL中下载指定文件,并通过注入的方式将下载的恶意样本进行启动,这次注入的目标是自身进程。下载方式和上一条指令用的方式一摸一样,此处不再进行过多的赘述。在获得后续样本后,其调用VirtualAlloc在自己的内存中分配缓冲区,并将可执行文件载入其中。

图片

恶意样本通过导入表,以及函数GetModuleHandleA和LoadLibraryA 获取导入表中已存在的每个DLL的基址。对于每一个已经导入的DLL,其通过IAT表检索每一个DLL中的函数,随后调用函数GetProcAddress来获取每个函数的地址,并将其写入IAT表中。

图片

最恶意样本通过调用函数CreateThread创建新线程来完成启动操作。

图片

当命令参数为“l时,恶意样本将从指定的URL中下载shellcode,并通过注入的方式将下载的恶意样本进行启动,这次注入的目标是svchost或自身。其下载shellcode的方式与之前无异,此处不再进行过多赘述。注入自身或注入svchost进程去执行shellcode的方式与之前的操作也基本一致,具体请看前两条指令。

图片

当命令参数为“l”时,恶意样本将从指定的URL中下载文件到TEMP文件夹中,并启动。下载方式与之前指令一样,不再进行过多赘述。恶意样本通过调用 GetTempPathA来获取TEMP文件夹路径,并调用函数GetTempFileNameA在获取的路径下创建一个名为“BN”的临时文件,随后调用CreateFileA和WriteFile将下载的内容写入之前创建的临时文件中。

图片

恶意样本首先判断下载的文件是DLL还是exe,若是DLL则用Rundll32.exe使其运行,而调用Rundll32.exe的方式是将其以参数的形式传入CreateProcess之中;若其是exe,则直接通过CreateProcess将其启动。

图片

 

总结

HANCITOR是一款成熟的商业化恶意软件下载器,此样本以Word文档为载体,该文档中包含恶意宏代码,恶意宏代码执行后会在主机上释放最终的DLL文件(HANCITOR),该DLL文件的功能包括为每个受害者生成唯一GUID,以及根据相关指令,从指定URL中下载后续的恶意样本以及shellcode并执行。建议提前部署高级威胁检测设备,对相关网络进行监控和保护。

图片

 

- End -

 

京公网安备 11010802024705号  京ICP备20030588号 Copyright © 兰云科技 www.lanysec.com 版权所有