-
Stager:分阶段式上线,从teamserver下载真正的payload后执行,体积小
-
Stageless:不分阶段上线,真正的payload直接在其中,适合用于红队测试中的免杀制作,体积大
Stager Exe Payload分析
软件版本:Teamserver 4.9.1
Payloads->Windows Stager Payload,具体配置如下
IDA 分析
入口点位于:4014C0
sub_401990
利用时间等信息异或获得两个随机数:randomA_4044D0
和randomB_4044E0
,且二者&
为0xFFFFFFFFFFFF
sub_401180
一些初始化的操作,和主要功能关系不大
sub_403040
真正释放payload的地方
sub_4017F8
这里模仿了windows中的管道的命名方式,并在后续的sub_4016E6
创建该管道
sub_4016E6 -> sub_401630
创建了命名管道后写入一些内容后关闭管道
查看调用发现向管道写入 lpBuffer_
的0x37D
字节
shift+e先保存lpBuffer_
方便后续分析
sub_4017A6
在创建线程命名管道写入过后进入该函数
-
sub_401704
从命名管道读取
0x37D
到申请的lpBuffer
-
sub_401595
经典的运行shellcode片段,调用如下
sub_401595(lpBuffer, nNumberOfBytesToWrite, &unk_404028);
。对刚才从管道中读出的数据进行了异或来还原,异或的key为unk_404028
编写还原脚本
if__name__=='__main__':cipher=b""keys= [0xC2, 0xF0, 0xA1]withopen("lpBuffer_.bin","rb") assrcFile:cipher=srcFile.read()withopen("decrypted_shellcode.bin","wb") asdstFile:counter=0forcincipher:dstFile.write((c^keys[counter%3]).to_bytes(1,'little'))counter+=1
唯一一个需要注意的地方就是C语言是固定数据类型的,所以使用&
可以达到和%
一样的效果,只不过&3
等效于%4
。python中的数据是不固定的,所以使用&可能由于数据长度导致数字错误从而index out of range
到这里观察我们还原出来的shellcode
如果我们对于相同的payload和listener生成shellcode(这里我用了一个youtube的beacon file)
发现惊人的相似,主要不同
得出结论:CobaltStrike 的 Stager Excute生成的artifact.exe实际上是在运行Stager Shellcode
sub_401563
比shellcode好多了的是这种payload会使用exe提供的GetModuleHandleA
和GetProcAddress
,从而避免了从LDR中遍历的冗余
Stager Shellcode Payload分析
将刚才还原的decrypted_shellcode.bin
放到ida中分析汇编(64位)
最开始IDA会将这段识别为数据,可以直接右键
可以创建为一个函数,便于分析
汇编逐行分析的话确实有点冗长
第一阶段:找到相关函数并加载
这里使用循环Ldr和异或比较得到关键值
一般来说对应的C代码长这样
-
找到loadlibrary
-
加载wininet加载相关函数,如果想知道传入的参数,直接按照传参顺序看寄存器即可(一般是stdcall)方式。在4.9版本中可以选择使用其他windows的http的库
估计从这里开始准备接收第二阶段payload然后运行
这里每次读取0x2000大小知道读完,传输了一个dll文件过来
第二阶段:反射式加载payload,这里运行的shellcode就是teamserver分发过来的了
相关函数地址保存在栈上,让后调用,这段反射式加载dll的shellcode具体可见:Cobaltstrike4.0 —— shellcode分析 https://forum.butian.net/share/2017
算了,不管了,端午开玩
原文始发于微信公众号(不止Sec):【免杀】Cobaltstrike Stager Payload分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论