APT32 OceanLotus样本shellcode分析

云里雾里 2021-12-14 09:18:00

0x00 概述


(一)who

"海莲花"(又名APT32OceanLotus),被认为是来自越南的APT攻击组织,自2012年活跃以来,一直针对中国大陆的敏感目标进行攻击活动,该组织主要针对工业领域、政府领域、以及与该组织政见不同的个人与记者。该组织被认为拥有越南背景并进行一系列符合越南国家利益的操作。
攻击手法包括投递诱饵钓鱼(office、黑lnk、白加黑等手法)、payload加载wwlib加载)、绕过安全检测等方面。而从整体攻击方式来看,依然采用电子邮件投递诱饵以及渗透的攻击方式,一旦获得一台机器的控制权后,立即对整个内网进行扫描和平移渗透攻击等。这也进一步说明了APT攻击活动不会因为被曝光而停止或者有所减弱,只要攻击目标存在价值,攻击会越来越猛烈,对抗也会越来越激烈。

(二)What

本次的OceanLotus样本分析,通过VT发现该样本的首次上传时间为2021-06-03 10:55:01 该样本是一个DLL文件DLL被load加载起来的时候会申请一段内存把资源段上的shellcode代码拷贝到内存中并加载,然后执行shellcodeshellcode会创建一个线程用于服务的自启动,随后会创建svchost.exe进程,往进程里面申请内存并写入恶意代码,通过SetThreadContext设置线程上下文的形式去执行svchost.exe的shellcode,该shellcode为Cobalt Strike最后请求C&C。希望刚入门样本分析的小伙伴们也能跟我一样慢慢一步步调试了解...

0x02 样本分析

(一)样本基础情况

样本类型 Hash
DLL edf7dc76776cd05ecf1bc190ae591654

通过virustotal可以发现样本的首次上传时间是在2021-06-03 10:55:01

https://www.virustotal.com/gui/file/f6913fa89fd56104ec7203c8ea829e3446bfdd1663381efc4c064ad2cfd309f4/details

样本可以通过微步去下载

https://s.threatbook.cn/report/file/f6913fa89fd56104ec7203c8ea829e3446bfdd1663381efc4c064ad2cfd309f4/?sign=history&env=win7_sp1_enx86_office2013

1.png

简单的通过pestudio查看下样本的基础信息

1.png

(二)逆向分析

加载资源段

通过IDA逆向分析DLL加载后,通过函数FindResource、SizeofResource、LoadResource、LockResource会从资源段中读取数据,通过VirtualAlloc 函数以分配内存的形式把恶意代码拷贝到内存中去执行。最终v6()是执行从资源段上加载的代码

2.png

使用studype我们也可以看到资源段的数据,但是在这里看不出什么,后面进行动态调试时候可以观察。

3.png

通过xdbg进行动态调试,VirtualAlloc执行后申请的地址返回在eax寄存器上,eax赋值给了edi,最后call edi执行隐藏在资源段上的恶意代码

4.png

Create Thread

步入跟进去call edi里面,我们可以发现此时已经在执行资源段上的shellcode

5.png

进入shellcode后第一个call eax是为了启动一个线程,通过微软官方文档我们得知CreateThread函数,我们得知第三个参数就是指向要由线程执行的应用程序定义的函数的指针。这个指针代表线程的起始地址。我们可以创建一个线程直接跳到该地址进行调试。

