Brute Ratel C4红队框架和EDR的猫鼠游戏(上)
2022-9-19 12:32:21 Author: 红队蓝军(查看原文) 阅读量:37 收藏

名称: Roshan_CV.iso
大小: 4839424 字节 (4726 KiB)
MD5: a7df3462a6dce565064cfe408557c4df
SHA1: 6b91bfc761fe958c8ac04dd403db284ccc3a530e
SHA256: 1fc7b0e1054d54ce8f1de0cc95976081c7a85c7926c03172a3ddaa672690042c

名称: OneDrive.Update
大小: 277064 字节 (270 KiB)
MD5: d6eae771c6cb12e17028fa35e4fba295
SHA1: 70767d3f7ff7736063ee76c0d9c0e90ce895332b
SHA256: b5d1d3c1aec2f2ef06e7d0b7996bc45df4744934bd66266a6ebb02d70e35236e

名称: OneDriveUpdater.exe
大小: 4200864 字节 (4102 KiB)
MD5: 792e95b64b9cf45ac8bc10d4d0f077c2
SHA1: e50af7ee7e0a323d8aa60b6d9b3d39ab33b004f5
SHA256: 60e64dd2c6d2ac6fe9b498fadac81bc34a725de5d893e7df8b2728d8dc5b192d

名称: version.dll
大小: 259584 字节 (253 KiB)
MD5: 76fa734236daa023444dec26863401dc
SHA1: a68a1b7ca1d1ddd005fd10382bf6cd0b86e74e86
SHA256: ea2876e9175410b6f6719f80ee44b9553960758c7d0f7bed73c0fe9a78d8e669

名称: vresion.dll
大小: 31496 字节 (30 KiB)
MD5: 17c1e1099b65051bb6dec71fea37315b
SHA1: 8ed26469afbd53da7749ef9c6ab8c7f010e9bb1e
SHA256: e549d528fee40208df2dd911c2d96b29d02df7bef9b30c93285f4a2f3e1ad5b0

名称: Roshan-Bandara_CV_Dialog
大小: 3149 字节 (3.07 KiB)
MD5: 82eb32d941b6dd63957a37453c9b0333
SHA1: f27a374044c73a6a5b2d926bb9468daf570b8bfc
SHA256: 4466017fd40c4b5fa9923928b7be3acf03825b4dd8c5fcf088992aee398b8c2d

恶意样本是个iso文件,双击挂载iso,一共有5个文件,除了Roshan-Bandara_CV_Dialog这个快捷方式之外其他的文件都是隐藏文件(我开启了显示隐藏文件所以这里全部显示了)

我们查看Roshan-Bandara_CV_Dialog快捷方式指向的目标%windir%/system32/cmd.exe /c start OneDriveUpdater.exe,主要就是调用cmd命令执行了隐藏文件OneDriveUpdater.exe,cmd.exe /c命令指定执行完后会自动关闭控制台窗口

我们接着看这个快捷方式的图标文件,发现其图标文件指向%ProgramFiles%\Microsoft Office\root\Office16\WINWORD.EXE,由于本机没有装Office 2016所以此快捷方式的图标就无法显示,由此可见此次攻击样本十分有针对性

其中的vresion.dll和OneDriveUpdater.exe为白文件都有Microsoft的有效数字签名

其中的version.dll链接器版本14.29是使用1929 (Visual Studio 2019 Version 16.10 + 16.11)编译的64位DLL,可以看到编译时间戳为2022-5-17 16:35:50

version.dll和vresion.dll的导出函数完全相同

OneDrive.Update是一个被加密的二进制文件,猜测可能是shellcode或者pe文件

使用ida64打开OneDriveUpdater.exe分析,我们可以看到OneDriveUpdater.exe一共调用了version.dll中的3个导出函数

接下来我们使用ida64分析version.dll,查看version.dll的导出函数时发现并没有相关的实现,而是使用了导出函数转发技术将函数转发到白文件vresion.dll的实现

stage0:version.dll代码分析

接下来我们分析version.dll的DllMain函数,只调用了一个sub_180002090函数

sub_180002090函数使用了WTSEnumerateProcessesA函数枚举进程

循环查找RuntimeBroker.exe进程

读取加密文件OneDrive.Update到内存

控制台窗口打印字符串"Please wait..."

先调用了NtDelayExecution函数休眠了几秒,接着调用NtOpenProcess函数以PROCESS_ALLACCESS权限打开RuntimeBroker.exe进程

此样本的NtOpenProcess函数实现,这些汇编代码特征让我想到了SysWhispers3项目

这是我使用SysWhispers3项目生成的NtOpenProcesss的syscall调用,发现除了SysWhispers3使用函数Hash方式之外汇编代码特征完全一致,可以判断此样本使用了SysWhispers3项目

接下来我们详细分析下首先SW3_GetSyscallEGG_180001D20函数参数为ntop

主要逻辑是通过gs:[60]获取PEB,然后通过偏移找到PEB->Ldr->InMemoryOrderModuleList链表,并通过访问LDR_DATA_TABLE_ENTRY->FullDllName字段使用_stricmp函数判断找到ntdll.dll

