0x00 概述
(一)who
"海莲花"(又名APT32、OceanLotus),被认为是来自越南的APT攻击组织,自2012年活跃以来,一直针对中国大陆的敏感目标进行攻击活动,该组织主要针对工业领域、政府领域、以及与该组织政见不同的个人与记者。该组织被认为拥有越南背景并进行一系列符合越南国家利益的操作。
攻击手法包括投递诱饵钓鱼(office、黑lnk、白加黑等手法)、payload加载(wwlib加载)、绕过安全检测等方面。而从整体攻击方式来看,依然采用电子邮件投递诱饵以及渗透的攻击方式,一旦获得一台机器的控制权后,立即对整个内网进行扫描和平移渗透攻击等。这也进一步说明了APT攻击活动不会因为被曝光而停止或者有所减弱,只要攻击目标存在价值,攻击会越来越猛烈,对抗也会越来越激烈。
(二)What
本次的OceanLotus样本分析,通过VT发现该样本的首次上传时间为2021-06-03 10:55:01 该样本是一个DLL文件,DLL被load加载起来的时候会申请一段内存把资源段上的shellcode代码拷贝到内存中并加载,然后执行shellcode,shellcode会创建一个线程用于服务的自启动,随后会创建svchost.exe进程,往进程里面申请内存并写入恶意代码,通过SetThreadContext设置线程上下文的形式去执行svchost.exe的shellcode,该shellcode为Cobalt Strike最后请求C&C。希望刚入门样本分析的小伙伴们也能跟我一样慢慢一步步调试了解...
0x02 样本分析
(一)样本基础情况
样本类型 | Hash |
---|---|
DLL | edf7dc76776cd05ecf1bc190ae591654 |
通过virustotal可以发现样本的首次上传时间是在2021-06-03 10:55:01
样本可以通过微步去下载
简单的通过pestudio查看下样本的基础信息
(二)逆向分析
加载资源段
通过IDA逆向分析DLL加载后,通过函数FindResource、SizeofResource、LoadResource、LockResource会从资源段中读取数据,通过VirtualAlloc 函数以分配内存的形式把恶意代码拷贝到内存中去执行。最终v6()是执行从资源段上加载的代码
使用studype我们也可以看到资源段的数据,但是在这里看不出什么,后面进行动态调试时候可以观察。
通过xdbg进行动态调试,VirtualAlloc执行后申请的地址返回在eax寄存器上,eax赋值给了edi,最后call edi执行隐藏在资源段上的恶意代码
Create Thread
步入跟进去call edi里面,我们可以发现此时已经在执行资源段上的shellcode
进入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
);
该经过逆向发现线程的功能主要是用于服务启动
shellcode分析
回到主线程里面继续分析,发现shellcode 通过loadLibrary的形式动态加载User32.dll、shell32.dll、paapi.dll、ntdll.dll
通过call edi的形式GetProcAddress获取多个API地址,若获取失败直接跳转到ret
还设置处理异常
通过lstrlenW获取svchost.exe路径的字符串长度
shellcode 第二次LoadLibrary动态加载user.dll等
这一次通过Getprocaddress通过call esi的形式获取API 这里是获取了openprocess的地址,获取失败就ret
创建svchost.exe申请空间并写入恶意代码
通过获取CreateProcess函数来创建svchost.exe
通过函数IsWow64process并且判断进程是32位还是64位
收集获取系统信息
第三次LoadLibrary,继续通过call esi执行GetProcAddress获取API,获取失败就Ret
使用HANDLE 通过GetProcessID函数获取进程ID,GetProcess的返回值是 0x1b98转成10进制是7064,表明创建的进程ID是7064
DWORD GetProcessId(
[in] HANDLE Process
);
我们通过使用工具火绒剑发现进程ID7064是svchost.exe程序
随后样本通过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
);
使用火绒剑工具观察svchost.exe的内存空间
VirtualAllocEx的第一参数是hprocess,此处是svchost.exe的进程句柄,第二次也是在svchost.exe中申请内存空间。并具有读写执行的权限。函数返回值是180000
再次观察svchost.exe在内存中的地址空间。
随后通过WriteProcessMemory函数往svchost.exe中地址180000的内存写入数据,写入的数据内容在22291DB地址上。
BOOL WriteProcessMemory(
[in] HANDLE hProcess,
[in] LPVOID lpBaseAddress,
[in] LPCVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesWritten
);
此时在火绒剑上通过观察发现shellcode已经写入了svchost.exe中
通过使用CreateToolHelp32Snapshot获取进程的快照并通过Thread32First和Thread32Next遍历线程
OpenThread打开线程ID是0x1b40对应是svchost的线程ID 6976
使用SuspendThread函数挂起线程
DWORD SuspendThread(
[in] HANDLE hThread
);
GetThreadContext保存线程的上下文
BOOL GetThreadContext(
[in] HANDLE hThread,
[in, out] LPCONTEXT lpContext
);
第二次WriteProcessMemory往svchost.exe中地址170000的内存写入数据,写入的数据内容在55F214地址上。
BOOL WriteProcessMemory(
[in] HANDLE hProcess,
[in] LPVOID lpBaseAddress,
[in] LPCVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesWritten
);
执行完后观察svchost.exe 0x170000已写入恶意代码
通过SetThreadContext设置svchost.exe线程上下文去执行shellcode
BOOL SetThreadContext(
[in] HANDLE hThread,
[in] const CONTEXT *lpContext
);
恢复svchost.exe线程继续执行,随后dll结束进程。
Svchost.exe内存代码分析
此时将Svchost.exe附加到xdbg上进行动态调试,并EIP设置180000处的,加载shellcode进行调试
VirtualAlloc申请内存,eax寄存器为申请的内存地址
我们可以发现申请的内存为AB0000,其中解密数据放到申请的内存当中
使用VirtualProtect函数让地址AB0000有可执行的权限。
BOOL VirtualProtect(
[in] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flNewProtect,
[out] PDWORD lpflOldProtect
);
通过call eax去执行解密后的shellcode,这里我们单步进入svchost.exe的shellcode
一直单步直到有call的地方留意下,这里发现似乎在解密请求头
看到堆栈情况有C&C和请求头,很明显是作为参数去调用跟进去单步查看。
随后这里选择不跳转
发现使用到Internetsetoption函数 表明有可能要进行网络连接行为。
使用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
);
最后后面拿到C2 通过微步发现该C&C是属于APT海莲花团队
0x03 总结和反思
我们可以发现这个dll分析起来并不难,关键在于面对shellcode时能否分析出重点功能,而不是误入到每一步的汇编指令,这里分析的shellcode我只比较关注侧重call的部分。其次我们发现这个样本也是有很多特征 比如一些特殊的字符串又或者是某段shellcode 能否作为yara规则去进行跟踪和狩猎。包括能否捕获到未发现以及未来攻击的一些样本,这些都是需要我们去深思的.---EOF