DoNot组织在其框架中引入浏览器窃取模块
· 2 分钟阅读 · @admin

Donot“肚脑虫”(APT-Q-38)是疑似具有南亚背景的APT组织,其主要以周边国家的政府机构 为目标进行网络攻击活动,通常以窃取敏感信息为目的。该组织具备针对Windows与Android双平台的攻击能力。 在对该组织追踪朔源的过程中,发现Donot使用了一系列新型的后门框架,该框架名为Jaca,根据组件的功能分别分为下载执行组件、文件上传组件、截图组件、文件收集组件、键盘鼠标消息记录组件、浏览器敏感信息窃取组件、移动磁盘文件收集组件等等。
2. 样本详情
| 文件名 | S03.doc |
| MD5 | 3fabf3b97362af460abe98855c7caef8 |
| 文件类型 | Office word文档 |
| 文件名 | HG5HlDPqsnr3HBwO.php |
| Md5 | 21b82530fa520eecd5aa677fa7ec0879 |
| 文件类型 | Office word模板 |
| 文件名 | pgixedfxglmjirdc.dll |
| Md5 | b38586849d45649db67189c1e7c0397e |
| 文件类型 | dll |
3. 流程图

4. 详细分析
1. s003.doc分析
该样本使用远程RTF模板注入,在RTF的template数据中插入要加载的模板文件,模板文件地址为:
http://necromencertwo.buzz/bfrp31KqURS2yZTE/0BmHwYTEgupY2Qfb.php
如下图所示:
托管模板文件的服务器会判断是否由office文档发送请求,如果不是则返回诱饵文档,否则返回携带恶意宏代码的文档。
模板文件的元数据如下, 元数据中与个人有关的元数据已经被清除, 使分析人员不能通过元数据获取到有用的信息。

从元数据中的数据可以推测出如下几点:
-
模板文件创建时间为2021年3月30日,最近的修改时间为2022年6月6号,可以得知至少在2021年3月份Donot组织就开始在使用远程RTF模板注入,并且是用工具对同一个文件来生成的包含不同恶意宏代码的文件。
-
Donot生成模板文件时使用的操作系统为win10-x64,使用的office word的版本为15.000。
1.1 宏代码
当模板注入成功时,它会诱使受害者开启宏功能以使恶意宏代码能够执行。宏被启用后调用dOCument_OpEN方法,dOCument_OpEN主要功能是拼接shellcode,调用ZwAllocateVirtualMemory在当前进程(word.exe)的内存空间分配内存存放shellcode并设置可执行属性;调用MultiByteToWideChar将shellcode从字节转换成utf-16;将转换后的shellcode作为回调参数传入函数EnumUILanguagesA中。

打开带有恶意宏代码的word程序有x86和x64版本两个版本,在宏代码中利用宏定义Win64来识别并在EnumUILanguagesA中使用不同版本的shellcode。

1.2 Stage1 x64 shellcode
X86和x64版本的shellcode大致一样, 不同的是获取PEB结构地址的方法和 在获取已加载的模块时使用的结构体偏移不一致。

通过PEB来查找kernel32.dll的加载地址

获取Dll函数加载地址和函数地址时并不使用明文来获取,而是在恶意程序内部硬编码了几个函数名对应的哈希值。寄存器 rsi为要查找的API地址所在的dll的加载基址,通过加载地址解析模块的导出表并计算哈希值,要查找的API都是以硬编码哈希的形式存放在程序内,该哈希值先异或0xBAADC0D3再与计算出的哈希值进行比较,如果相等则返回对应API的函数地址,否则继续比较直到找到为止。

解析以下函数地址用于保存下载的文件和分配内存

从服务器下载加密的shellcode并保存到临时文件,由于服务器已经无法连接,不能继续分析下一阶段的shellcode。

解密加密的shellcode并跳转到shellcode执行代码。

在shellcode中发现一些有趣的字符串,这些信息是用于第二阶段的shellcode用于解密的xor密钥和一些安全产品到期时间等等。

a) Stage1 x86 shellcode
这一阶段的shellcode与x64版本的shellcode一样,开头代码为解密后续的加密数据,解密算法为对加密数据的每一个字节先取反然后异或0x2B,大小为0x29A。