HANDLE CreateThread( [in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes, [in] SIZE_T dwStackSize, [in] LPTHREAD_START_ROUTINE lpStartAddress, [in, optional] __drv_aliasesMem LPVOID lpParameter, [in] DWORD dwCreationFlags, [out, optional] LPDWORD lpThreadId );

6.png

该经过逆向发现线程的功能主要是用于服务启动

7.png

shellcode分析

回到主线程里面继续分析,发现shellcode 通过loadLibrary的形式动态加载User32.dll、shell32.dll、paapi.dll、ntdll.dll

8.png

通过call edi的形式GetProcAddress获取多个API地址,若获取失败直接跳转到ret

9.png

还设置处理异常

10.png

通过lstrlenW获取svchost.exe路径的字符串长度

11.png

shellcode 第二次LoadLibrary动态加载user.dll等

12.png

这一次通过Getprocaddress通过call esi的形式获取API 这里是获取了openprocess的地址,获取失败就ret

13.png

创建svchost.exe申请空间并写入恶意代码

通过获取CreateProcess函数来创建svchost.exe

15.png

通过函数IsWow64process并且判断进程是32位还是64位

16.png

收集获取系统信息

17.png

第三次LoadLibrary,继续通过call esi执行GetProcAddress获取API,获取失败就Ret

18.png

19.png

使用HANDLE 通过GetProcessID函数获取进程ID,GetProcess的返回值是 0x1b98转成10进制是7064,表明创建的进程ID是7064

DWORD GetProcessId( [in] HANDLE Process );

21.png

我们通过使用工具火绒剑发现进程ID7064是svchost.exe程序

20.png

随后样本通过VirtualAllocEx函数在svchost.exe中申请内存空间,这里可以通过进程句柄知道是往svchost.exe上申请内存空间,并具有读写执行的权限。申请的内存空间为地址是eax寄存器的数值。

LPVOID VirtualAllocEx( [in] HANDLE hProcess, [in, optional] LPVOID lpAddress, [in] SIZE_T dwSize, [in] DWORD flAllocationType, [in] DWORD flProtect );

22.png

使用火绒剑工具观察svchost.exe的内存空间

23.png

VirtualAllocEx的第一参数是hprocess,此处是svchost.exe的进程句柄,第二次也是在svchost.exe中申请内存空间。并具有读写执行的权限。函数返回值是180000

24.png

再次观察svchost.exe在内存中的地址空间。

25.png

随后通过WriteProcessMemory函数往svchost.exe中地址180000的内存写入数据,写入的数据内容在22291DB地址上。

BOOL WriteProcessMemory( [in] HANDLE hProcess, [in] LPVOID lpBaseAddress, [in] LPCVOID lpBuffer, [in] SIZE_T nSize, [out] SIZE_T *lpNumberOfBytesWritten );

26.png

此时在火绒剑上通过观察发现shellcode已经写入了svchost.exe中

27.png

通过使用CreateToolHelp32Snapshot获取进程的快照并通过Thread32First和Thread32Next遍历线程

28.png

29.png

30.png

OpenThread打开线程ID是0x1b40对应是svchost的线程ID 6976

31.png

使用SuspendThread函数挂起线程

DWORD SuspendThread( [in] HANDLE hThread );

32.png

GetThreadContext保存线程的上下文

BOOL GetThreadContext( [in] HANDLE hThread, [in, out] LPCONTEXT lpContext );

33.png

第二次WriteProcessMemory往svchost.exe中地址170000的内存写入数据,写入的数据内容在55F214地址上。

BOOL WriteProcessMemory( [in] HANDLE hProcess, [in] LPVOID lpBaseAddress, [in] LPCVOID lpBuffer, [in] SIZE_T nSize, [out] SIZE_T *lpNumberOfBytesWritten );

34.png

执行完后观察svchost.exe 0x170000已写入恶意代码

35.png

通过SetThreadContext设置svchost.exe线程上下文去执行shellcode

BOOL SetThreadContext( [in] HANDLE hThread, [in] const CONTEXT *lpContext );

36.png

恢复svchost.exe线程继续执行,随后dll结束进程。

37.png

Svchost.exe内存代码分析

此时将Svchost.exe附加到xdbg上进行动态调试,并EIP设置180000处的,加载shellcode进行调试

38.png

VirtualAlloc申请内存,eax寄存器为申请的内存地址

39.png

我们可以发现申请的内存为AB0000,其中解密数据放到申请的内存当中

40.png

使用VirtualProtect函数让地址AB0000有可执行的权限。

BOOL VirtualProtect( [in] LPVOID lpAddress, [in] SIZE_T dwSize, [in] DWORD flNewProtect, [out] PDWORD lpflOldProtect );

41.png

通过call eax去执行解密后的shellcode,这里我们单步进入svchost.exe的shellcode

42.png

一直单步直到有call的地方留意下,这里发现似乎在解密请求头

43.png

看到堆栈情况有C&C和请求头,很明显是作为参数去调用跟进去单步查看。

45.png

随后这里选择不跳转

44.png

发现使用到Internetsetoption函数 表明有可能要进行网络连接行为。

46.png

使用InternetOpenA请求C2:185.225.19[.]22,其实如果熟悉Cobalt Strike的就知道这是一个Cobalt Strike的代码

HINTERNET InternetOpenA( [in] LPCSTR lpszAgent, [in] DWORD dwAccessType, [in] LPCSTR lpszProxy, [in] LPCSTR lpszProxyBypass, [in] DWORD dwFlags );

47.png

最后后面拿到C2 通过微步发现该C&C是属于APT海莲花团队

49.png

0x03 总结和反思

我们可以发现这个dll分析起来并不难,关键在于面对shellcode时能否分析出重点功能,而不是误入到每一步的汇编指令,这里分析的shellcode我只比较关注侧重call的部分。其次我们发现这个样本也是有很多特征 比如一些特殊的字符串又或者是某段shellcode 能否作为yara规则去进行跟踪和狩猎。包括能否捕获到未发现以及未来攻击的一些样本,这些都是需要我们去深思的.---EOF

评论

云里雾里

云里雾里,尽在我眼里

twitter weibo github wechat

随机分类

密码学 文章:13 篇
漏洞分析 文章:212 篇
memcache安全 文章:1 篇
APT 文章:6 篇
业务安全 文章:29 篇

扫码关注公众号

WeChat Offical Account QRCode

最新评论

Article_kelp

因为这里的静态目录访功能应该理解为绑定在static路径下的内置路由,你需要用s

N

Nas

师傅您好!_static_url_path那 flag在当前目录下 通过原型链污

Z

zhangy

你好,为什么我也是用windows2016和win10,但是流量是smb3,加密

0

0x0dee

标题写错了,是ASX to MP3 3.1.3.7 - '.m3u' Local

K

k0uaz

foniw师傅提到的setfge当在类的字段名成是age时不会自动调用。因为获取

目录