分析过程
cs生成分阶段的dll x64位,丢进IDA分析
DllMain函数:
CreateThread启动线程调用sub_6BAC16B0函数 调用sub_6BAC15B2函数 sub_6BAC16B0函数:
将WInMain函数的dll句柄传入到sub_6BAC1605函数执行 sub_6BAC1605函数:
系统启动以来经过的毫秒数*0x26AA 拼接获取管道名 -> .pipeMSSE-%d-server (例如:.pipeMSSE-1234-server)。该管道的格式是有据可查的“钴罢工”危害指标
3.CreateThread启动线程调用调用StartAddress函数StartAddress函数:
调用sub_6BAC1440函数,传入一个指针和nNumberOfBytesToRead变量 sub_6BAC1440函数:
CreateNamedPipeA创建管道 ConnectNamedPipe连接管道 连接成功,WriteFile管道写入shellcode CloseHandle关闭句柄(一旦将shellcode写入管道后,先前通过管道打开的句柄就通过闭合CloseHandle。这表明管道的唯一目的是传输加密的Shellcode) sub_6BAC1512函数:
读取管道里的shell复制到数组 (一旦管道以只读模式打开,该FillBufferFromPipe函数将继续在shellcode上进行复制,直到使用填充分配的缓冲区ReadFile。缓冲区填满后,将关闭命名管道的句柄CloseHandle并FillBufferFromPipe返回TRUE) sub_6BAC176E函数:
使用VirtualAlloc更改内存区域权限(MEM_RESERVE|MEM_COMMIT) 一旦分配了区域,该函数就会在shellcode缓冲区上循环并使用简单的xor操作将每个字节解密到新分配的区域中 调用sub_6BAC1733函数 VirtualProtect更改区域页面权限为PAGE_EXECUTE_READ CreateThread启动线程调用sub_6BAC1730函数 sub_6BAC1733函数:
根据判断确定将GetModuleHandleA、GetProcAddress函数地址写入内存(数组) sub_6BAC1730函数:
shellcode执行 总结:
创建管道写shellcode 从管道读取shellcode复制到数组 更改内存区域权限(MEM_RESERVE|MEM_COMMIT),xor解密shellcode,将GetModuleHandleA、GetProcAddress函数地址写入内存,更改区域页面权限为PAGE_EXECUTE_READ shellcode执行 参考链接:
https://blog.nviso.eu/2021/04/26/anatomy-of-cobalt-strike-dll-stagers
文章来源于:https://422926799.github.io/posts/78291ddc.html
若有侵权请联系删除
加下方wx,拉你一起进群学习
原文始发于微信公众号(红队蓝军):Cobalt Strike的DLL Stager分析