与x64版本的shellcode一样, 通过是遍历peb的链表InLoadOrderModuleList指向的模块相关的数据结构来获取kernel32.dll的加载地址。

通过比较函数哈希来获取函数地址的方法与x64版本一样。

解密该阶段和下阶段shellcode要使用的API函数地址。

从服务器上下载加密的shellcode, x64 shellcode下载是png后缀的文件,x86下载的是ico后缀文件。

异或解密后服务器上下载的shellcode, 然后判断解密的shellcode的入口点是否为0x89、0x90、0xcc, 如果是则表示已经解密成功,跳转到shellcode入口点执行代码,如果不是则从shellcode返回到进程word而不执行任何恶意代码。
1.4 Stage2 x86 shellcode
该阶段的shellcode入口代码和前面的shellcode一样,先解密加密数据然后跳转到解密后的代码执行。

解析shellcode用到的API地址, 解析方法与前面shellcode与前面的shellcode使用的方法一样。

在这一阶段shellcode中,寄存器EDI指向的内存使用的结构体如下:
struct format
{
int kernel32_VirtualAlloc;
…//省略部分字段均为API的函数地址
int urlmon_URLDownloadToFileA;
char unkonw_data[296];
char syswow64_path[256]; //字符串%tmp%\syswow64.dll
char doc_path[256];//文档路径 '%tmp%\document.doc
char cmd1[256];
int klif_exits;//klif.sys是否存在
char klif_flag;// klif.sys文件的过期标志
int aswsp_exits;// aswsp.sys是否存在
char aswsp_flag;// aswsp.sys文件的过期标志
int bsfs_exits;// bsfs.sys是否存在
char bsfs_flag;//bsfs.sys的过期标志
int gzflt_exits;// gzflt.sys是否存在
char gzflt_flag;//gzflt.sys的过期标志
int ehdrv_exits;// ehdrv.sys是否存在
char ehdrv_flag;//ehdrv.sys的过期标志
int _360AvFlt_exits;// 360AvFlt.sys是否存在
char _360AvFlt_flag;// 360AvFlt.sys的过期标志
};
Shellcode会检测以下文件是否存在, 并使用结构体的两个字段来分别表示文件是否存在或者是否已经过期。比如用字段bsfs_exits来标志basfs.sys是否存在,bsfs_flag来判断是否过期。
klif.sys aswsp.sys bsfs.sys gzflt.sys ehdrv.sys 360AvFlt.sys
以aswsp.sys为例, 该文件不存在时字段bsfs_exits值设为0, 将本地时间与预设的过期时间相比较,小于等于过期时间时字段aswsp_flag设置为1,否则为2。

如果文件存在, 则根据flag的值来执行不同的行为, 在这个行为中使用以下这些值, 分别用[1]-[7]来表示。
[1] hxxp://mak.logupdates.xyz/DWqYVVzQLc0xrqvt/HG5HlDPqsnr3HBwOKY0vKGRBE7V0sDPdZb09n7xhp0klyT5X.mp3 [2] hxxp://mak.logupdates.xyz/DWqYVVzQLc0xrqvt/HG5HlDPqsnr3HBwOKY0vKGRBE7V0sDPdZb09n7xhp0klyT5X.doc [3] %tmp%\syswow64.dll [4] %tmp%\document.doc [5] Qoltyfotskelo [6] schtasks.exe /create /tn wakeup /tr "rundll32 %tmp%\syswow64.dll, HPMG" /f /sc DAILY /st 11:00 /ri 10 /du 24:00、 [7] cmd.exe %tmp%\syswow64.dll
下表为如果驱动文件存在时shellcode要执行的动作:
| 驱动名 | 所属安全软件 | 到期时间 | Flag为1(未过期) | Flag为2(已过期) |
| gzflt.sys | BitDefender | 2022.07.15 | 参考1.5 | 参考1.6 |
| klif.sys | 卡巴斯基 | 2022.07.11 | 参考1.7 | 解密shellcode,后面与节1.6一样 |
| aswsp.sys | Avast | 2022.07.15 | 参考1.5 | 参考1.6 |
| ehdrv.sys | ESET NOD32 | 2022.07.23 | 参考1.5 | 参考1.6 |
| bsfs.sys | QuickHeal | 2022.07.17 | 参考1.5 | 返回到进程word |
| 360AvFlt.sys | 奇虎360 | 2022.07.19 | 参考1.5 | 参考1.6 |
1.5 下载文件并调用导出函数
从连接[1]下载文件并保存到[3],下载的文件头部的PE结构magic值被抹除,这是为了绕过反病毒软件的检测。恢复文件头部然后加载文件并调用其导出函数[5]

