cobalt strike https stage 生成分析

前言:cobalt strike https stage 生成分析笔记,这里主要学习cs如何进行构造payload

分阶段stage payload生成

这里的话主要分析就是客户端中的aggressor.dialogs.WindowsExecutableStageDialog#dialogAction

如上图所示点击generate,这个部分主要就是在窗口上进行选择相关的选项,然后进行生成的入口点

获取相关的payload的系统位数和对应的listener,然后调用getPayloadStager

boolean var3 = DialogUtils.bool(var2, "x64");
String var4 = DialogUtils.string(var2, "listener");
this.stager = ListenerUtils.getListener(this.client, var4).getPayloadStager(var3 ? "x64" : "x86");

getPayloadStager中先调用了getPayload,获取通信的类型,我这里选择的是https

接着就是走到stagers.Stagers#shellcode方法中,这里会通过stagers.Stagers#resolve方法,该方法会根据对应的listener和系统位数获得一个GenericStager对象来进行使用

接着就是通过stagers.GenericStager#generate

  • 首先通过CommonUtils.resource(this.getStagerFile());拿到对应的stage文件的样本,我这里生成的是resources/httpsstager.bin
public String getStagerFile() {
return "resources/httpsstager.bin";
}

如果你将resources/httpsstager.bin文件拖入到hex编辑器中,你会发现展示如下图所示

  • CommonUtils.readAll(var1); 得到对应的字节流

  • CommonUtils.bString(var2); 对上面读取的字节流进行ISO8859-1字符编码转换

  • var3 = var3 + this.getListener().getStagerHost() + '\u0000'; 在末尾继续拼接通信的Host字段

  • 将Packer存储小端格式的端口号替换到指定端口判断,其中还会进行判断对应的getPortOffset()偏移值的位置是不是4444(十六进制0x115C),可以匹配到

  • 同样的效果,一样是判断结束偏移 getExitOffset 这里对应的十进制745 十六进制就是0x2E9

  • 后面也是同样的继续填充getSkipOffset isSSL ,接着就是填充header头,将其中的XXXXX字符串全部进行替换header头部分

  • 将YYYYY字段替换为要远程请求加载的地址,其中地址生成的函数是this.getURI()

this.getURI() 这个函数继续跟进去可以发现最后通过该common.CommonUtils#MSFURI方法来随机生成4个字符的请求接口名称

public static String MSFURI(int var0) {
String[] var1 = toArray("a, b, c, d, e, f, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9");
StringBuffer var2;
do {
var2 = new StringBuffer(var0 + 1);
var2.append("/");
for(int var3 = 0; var3 < var0; ++var3) {
var2.append(pick(var1));
}
} while(checksum8(var2.toString()) != 92L);
return var2.toString();
}

比较有意思的就是生成四个字符的时候,还会调用checksum8(var2.toString()) != 92L)方法,让四个字符的ASCII码相加,并且还需要mod 256需要等于92,否则就重新生成

最终生成完成之后就进行saveFile操作,保存的就是shellcode的payload

接着进入到保存shellcode的阶段aggressor.dialogs.WindowsExecutableDialog#dialogResult

因为生成的是exe格式,所以走的是common.BaseArtifactUtils#patchArtifact

可以看到继续给common.BaseArtifactUtils#patchArtifact方法继续给上面生成的字节打补丁patch

common.BaseArtifactUtils#_patchArtifact方法中通过生成四个rand(254)字符,然后对shellcode的数组进行异或加密

上面异或加密完之后又开始生成了一个Packer对象,写入了shellcode的长度以及异或的4个字符用于后面进行解密操作,其中var9+16不知道作用是什么

Packer var10 = new Packer();
var10.little();
var10.addInteger(var9 + 16);
var10.addInteger(shellcode.length);
var10.addString(var6, var6.length);

通过ida可以发现存在异或还原片段,如下所示,四个字节一一对应

后面的话就是修复PE文件中的校验和字段,到这里payload生成完成

posted @   zpchcbd  阅读(301)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示