CobaltStrike Charset Improvement
字数 1635 2025-08-29 08:31:54
CobaltStrike 字符集编码改进技术文档
0x01 场景概述
在使用CobaltStrike时,配合第三方工具(如带web探测功能的工具)时,获取到的webtitle或其他内容通过beacon console回显时,经常出现乱码问题。主要原因:
- 第三方工具获取的webtitle通常是UTF-8编码格式
- 包含中文内容时尤其明显
- 在简体中文Windows系统上测试发现:
- GB2312编码文件显示正常
- UTF-8编码文件显示乱码
根本原因:编码不统一导致的问题。
0x02 编码定位与调试环境搭建
反编译环境准备
-
使用IDEA自带的反编译插件java-decompiler.jar:
java -cp java-decompiler.jar org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -dgs=true cs_bin/cobaltstrike.jar cs_src/ -
构建二次开发环境:
- 基于反编译得到的源代码
- 使用原始cobaltstrike.jar
- 采用增量修改方式
调试环境配置
Server端配置:
- Main class:
server.TeamServer - VM options:
-XX:ParallelGCThreads=4 -Dcobaltstrike.server_port=50050 -Djavax.net.ssl.keyStore=./cobaltstrike.store -Djavax.net.ssl.keyStorePassword=123456 -server -XX:+AggressiveHeap -XX:+UseParallelGC -classpath ./cobaltstrike.jar server.TeamServer $* - Program arguments:
172.16.119.1 123456(示例)
Client端配置:
- VM options:
-Dfile.encoding=UTF-8 -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC
编码处理流程分析
- Client与Server交互时,metadata携带系统编码信息
- 处理流程:
beacon.BeaconC2.process_beacon_metadata()- 调用
common.WindowsCharsets.getName()解析编码类型 WindowsCharsets.getName()通过switch-case维护编码解析对应表- 实例化
BeaconEntry并将编码类型赋值给beaconEntry.chst - 通过
this.getCharsets().register(beaconEntry.getId(), var9, var10)注册编码信息
关键代码:
public void register(Map map, String var2, String var3) {
if (var3 != null) {
try {
Charset var4 = Charset.forName(var3);
synchronized (this) {
map.put(var2, var4);
}
} catch (Exception var8) {
MudgeSanity.logException("Could not find charset '" + var3 + "' for Beacon ID " + var2, var8, false);
}
}
}
测试验证:强制修改注册编码类型为UTF-8可使UTF-8内容正常显示,但GB2312内容变为乱码。
0x03 功能实现方案
设计思路
仿造Note功能实现动态修改编码功能,包含两部分:
- beacon console命令
- GUI界面选项
代码实现
Client端处理:
beacon.TaskBeacon.Note()处理note xxx指令aggressor.windows.BeaconConsole首次处理请求- 最终通过
common.TeamQueue.run()发送指令到teamserver
Server端处理:
server.Beacons.buildBeaconModel()处理接收的指令- 使用
this.notes维护beaconId和note的键值对 - 通过广播机制更新状态
GUI实现代码(添加到default.cna):
item "Setchar" {
$bid = $1;
$dialog = dialog("Setchar", %(charsets => ""), &Setchar);
dialog_description($dialog, "Set the Beacon's Charset ");
drow_combobox($dialog, "charsets", "charset:", @("", "UTF-8", "GBK", "GB2312", "GB18030", "ISO-8859-1", "BIG5", "UTF-16", "UTF-16LE", "UTF-16BE"));
dbutton_action($dialog, "Setchar");
dialog_show($dialog);
}
sub Setchar {
binput($bid, "setchar $3['charsets']");
beacon_setchar($bid, $3['charsets']);
}
支持编码类型:
- UTF-8
- GBK
- GB2312
- GB18030
- ISO-8859-1
- BIG5
- UTF-16
- UTF-16LE
- UTF-16BE
0x04 使用效果
Console命令使用
添加setchar命令:
Use: setchar [text]
e.g: setchar utf-8 | setchar
set a charset to this Beacon.
GUI界面使用
- 通过图形菜单设置编码
- 可选择9种编码格式
- 选择空值将重置为初始编码
0x05 技术总结
- 通过分析CobaltStrike的编码处理流程定位问题
- 借鉴Note功能的实现方式
- 采用增量修改方式保持代码稳定性
- 提供Console和GUI两种操作方式
- 支持多种常见编码格式切换
附录:完整实现要点
- 编码注册机制:修改
beacon.BeaconCharsets.register()方法 - 命令处理:仿照
Note命令实现setchar命令处理 - 状态维护:在Server端维护编码状态
- GUI集成:通过default.cna添加图形界面
- 广播机制:确保编码更改能实时生效
通过此改进,可有效解决CobaltStrike中因编码不一致导致的乱码问题,提升工具在多种语言环境下的可用性。