1.6 通过WinExcute执行程序
从连接[1]下载文件并保存到路径[3],从连接[2]下载诱饵文档保存到路径[5],然后拼接创建计划任务时需要的命令行[6],使用函数WinExec来执行命令。

1.7 注入shellcode到bcrypt.dll并执行
将另一段shellcode注入到模块bcrypt.dll的内存空间内, 修改内存属性为可执行然后执行注入的shellcode。

注入的代码如下, 也是从连接[1]下载文件保存到[3],然后执行dll的导出函数。

2. syswow64.dll分析
该文件包含两个导出函数Yolueorgw和Qoltyfotskelo。第一个导出函数主要是检测防病毒软件和检测是否在虚拟机内执行。第二个导出函数为设置计划任务。
1. 检测互斥量和虚拟机环境
创建名为”KRDNVCEAMGT@LJHNKED”的互斥量, 如果恶意程序已经在运行中则退出程序。通过WMI来查询产品名来判断是否处于虚拟机环境中,如果处于虚拟机环境中则退出程序。

2. 检测是否安装安全软件
恶意程序检测目标机器上是否由安装360TotalSecurity,如果有则将自删除代码写入脚本并执行。

自删除代码如下,bat使用了5个参数, 通过taskkill结束自身进程,调用del删除自身文件,调用schtasks来删除名为DrivealoneUpdates的计划任务。

3. 收集信息
收集受害者用户名、机器名和处理器ID信息。

收集目录” C:\Program Files”和” C:\Program Files(x86)”下所有的文件夹,并用字符”?”来分隔。

最终将所有收集到的数据拼接在一起并加密上传到C&C服务器,使用的加密方法为AES256+Base64,通过post方法将加密后的值作为字段batac的值发送到C&C服务器
rus.feedpolicy.xyz/Nb438e8pcbar5ky245ntr4um/tk5hyeq9pgdt

3. 检测网络是否有效
恶意程序往地址en.wikipedia.org/wiki/Encyclopedia发送数据包来检测受害者机器的网络是否有效。

网络有效则在目录”c:\ProgramData”下创建文件”yjzsghu.txt”并写入数据” BQO89GHY7ki”来标识网络处于连通状态。

4. 创建计划任务
创建定时的计划任务,每隔3分钟执行一次程序,执行的程序和命令行如下:
rundll32.exe %Temp%\pgixedfxglmjirdc.dll,Yolueorgw

4. 删除计划任务
调用程序schtasks来删除名为Jiscor的计划任务。

5. C&C指令
如果由C&C服务器返回的指令中包含”Lok”时恶意程序发送数据到C&C服务器请求下载文件, 发送的格式如下, 与上传泄露信息时使用相同的加密方法。
用户名-机器名-处理器ID|||dll名

下载的模块保存于目录%pragramData%/DeviceStage下。

由于C&C服务器已经关闭,无法接收到后续的指令,因此无法继续分析下去。
5. IOC
3fabf3b97362af460abe98855c7caef8 21b82530fa520eecd5aa677fa7ec0879 b38586849d45649db67189c1e7c0397e yjzsghu.txt hxxp://necromencertwo.buzz/bfrp31KqURS2yZTE/0BmHwYTEgupY2Qfb.php
6. ATT&CK矩阵
| Tactic | ID | Name | Description |
| initial-access | Phishing | T1566 | 通过网络钓鱼投递 |
| execution | Command and Scripting Interpreter | T1059 | 使用bat脚本自删除 |
| Scheduled Task/Job | T1053 | 设置计划任务来定时执行程序 | |
| defense-evasion | Template Injection | T1221 | Office文档使用模板注入 |

