Cobalt Strike的DLL Stager分析
2023-5-19 15:2:41 Author: 红队蓝军(查看原文) 阅读量:16 收藏

分析过程

cs生成分阶段的dll x64位,丢进IDA分析

DllMain函数:

  1. CreateThread启动线程调用sub_6BAC16B0函数
  2. 调用sub_6BAC15B2函数

sub_6BAC16B0函数:

  1. 将WInMain函数的dll句柄传入到sub_6BAC1605函数执行

sub_6BAC1605函数:

  1. 系统启动以来经过的毫秒数*0x26AA
  2. 拼接获取管道名 -> .\pipe\MSSE-%d-server (例如:.\pipe\MSSE-1234-server)。该管道的格式是有据可查的“钴罢工”危害指标
    3.CreateThread启动线程调用调用StartAddress函数

StartAddress函数:

  1. 调用sub_6BAC1440函数,传入一个指针和nNumberOfBytesToRead变量

sub_6BAC1440函数:

  1. CreateNamedPipeA创建管道
  2. ConnectNamedPipe连接管道
  3. 连接成功,WriteFile管道写入shellcode
  4. CloseHandle关闭句柄(一旦将shellcode写入管道后,先前通过管道打开的句柄就通过闭合CloseHandle。这表明管道的唯一目的是传输加密的Shellcode)

sub_6BAC1512函数:

  1. 读取管道里的shell复制到数组 (一旦管道以只读模式打开,该FillBufferFromPipe函数将继续在shellcode上进行复制,直到使用填充分配的缓冲区ReadFile。缓冲区填满后,将关闭命名管道的句柄CloseHandle并FillBufferFromPipe返回TRUE)

sub_6BAC176E函数:

  1. 使用VirtualAlloc更改内存区域权限(MEM_RESERVE|MEM_COMMIT)
  2. 一旦分配了区域,该函数就会在shellcode缓冲区上循环并使用简单的xor操作将每个字节解密到新分配的区域中
  3. 调用sub_6BAC1733函数
  4. VirtualProtect更改区域页面权限为PAGE_EXECUTE_READ
  5. CreateThread启动线程调用sub_6BAC1730函数

sub_6BAC1733函数:

  1. 根据判断确定将GetModuleHandleA、GetProcAddress函数地址写入内存(数组)

sub_6BAC1730函数:

  1. shellcode执行

总结:

  1. 创建管道写shellcode
  2. 从管道读取shellcode复制到数组
  3. 更改内存区域权限(MEM_RESERVE|MEM_COMMIT),xor解密shellcode,将GetModuleHandleA、GetProcAddress函数地址写入内存,更改区域页面权限为PAGE_EXECUTE_READ
  4. shellcode执行

参考链接:

https://blog.nviso.eu/2021/04/26/anatomy-of-cobalt-strike-dll-stagers

https://422926799.github.io/posts/78291ddc.html

wx


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