海莲花OceanLotus样本分析

基本信息

APT32是一个至少从2014年开始活跃的威胁组织,别名海莲花(OceanLotus)。该组织针对多个私营企业、外国政府、持不同政见者和记者,重点关注越南、菲律宾、老挝和柬埔寨等东南亚国家。该组织是一个与越南政府利益一致的网络间谍组织。

FILENAME FILESIZE MD5
sample.exe 23487488 bytes 09D115A3B45694F8124CD8077D51A2EC

流程图

image-20210526155604064

动态分析

使用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
2
3
4
5
6
7
8
9
10
11
12
13
14
FIND:
STI
CASE1:
CMP [eip],#E8#,1
JNE CASE2
pause
CASE2:
CMP [eip],#FF#,1
JNE CASE3
pause
CASE3:
CMP [eip],#9A#,1
JNE FIND
pause

调用LoadLibraryW加载Ole32.dll

调用GetProcAddress获取CoInitialize,在这里发现该样本一个特征,每次关键函数调用都是在异常handler里进行的,猜测该混淆模式就是利用异常执行真正核心代码,而正常程序流程都是混淆代码

判断程序运行参数是否为--splash,这里是在确认是样本母体还是后缀为tmp的拷贝体

程序开始循环申请内存,申请大小从1字节开始依次递增,这仍是混淆的一部分,但申请内存就会使用call执行,之前的OD脚本貌似不是很管用了,修改脚本再试试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
FIND:
STI
CASE1:
CMP [eip],#E8#,1
JNE CASE2
CMP eip,468F11//new
JE NOTFIN
CMP eip,469906//memcpy
JE NOTFIN
CMP eip,469517//delete
JE NOTFIN
CMP eip,4697b3//hunxiao2
JE FIND
CMP eip,486980//hunxiao1
JE FIND
pause
CASE2:
CMP [eip],#FF#,1
JNE CASE3
CMP eip,48762d
JE FIND
pause
CASE3:
CMP [eip],#9A#,1
JNE FIND
pause
NOTFIN:
STO
jmp FIND

调用服务操作系列API,判断是否存在名为Schedule的服务

不存在Schedule服务,获取TEMP目录路径,创建TEMP文件

获取当前进程名称

image-20210510183003150

调用windows提供加密系列API,生成128字节随机密钥

75CC1526DC9E6F591AF2C508C636FFEC66DE8594736B5D7C947E549A0B2AC0720E84E32B30F78148972030677A35B2350C1071A4DA378F345E432FBAE3DF0BEA

image-20210510183450290

image-20210510183938498

调用文件操作系列API ,将样本母体读入内存

image-20210510185023137

image-20210510185102176

image-20210510185616029

再次调用文件操作系列API ,将母体写入前述创建的tmp文件中

image-20210511165925818

image-20210511170404432

拼接命令行参数并带参创建进程执行tmp文件,随后退出主进程

tmp进程参数如下

[tmp文件路径] + [-–splansh] + [样本母体路径]+ [生成的随机密钥]

image-20210511182824085

image-20210511183329693

image-20210511183509345

tmp文件调试

设置镜像劫持后调试子程序,来到判断--splash参数之后的逻辑

通过API PathFileExistsW判断样本母体是否存在

这里发现一种之前从未见过的检测镜像劫持的方法,在样本母体中使用CreateProcessW创建子进程时,传入参数如下,红框中的字节码20,原本传入的是09,而在使用镜像劫持时发现参数变成了20,在调用PathFileExistsW判断样本母体是否存在时,09会被识别为结束符号,可以正确检测到样本存在,而20会将生成的随机密钥和文件路径拼接成一个字符串从而导致检测失败

image-20210524130851762

调用资源操作系列API,将资源名称为0x65的内容加载到内存并进行解密,将解密的内容重写回样本母体文件(解密的内容为正常的docx文件)

image-20210512104253276

image-20210512104102595

image-20210512104144523

image-20210524141032691

再次调用资源操作系列API,将资源名称为0x7的内容加载到内存,从资源中取出文件后缀字符串”.docx”,修改样本母体后缀为”.docx”,并打开docx文件迷惑用户

image-20210524150923714

image-20210524151154358

image-20210524151325794

通过特权指令检测虚拟机环境

image-20210514124106512

image-20210514130309011

初始化sha256哈希算法和拍进程拍照,后续并未使用

image-20210524184829644

image-20210524190409311

image-20210525010718652

动态获取CreateDirectoryW函数地址并调用,判断所要释放文件的路径是否为根路径

image-20210525021258054

image-20210525022153229

解密并释放

%appdata%/Tencent/QQ/qq.exe与

%appdata%/Tencent/QQ/plugin/Com.Tencnt.DirectShow/bundle.rdb

image-20210525023546007

修改注册表项

HKCU/SOFTWARE/mspaint–>…Com.Tencent.DirectShow\Bundle.rdb

HKLM/SOFTWARE/mspaint–>…Com.Tencent.DirectShow\Bundle.rdb

image-20210525025703894

image-20210525025743642

创建两条计划任务每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!

image-20210525154646494

QQ.exe分析

定时条件出发后会执行QQ.exe,同样的混淆手法,这里简单使用API monitor进行分析,首先是动态获取后续要用的API

image-20210525163816338

在程序运行目录创建QQ.exe.db,后将所运行QQ.exe写入到文件,并将QQ.exe.db重命名为QQ.exe.bak,随后动态修改QQ.exe静态文件内容

image-20210526005306927

随后通过注册表读取前述释放bundle.rdb路径

image-20210525163947112

大量混淆过后带参执行QQ.exe,参数为rundll32.exe /m(这里又是一个坑,如果设置镜像劫持,CreateProcess将导致启动系统自带的rundll32.exe,暂不深入研究)

image-20210525165613474

创建msiexec.exe进程

image-20210525171917035

再次动态获取函数地址

image-20210525172204242

注入shellcode到msiexec进程,第一次注入内容为bundle.rdb路径,第二次为要执行的代码

image-20210525172645639

shellcode比较简明,直接调用LoadLibraryW加载Bundle.rdb

image-20210526020421737

Bundle分析

首先是动态获取API IsProcessorFeaturePresent进行反调试

image-20210526023729346

解析C2地址,尝试循环连接到不同的C2服务器

image-20210526024922977

image-20210526024945888

image-20210526025040090

image-20210526025152972

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建立通信。海莲花的样本使用的反分析反调试手段越来越多,分析起来难度较大,其实样本核心逻辑并不会很多,但是单从样本大小来看,一个文件几十兆,可想而知,其中参杂了很多无效指令和函数进行混淆,并动态解密各种代码数据。