海莲花OceanLotus样本分析
基本信息
APT32是一个至少从2014年开始活跃的威胁组织,别名海莲花(OceanLotus)。该组织针对多个私营企业、外国政府、持不同政见者和记者,重点关注越南、菲律宾、老挝和柬埔寨等东南亚国家。该组织是一个与越南政府利益一致的网络间谍组织。
FILENAME | FILESIZE | MD5 |
---|---|---|
sample.exe | 23487488 bytes | 09D115A3B45694F8124CD8077D51A2EC |
流程图
动态分析
使用ProcMon
进行抓包,样本释放名为A553.tmp
的文件到环境变量TEMP目录,后经查看释放文件是样本母体拷贝到了TEMP目录
释放后执行释放的A553.tmp
文件,释放体会将样本母体替换为同名的真实docx文档,并通过注册表查询word文档关联的默认打开程序,使用默认程序打开docx文档迷惑用户
详细分析
样本入口点存在混淆代码,干扰分析与调试,排除无意义的跳转逻辑,剩下一个真实的条件跳转,根据判断条件,基本可以断定这个混淆会循环0xF5B2C
次,在其地址后下断,直接跑即可到达核心代码位置
将内存页起始地址为0x45A000
,大小为0x5DC00
的内存属性修改为PAGE_READWRITE
解密代码,将0x45A000
地址内容使用bswap
指令进行字节次序变反,并将相邻的两个四字节进行位置调换
解密完成,再次调用VirtualProtect
将内存属性修改为PAGE_EXECUTE_READ
到这里后发现其实前面的代码类似于一个自写的混淆加密壳,此时才来到程序真正的入口点,使用ODdump
功能+ImprotREC
对进程进行脱壳修复
对修复后的程序进行分析,发现程序中仍嵌有大量混淆代码
来到核心逻辑,首先获取计算机名称
将计算机名中大写转换为小写,根据代码特征可以看出该代码为GitHUb开源VC-LTL项目,该项目是基于MS VCRT的开源CRT库,可减少程序二进制文件的大小并告别Microsoft运行时DLL,例如msvcr120.dll,api-ms-win-crt-time-l1-1-0.dll和其他依赖项
这样一来,增加了样本分析难度,继续跟进时发现混淆的一个规律,在函数开头时便进行混淆跳转,而最后还是会回到函数内部执行后续调用,下图函数为例,在函数入口点跳飞,之后跳转回call memcpy
处
混淆太多了,程序中存在很多无意义的条件跳转以及push+retn
,短时间内去除混淆是不可能了,为了节省时间,想个懒办法,编写OD脚本,在所有的call
指令断下,断下后再根据IDA分析是否需要进入call,这样能缩短一部分时间
1 | FIND: |
调用LoadLibraryW
加载Ole32.dll
调用GetProcAddress
获取CoInitialize
,在这里发现该样本一个特征,每次关键函数调用都是在异常handler
里进行的,猜测该混淆模式就是利用异常执行真正核心代码,而正常程序流程都是混淆代码
判断程序运行参数是否为--splash
,这里是在确认是样本母体还是后缀为tmp的拷贝体
程序开始循环申请内存,申请大小从1字节开始依次递增,这仍是混淆的一部分,但申请内存就会使用call执行,之前的OD脚本貌似不是很管用了,修改脚本再试试
1 | FIND: |
调用服务操作系列API,判断是否存在名为Schedule
的服务
不存在Schedule
服务,获取TEMP目录路径,创建TEMP文件
获取当前进程名称
调用windows提供加密系列API,生成128字节随机密钥
75CC1526DC9E6F591AF2C508C636FFEC66DE8594736B5D7C947E549A0B2AC0720E84E32B30F78148972030677A35B2350C1071A4DA378F345E432FBAE3DF0BEA
调用文件操作系列API ,将样本母体读入内存
再次调用文件操作系列API ,将母体写入前述创建的tmp文件中
拼接命令行参数并带参创建进程执行tmp文件,随后退出主进程
tmp进程参数如下
[tmp文件路径] + [-–splansh] + [样本母体路径]+ [生成的随机密钥]
tmp文件调试
设置镜像劫持后调试子程序,来到判断--splash
参数之后的逻辑
通过API PathFileExistsW
判断样本母体是否存在
这里发现一种之前从未见过的检测镜像劫持的方法,在样本母体中使用CreateProcessW
创建子进程时,传入参数如下,红框中的字节码20,原本传入的是09,而在使用镜像劫持时发现参数变成了20,在调用PathFileExistsW
判断样本母体是否存在时,09会被识别为结束符号,可以正确检测到样本存在,而20会将生成的随机密钥和文件路径拼接成一个字符串从而导致检测失败
调用资源操作系列API,将资源名称为0x65的内容加载到内存并进行解密,将解密的内容重写回样本母体文件(解密的内容为正常的docx文件)
再次调用资源操作系列API,将资源名称为0x7的内容加载到内存,从资源中取出文件后缀字符串”.docx”,修改样本母体后缀为”.docx”,并打开docx文件迷惑用户
通过特权指令检测虚拟机环境
初始化sha256哈希算法和拍进程拍照,后续并未使用
动态获取CreateDirectoryW
函数地址并调用,判断所要释放文件的路径是否为根路径
解密并释放
%appdata%/Tencent/QQ/qq.exe与
%appdata%/Tencent/QQ/plugin/Com.Tencnt.DirectShow/bundle.rdb
修改注册表项
HKCU/SOFTWARE/mspaint–>…Com.Tencent.DirectShow\Bundle.rdb
HKLM/SOFTWARE/mspaint–>…Com.Tencent.DirectShow\Bundle.rdb
创建两条计划任务每15分钟执行一次释放体名为qq.exe的程序
QQ International Automatic Updates:
Intelligently select the best update type for QQ when available.
Download and install updates automatically to save time and effort.
Keep the lastest version, enjoy the best performance!
QQ.exe分析
定时条件出发后会执行QQ.exe,同样的混淆手法,这里简单使用API monitor
进行分析,首先是动态获取后续要用的API
在程序运行目录创建QQ.exe.db,后将所运行QQ.exe写入到文件,并将QQ.exe.db重命名为QQ.exe.bak,随后动态修改QQ.exe静态文件内容
随后通过注册表读取前述释放bundle.rdb路径
大量混淆过后带参执行QQ.exe,参数为rundll32.exe /m
(这里又是一个坑,如果设置镜像劫持,CreateProcess将导致启动系统自带的rundll32.exe,暂不深入研究)
创建msiexec.exe进程
再次动态获取函数地址
注入shellcode到msiexec进程,第一次注入内容为bundle.rdb路径,第二次为要执行的代码
shellcode比较简明,直接调用LoadLibraryW
加载Bundle.rdb
Bundle分析
首先是动态获取API IsProcessorFeaturePresent
进行反调试
解析C2地址,尝试循环连接到不同的C2服务器
C2均已失效,无法获取后续模块,Bundle.rdb其实就是用来与C2进行交互的后门模块
IOC
NAME | MD5 |
---|---|
QQ.EXE | 52E69E757AA2A8E001E410AD6372D620 |
bundle.rbd | 3B4BB69D1D61FBE215CAD7D833026D4C |
C2 |
---|
blog.panggin[.]org:27408 |
yii.yiihao126[.]net:40005 |
share.codehao[.]net:80 |
yii.yiihao126[.]net:443 |
总结
后门功能已分析完毕,由于C2失效无法跟进后续行为,这个样本的行为从用户角度来看一切看似很正常,像是QQ的定时自动更新功能一样,使用msiexec安装新的QQ程序。但实质是注入恶意模块到msiexec与C2建立通信。海莲花的样本使用的反分析反调试手段越来越多,分析起来难度较大,其实样本核心逻辑并不会很多,但是单从样本大小来看,一个文件几十兆,可想而知,其中参杂了很多无效指令和函数进行混淆,并动态解密各种代码数据。