海莲花APT的某款样本分析 | 42期

admin 2024年10月19日22:44:52评论23 views字数 5409阅读18分1秒阅读模式
 海莲花APT的某款样本分析 | 42期

APT海莲花的某款样本分析

小常识: APT海莲花的英文名字 OceanLotus。

01 身份证

名字: 36 ASEAN Summit 26-06-2020 Conference.doc~.exe。

SHA256: dbde2b710bee38eb3ff1a72b673f756c27faa45d5c38cbe0f8a5dfccb16c18ba。

MD5: SHA1: 4a41bc81b27374b8a711794a7b27d51700403341。

样本格式: SFX(RAX自解压)。

回连C2: tripplekill.mentosfontcmb.com。

长这个样子:

海莲花APT的某款样本分析 | 42期

看上去是一个word,但他本来就是一个exe。

02 运行效果

通过网上的样本分析得:很多东西都是为了解密一段shellcode,然后执行它。于是我用了比较直接的形式解密了shellcode然后执行它。

直接的效果就是wps打开了一个word,然后就没了。

03 基本PE信息

海莲花APT的某款样本分析 | 42期

Die中,出现一些关键字,PE32和Zip经过查询资料,推断该文件为自解压压缩文件。

通过7-zip打开文件:

海莲花APT的某款样本分析 | 42期

发现这些信息。

APT组织加载恶意样本的方式多种多样,其中白加黑的加载方式是一种常用的APT攻击手法,也是海莲花APT组织最常用的APT攻击手法之一,统计最近几年国内发布的OceanLotus(海莲花)APT组织报告中的白+黑程序名。

如下所示:

海莲花APT的某款样本分析 | 42期

之前我们用7-zip打开过exe文件,我们可以解压打开它(哇塞,既然可以把一个exe 解压缩)。

内含有:

海莲花APT的某款样本分析 | 42期

本次样本采用白+黑的模式运行。 

启动白程序,然后利用升级程序MicrosoftUpdate.exe

加载SoftwareUpdateFiles.Resources目录下的恶意程序SoftwareUpdateFilesLocalized.dll。

SoftwareUpdateFilesLocalized.dll会读取目录下的SoftwareUpdateFiles.locale文件。

然后解密SoftwareUpdateFiles.locale并执行。

04 Dll 加载

主要是寻找SoftwareUpdateFilesLocalized.dll如何被加载的。

MicrosoftUpdate.exe的导入表里面有SoftwareUpdateFiles.dll,但是没有SoftwareUpdateFilesLocalized.dll ,而且查看MicrosoftUpdate.exe,SoftwareUpdateFiles.dll,SoftwareUpdateFilesLocalized.dll的字符串信息,并没发现SoftwareUpdateFilesLocalized.dll的字符串信息。

查资料后推测:SoftwareUpdateFilesLocalized.dll由其他系统dll加载(后来证实发现,是SoftwareUpdateFiles.dll,加载的SoftwareUpdateFilesLocalized.dll)。

还有一种情况是把数据解密后才会有目标字符,只是猜测罢了。

海莲花APT的某款样本分析 | 42期

可以看见在C:WindowsSysWOW64msvcrt.dll加载后,就加载了C:UsersvirusDesktop7579AEDE6A223C96231AD30472A060DBSoftwareUpdateFiles.dll。

SoftwareUpdateFiles.dll是存在于导入表的,然后看SoftwareUpdateFilesLocalized.dll是怎么加载的,通过xdebug和IDA 2次测试,发现IMM32.DLL加载后,才会加载SoftwareUpdateFilesLocalized.dll,然后看IMM32.DLL是否引入SoftwareUpdateFilesLocalized.dll。

海莲花APT的某款样本分析 | 42期

发现并没有引入。 

可能是IMM32.DLL动态加载的,然后猜测是IMM32.DLL调用了Kernel32的LoadLibiary加载的。

海莲花APT的某款样本分析 | 42期

所以,可以去对应的API下断点。

海莲花APT的某款样本分析 | 42期

虽然导入表只有LoadLibiaryExW,但是我还是在可能的地方都设置了断点,比如在上面。

海莲花APT的某款样本分析 | 42期

于是F9后,它停在了:

海莲花APT的某款样本分析 | 42期

what?

难道不是IMM32.DLL加载的,明明IMM32.DLL只调用了Kernel32的LoadLibiaryExW。为什么这里是LoadLibarayW?

观察函数的参数:

海莲花APT的某款样本分析 | 42期

就是一个字符串,内容是一个dll地址。

海莲花APT的某款样本分析 | 42期

之后再次F9,就不会停在LoadLibary相关的API,说明后面也没有加载SoftwareUpdateFilesLocalized.dll。

