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生成完成
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY