微信公众号:BateSec
为国之安全而奋斗,为信息安全而发声!
如有问题或建议,请在公众号后台留言
如果你觉得本文对你有帮助,欢迎关注本公众号,后期会不定时公布二开细节
特征修改
书接上文,确定了特征位置,开始针对各个特征进行修改
根据以上能得出,需要修改源码的特征为以下几个
1.Beacon Staging特征,去除checksum8特征
2.修改默认端口(从源码中修改teamserver默认端口)
3.破解(附加cs4.5破解方法)
4.javaagent暗桩
修改Stager防止被直接扫描:修改位置如下
cloudstrike/webserver.java
修改
public static boolean isStager(String uri) {
return checksum8(uri) == 92L;
}
public static boolean isStagerX64(String uri) {
return checksum8(uri) == 93L && uri.matches("/[A-Za-z0-9]{4}");
}
修改isStager
函数,只要不是92
或者93
就行。这里首先需要修改checksum8
,将其返回值改为return sum
public static long checksum8(String text) {
if (text.length() < 4) {
return 0L;
} else {
text = text.replace("/", "");
long sum = 0L;
for(int x = 0; x < text.length(); ++x) {
sum += (long)text.charAt(x);
}
return sum % 256L;
}
}
利用脚本计算来生成我们的返回值
public class test {
public static long checksum8(String text) {
if (text.length() < 4) {
return 0L;
} else {
text = text.replace("/", "");
long sum = 0L;
for(int x = 0; x < text.length(); ++x) {
sum += (long)text.charAt(x);
}
return sum ;
}
}
}
public static void main(String []args) {
String key = "随机填写";
long flag = checksum8(key);
System.out.println(flag);
}
}
将计算结果值放入webserver.java
的isStager
方法中替换92L
修改结果
public static boolean isStager(String uri) {
return checksum8(uri) == '计算结果';
}
同时修改return
为我们生成的key
common/CommonUtils.java
修改
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 "上问中的随机填写";
}
上述,x64
同理修改即可
接下来修改
beacon/BeaconPayload.java
将异或值0x2e(46)
改为0x5e
(默认显示为10进制
,我们改为94
即可)
public static byte[] beacon_obfuscate(byte[] var0) {
byte[] var1 = new byte[var0.length];
for(int var2 = 0; var2 < var0.length; ++var2) {
var1[var2] = (byte)(var0[var2] ^ 46("修改此处"));
}
return var1;
}
修改DLL文件
同时我们需要到生成时调用的DLL文件进行修改,否则会导致异或值不一样导致的无法上线,下载解密的问题
使用脚本对Sleeve进行解密,具体原理可以查看CobaltStrike的认证流程
https://github.com/ca3tie1/CrackSleeve
beacon.dll
beacon.x64.dll
dnsb.dll
dnsb.x64.dll
pivot.dll
pivot.x64.dll
利用ida
工具将这些dll中的0x2e
修改为我们之前修改的0x5e
到此修改结束
将修改的java
文件和dll
文件放到我们项目中
利用idea构建工具重新打包即可
修改默认端口(从源码中修改teamserver默认端口)
修改位置
aggressordialogsConnectDialog.java
将其中的port 修改即可
public void show() {
A();
boolean var1 = false;
String var2 = Prefs.getPreferences().getString("connection.last", "New Profile");
JFrame var3 = DialogUtils.dialog("Connect", 640, 480);
var3.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent var1) {
ConnectDialog.this.window.closeConnect();
}
});
this.options = new Navigator();
this.options.addPage("New Profile", (Icon)null, "This is the connect dialog. You should use it to connect to a Cobalt Strike (Aggressor) team server.", (new Connect(this.window)).getContent(var3, "neo", "password", "127.0.0.1", "50050", "[email protected]"));
List var4 = Prefs.getPreferences().getList("connection.profiles");
Iterator var5 = var4.iterator();
while(var5.hasNext()) {
String var6 = (String)var5.next();
String var7 = Prefs.getPreferences().getString("connection.profiles." + var6 + ".user", "neo");
String var8 = Prefs.getPreferences().getString("connection.profiles." + var6 + ".password", "password");
String var9 = Prefs.getPreferences().getString("connection.profiles." + var6 + ".port", "50050");
String var10 = Prefs.getPreferences().getString("connection.profiles." + var6 + ".alias", var7 + "@" + var6);
String var11 = this.window.isConnected(var6) ? "*" : "";
String var12 = var11 + var6 + "!!" + var11 + var10;
this.options.addPage(var12, (Icon)null, "This is the connect dialog. You should use it to connect to a Cobalt Strike (Aggressor) team server.", (new Connect(this.window)).getContent(var3, var7, var8, var6, var9, var10));
if (var2.equals(var6)) {
var1 = true;
var2 = var12;
}
}
this.options.set(var1 ? var2 : "New Profile");
this.options.useAlternateValue(this.useAliasName);
this.viewAliasName = new JButton("Alias Names");
this.viewAliasName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent var1) {
ConnectDialog.this.options.useAlternateValue(true);
ConnectDialog.this.viewAliasName.setFont(ConnectDialog.this.viewAliasName.getFont().deriveFont(1));
ConnectDialog.this.viewHostName.setFont(ConnectDialog.this.viewHostName.getFont().deriveFont(0));
}
});
this.viewHostName = new JButton("Host Names");
this.viewHostName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent var1) {
ConnectDialog.this.options.useAlternateValue(false);
ConnectDialog.this.viewHostName.setFont(ConnectDialog.this.viewHostName.getFont().deriveFont(1));
ConnectDialog.this.viewAliasName.setFont(ConnectDialog.this.viewAliasName.getFont().deriveFont(0));
}
});
var3.add(DialogUtils.center(this.viewAliasName, this.viewHostName), "North");
var3.add(this.options, "Center");
var3.pack();
if (this.useAliasName) {
this.viewAliasName.setFont(this.viewAliasName.getFont().deriveFont(1));
this.viewAliasName.requestFocusInWindow();
} else {
this.viewHostName.setFont(this.viewHostName.getFont().deriveFont(1));
this.viewHostName.requestFocusInWindow();
}
var3.setVisible(true);
}
cs4.5破解
修改
common/Authorization.java
替换Authorization
构造方法
public Authorization() {
byte[] var4 = new byte[]{1, -55, -61, 127, 0, 1, -122, -96, 45, 16, 27, -27, -66, 82, -58, 37, 92, 51, 85, -114, -118, 28, -74, 103, -53, 6, 16, -128, -29, 42, 116, 32, 96, -72, -124, 65, -101, -96, -63, 113, -55, -86, 118, 16, -78, 13, 72, 122, -35, -44, 113, 52, 24, -14, -43, -93, -82, 2, -89, -96, 16, 58, 68, 37, 73, 15, 56, -102, -18, -61, 18, -67, -41, 88, -83, 43, -103, 16, 94, -104, 25, 74, 1, -58, -76, -113, -91, -126, -90, -87, -4, -69, -110, -42, 16, -13, -114, -77, -47, -93, 53, -78, 82, -75, -117, -62, -84, -34, -127, -75, 66, 0, 0, 0, 24, 66, 101, 117, 100, 116, 75, 103, 113, 110, 108, 109, 48, 82, 117, 118, 102, 43, 86, 89, 120, 117, 119, 61, 61};
if (var4.length != 0) {
try {
DataParser var5 = new DataParser(var4);
var5.big();
int var6 = var5.readInt();
this.watermark = var5.readInt();
byte var7 = var5.readByte();
if (var7 < 45) {
this.error = "Authorization file is not for Cobalt Strike 4.5+";
return;
}
byte var8 = var5.readByte();
var5.readBytes(var8);
byte var10 = var5.readByte();
var5.readBytes(var10);
byte var12 = var5.readByte();
var5.readBytes(var12);
byte var14 = var5.readByte();
var5.readBytes(var14);
byte var16 = var5.readByte();
var5.readBytes(var16);
byte var18 = var5.readByte();
byte[] var19 = var5.readBytes(var18);
if (var7 < 45) {
CommonUtils.print_error("Authorization version " + var7 + " does not support watermark hash.");
} else if (!var5.more()) {
CommonUtils.print_error("Authorization data is incomplete. Watermark hash is not available.");
} else {
int var20 = var5.readInt();
if (var20 > 0) {
this.watermarkHash = var5.readString(var20);
}
}
if (29999999 == var6) {
this.validto = "forever";
MudgeSanity.systemDetail("valid to", "perpetual");
} else {
if (!this.A(var6)) {
this.error = "Valid to date (" + var6 + ") is invalid";
return;
}
this.validto = "20" + var6;
MudgeSanity.systemDetail("valid to", CommonUtils.formatDateAny("MMMMM d, YYYY", this.getExpirationDate()));
}
this.valid = true;
MudgeSanity.systemDetail("id", this.watermark + "");
SleevedResource.Setup(var19);
} catch (Exception var13) {
MudgeSanity.logException("auth file parsing", var13, false);
}
}
}
cs4.5 去除javaagent暗桩
全局搜索javaagent
注释掉结束进程即可或者将javaagent判断直接删除(没测试过,需要一个一个修改测试)
欢迎关注
如果你觉得本文对你有帮助,欢迎关注本公众号,后期会不定时公布二开细节
原文始发于微信公众号(BateSec):Cobaltstrike二开系列(三)