于是我们算是知道了是LoadLibaryW加载的SoftwareUpdateFilesLocalized.dll。

但是很懵,到底是谁调用LoadLibiaryW加载的SoftwareUpdateFilesLocalized.dll?

到底是谁调用的LoadLibaryW,其实你看LoadLibaryW函数返回到哪个模块,说明就是那个模块就调用了LoadLibaryW呗。

这不就是<<逆向工程核心原理>>讲过的吗?

海莲花APT的某款样本分析 | 42期

于是去往返回地址就在SoftwareUpdateFiles.dll模块。

通过返回地址和IDA的静态分析,发现在int __thiscall ASUResourceProxy::ASUResource-Proxy(int this,wchar_t *a2)函数里面加载了dll:

海莲花APT的某款样本分析 | 42期

然后很奇怪的是,对于SoftwareUpdateFilesLocalized.dll的DllMain,

海莲花APT的某款样本分析 | 42期

进入sub_10001020((int)hinstDLL);是对SoftwareUpdateFiles.dll做一个API的Hook。

海莲花APT的某款样本分析 | 42期

也就是SoftwareUpdateFiles.dll(A)加载SoftwareUpdateFilesLocalized.dll(B),然后SoftwareUpdateFilesLocalized.dll(B)调用dllMain又把SoftwareUpdateFiles.dll(A)给Hook。

海莲花APT的某款样本分析 | 42期

为什么这样做呢?

对于SoftwareUpdateFiles.dll加载SoftwareUpdateFilesLocalized.dll的时候,

海莲花APT的某款样本分析 | 42期

它意思就是说,如果SoftwareUpdateFilesLocalized.dll加载失败了,那就不调用没有下面这句话。

海莲花APT的某款样本分析 | 42期

也就是SoftwareUpdateFilesLocalized.dll加载失败后不报错。

海莲花APT的某款样本分析 | 42期

然后对MicrosoftUpdate.exe的函数hook。

05 shellcode 加载

分析SoftwareUpdateFilesLocalized.dll对于存在SHELLCODE的样本,其加载原理大多通过"VirtualAlloc"函数将SHELLCODE注入到某个内存空间中,所以寻找VirtualAlloc的交叉引用即可。 

于是就可以发现一个函数void __noreturn sub_100010C0(),在SoftwareUpdateFilesLocalized.dll被加载后,在一些关键位置下了断点。

第1次F9来到SoftwareUpdateFilesLocalized.dll的HMODULE __usercall sub_10001020@(int a1@),然后对SoftwareUpdateFiles.dll进行一个Hook,让它不报错。

然后再次对MicrosoftUpdate.exe Hook。

海莲花APT的某款样本分析 | 42期

可以看出,他是Hook了12个字节, 2+4+2+4,效果如下,Hook前:

海莲花APT的某款样本分析 | 42期

Hook后,去往SoftwareUpdateFilesLocalized.dll解密二进制文件SoftwareUpdateFiles.locale让他执行。

海莲花APT的某款样本分析 | 42期

于是第二次F9,出现了很多C+= Exception,也就是F9了很多次,每次把异常交个程序自己处理。

后面又来到了SoftwareUpdateFiles.dll,然后它再次加载SoftwareUpdateFilesLocalized.dll,然后再F9,就发现它去往了二进制文件解密函数,该函数前面干的事情就是获取路径。

海莲花APT的某款样本分析 | 42期

后面就是读取文件,然后分配内存,然后解密。

海莲花APT的某款样本分析 | 42期

注意对内容解密后,它是直接:

海莲花APT的某款样本分析 | 42期

也侧面说明了该二进制文件不是可执行的PE文件,而是shellcode。

06 shellcode 分析

这一次算是真正的发现了shellcode长什么样子。

ShellCode加入大量无意义运算和无效跳转花指令,用于干扰分析。

07 重定位分析

海莲花APT的某款样本分析 | 42期

第一条指令运行: 如果st0<st5,那么st5=st0,否则啥也没发生< div="">,指令运行前:

海莲花APT的某款样本分析 | 42期

运行后:

海莲花APT的某款样本分析 | 42期

其实到这里,我们还是不太清楚第一句话是干嘛的。 

(ps:后面一点点马上解释。)

执行fnstenv byte ptr [esp-0Ch]前:

海莲花APT的某款样本分析 | 42期

当fnstenv byte ptr [esp-4*3]执行之后:

(ps:他就是把FPU的一部分环境拷贝到esp-4*3的地方。)

海莲花APT的某款样本分析 | 42期