接下来通过解析ntdll.dll的PE结构获取导出函数

第一个导出函数名称

memcmp函数对比直到找到导出函数NtOpenProcess

最终获取到导出函数地址

接下来通过搜索函数NtOpenProcess的OPCODE特征找到syscall(0F05)的地址(EGG)

接下来分析SW3_GetSyscallNumber_180002000函数,主要逻辑还是通过OPCODE特征搜索找到syscall id,关于syscall id对应的函数在不同windows版本下不同可以在j00ru的博客查询

此时RAX为NtOpenProcess函数的syscall id:26,r15为syscall的地址

通过syscall调用NtOpenProcess函数

接下来使用硬编码的xor密钥jikoewarfkmzsdlhfnuiwaejrpaw解密OneDrive.Update,解密大小为0x493E0

调用了NtCreateSection函数创建0x493E0大小的PAGE_EXECUTE_READWRITE内存权限,SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE访问属性的section

接着调用NtMapViewOfSection函数将section映射到本进程虚拟内存

并调用NtMapViewOfSection函数将section映射到RuntimeBroker.exe进程虚拟内存

使用memmove函数将解密后的shellcode复制到本进程section共享内存空间,此时section内存会同步映射到远程进程RuntimeBroker.exe进程虚拟内存

然后调用NtCreateThreadEx函数在RuntimeBroker.exe进程中创建远程线程执行注入的shellcode

我们使用processhack工具查看RuntimeBroker.exe进程内存可以看到shellcode已经注入成功

stage1:OneDrive.Update代码分析

为了方便调试我将stage0解密后的shellcode从内存中dump下来并使用自写的shellcode loader加载调试分析,shellcode开头有巨量的movpush执行的组合,通过压入栈中的数据可以判断大致是在初始化数据和函数调用要用到的参数等等
在偏移0x43750处才开始主要逻辑
可以看到刚刚压入栈中的众多数据包含了一个PE文件并且此PE文件的Dos头的MZSignature(0x5A4D)被抹除防止EDR进行内存扫描查杀,通过访问0x3C位置AddressOfNewExeHeader开始解析此PE文件
最终获取导出函数的RVA:0x92E0
接下来的逻辑还是熟悉的通过PEB-Ldr->InMemoryOrderModuleList获取ntdll.dll的基址
然后调用FindHashFunAddress_5137AE函数通过函数Hash获取对应函数的地址
通过解析ntdll.dll的PE结构获取导出函数名称表
并对导出函数名进行ror13 Hash然后对比目标函数Hash直到找到需要的函数

获取到需要的导出函数地址后会调用CheckFuninlineHook_51375B函数进行检查
首先检查函数头是否被下了int3软件断点(0xCC),然后通过检测OPCODE编码E9(jmp)判断函数是否被EDR给inlineHook,如果函数正常则通过偏移获取函数的syscall id
接着将参数压栈,通过syscall调用ZwAllocateVirtualMemory申请PAGE_READWRITE权限的内存
接着又申请了一块内存PAGE_READWRITE权限的内存
申请完内存后调用了CopyPeToAllocAddress_513815函数
此函数将栈中的PE文件(0x3240)大小的内容以每次QWORD大小复制到申请的虚拟内存中
PE文件复制完成
接着调用 MemSetPeMemoryFeatures_513805函数将内存中PE文件Dos头除了AddressOfNewExeHeader字段以外的内存置0,防止EDR扫描内存查杀
又调用了MemSetPeMemoryFeatures_513805函数将内存中PE文件DosStub部分的内存置0
接着调用CopyBase64ToAllocAddress_513820函数
将0x148字节大小的Base64编码数据复制到申请的第二块虚拟内存中
复制完内存后还是通过调用FindHashFunAddress_5137AE函数通过函数Hash获取ZwProtectVirtualMemory函数地址
调用ZwProtectVirtualMemory将存放PE文件那块内存属性改为PAGE_EXECUTE_READ属性
获取了ZwCreateThreadEx的syscall id
调用ZwCreateThreadEx执行的函数为函数开头获取的导出函数
调用ZwWaitForSingleObject函数等待线程执行完毕文章来源于:https://www.freebuf.com/articles/system/341336.html

若有侵权请联系删除
加下方wx,拉你一起进群学习

往期推荐

关于利用rundll32执行程序的分析

什么?Windows defender 竟如此脆弱?

最新办法绕过360核晶添加计划任务

什么?你还不会webshell免杀?(七)

一款域信息收集神器

最新绕过360添加用户 | 红队蓝军祝您双节快乐

域内批量获取敏感文件

什么?你还不会webshell免杀?(六)



文章来源: http://mp.weixin.qq.com/s?__biz=Mzg2NDY2MTQ1OQ==&mid=2247503074&idx=1&sn=510a935e4d9bb1be8485781c0bb2e736&chksm=ce67765ef910ff48e2667fb1a7cd73a98dd9c1ea342a5b7faf7d34e23505d381d3495ad3691c#rd
如有侵权请联系:admin#unsafe.sh