可以看到[esp]的地方,他的值=0x00BD0000,这个数据很特殊,也就是他的值就是shellcode开始的地方,也就是说这个是一个EIP,我尝试运行了几遍,发现[esp]始终的执行一个shellcode起始地址。后面拷打了很多次chatgpt,他才告诉我这是为什么。 

首先是提问:

海莲花APT的某款样本分析 | 42期

fnstenv指令保存的字节数取决于使用的保存格式,在x86汇编中,有两种保存格式: 

1.短格式:fnstenv [目标],它保存28个字节的FPU环境信息。

2.长格式:fnstenv [目标],它保存108个字节的FPU环境信息。

因此,fnstenv指令会存储28个字节或108个字节,具体取决于您选择的保存格式,在大多数情况下,推荐使用较小的短格式,除非您需要完整的FPU环境信息。 

然后,对于我们这里,他属于28字节的情况:

海莲花APT的某款样本分析 | 42期

1.控制寄存器(Control Register,CW):2个字节;

2. 状态寄存器(Status Register,SW):2个字节;

3. 标签寄存器(Tag Register,TW):2个字节;

4.FPU指令指针偏移量(Instruction Pointer Offset):2个字节;

5.FPU指令指针选择器(Instruction Pointer Selector):2个字节;

6. 数据指针偏移量(Operand Pointer Offset):2个字节; 

7.数据指针选择器(Operand Pointer Selector):2个字节;

8.FPU状态寄存器(FPU Status Word):2个字节; 

9.FPU控制寄存器(FPU Control Word):2个字节; 

10.FPU标签寄存器(FPU Tag Word):2个字节; 

11.FPU数据寄存器(FPU Data Registers):8个字节。

通过观察发现,数据指针选择器和FPU状态寄存器构成的4字节是shellcode的起始地址。

于是问chargpt:

海莲花APT的某款样本分析 | 42期

数据指针选择器(Data Pointer Selector)和FPU状态寄存器(FPU Status Register), 与当前运行的EIP(Extended Instruction Pointer)在x86架构中是有关系的。 

当执行FPU指令时,数据指针选择器会帮助确定从哪里加载或存储FPU数据寄存器的值,而FPU状态寄存器则包含了FPU的运算状态和控制信息这些寄存器的值会影响FPU指令的执行过程,EIP则是指向当前正在执行的指令的指针在程序执行期间,如果涉及到FPU操作,FPU数据的加载和保存可能会涉及到EIP的信息,以确定正确的数据寄存器位置和正确的FPU状态。 

因此,数据指针选择器和FPU状态寄存器与当前运行的EIP密切相关,用于在执行浮点运算时正确管理和控制FPU环境,对于chatgpt的回答,只能说是了解一下,可能就真的是那么一回事情。 

这就是为什么shellcode一开始就要fcmovb st,st(5) 

只是为了构造一个FPU指令,方便后面做一个环境的保存,至于为什么是[esp-0Ch],是为了刚好把那个FPU据指针选择器给pop出来。

08 SMC-1

然后就是SMC解码可以看出是通过Loop循环异或实现SMC。

海莲花APT的某款样本分析 | 42期

一开始对00E0001B地址处解密,解密之后才是loop循环。

海莲花APT的某款样本分析 | 42期
海莲花APT的某款样本分析 | 42期

感觉这种加密算法更加小小的复杂。

09 找打kernel32并获GetProcAddress

函数分析struct LIST_ENTRY *__stdcall sub_11F0059(DWORD *a1),关于那个结构体到底怎么会是这样,查看笔记:https://www.notion.so/aca3da52fbe14f0380c8d770b79feaad。

海莲花APT的某款样本分析 | 42期
海莲花APT的某款样本分析 | 42期

然后具体说一下他是怎么回事的,关于模块寻找的函数如下:

海莲花APT的某款样本分析 | 42期

对于每次遍历,如何处理?

海莲花APT的某款样本分析 | 42期

遍历到kernel32.dll后如何获取导出函数?

如下:

海莲花APT的某款样本分析 | 42期

10 加载API和其他操作

一开始加载了很多的API,接着才是调用API的一些操作。

海莲花APT的某款样本分析 | 42期

接着后面就是一些奇奇怪怪的文件操作了。

海莲花APT的某款样本分析 | 42期

11 后续

海莲花APT的某款样本分析 | 42期

后续有一点多,这里就不进行具体分析了。

12 其它发现

热补丁:

海莲花APT的某款样本分析 | 42期
海莲花APT的某款样本分析 | 42期

长按二维码关注

D0g3

道格安全

原文始发于微信公众号(道格安全):海莲花APT的某款样本分析 | 42期

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年10月19日22:44:52
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   海莲花APT的某款样本分析 | 42期https://cn-sec.com/archives/1940754.html

发表评论

匿名网友 填写信息