一种基于规则的 JavaWeb 回显方案
字数 1136 2025-08-10 19:49:11
JavaWeb 回显技术研究与实现
背景与概述
JavaWeb 回显技术是漏洞检测和利用中的关键技术。相比反连检测(需要目标服务器主动连接外部监听服务器),回显技术具有以下优势:
- 不受网络环境影响(内网或网络差的环境也能使用)
- 避免因网络问题导致的漏报
回显原理
底层机制
Java 处理 HTTP 请求的流程:
- 基于 Socket 通信
- Java 通过 JNI 调用系统 API 读写 Socket
- 每个 TCP 连接对应一个文件描述符和 Socket 对象
两种实现方式
-
Socket 层回显:
- 优点:通用性强
- 缺点:需要通过 IP 和端口区分请求,网络经过转发时可能无法获取真实源 IP
-
Servlet 层回显:
- 通过 HttpServletResponse 对象实现
- 难点:如何快速定位当前请求的 HttpServletResponse 对象
对象查找技术
1. 暴力查找
实现原理:
- 从线程对象开始递归查找字段和类静态成员
- 使用树结构存储查找路径
核心代码实现:
public class Searcher1 {
public Node SearchResponse(Object o) {
Node root = new Node(String.format("(%s)%s",o.getClass().getName(),"currentThread"),o);
if (searchResponse(o,root,new HashSet<Object>(),0)){
return root;
}else {
return null;
}
}
boolean searchResponse(Object o, Node node, Set searched, int deep) {
if (o instanceof HttpServletResponse){
return true;
}
// 递归查找逻辑...
}
}
优缺点:
- 优点:通用性强,成功率100%
- 缺点:性能开销大,响应慢,可能丢失请求
2. 模糊查找
优化思路:
- 根据已知路径特征进行剪枝
- 特征包括:线程表结构、类名/属性名含"Response"等
实现要点:
public SearchResult findObjectByFeature(Object o, Pattern[] features,List trace,
HashSet<Object> searched,int n,int maxSingleFeatureDeep,int deep,int maxTotalDeep) {
// 根据特征优先搜索可疑目标
if (features.length != 0 && features[0].matcher(fieldObj.getClass().getName()).find()) {
nextTargets.add(fieldObj);
}
// ...
}
3. 精确查找(基于规则)
实现步骤:
- 通过调试或工具获取特定框架/中间件的Response对象路径
- 将路径转化为查找规则
- 根据规则精确查找
规则示例:
String[] rules = {
"workEntry,response", // Tomcat规则
"threadLocals,table|value_response,response" // WebLogic规则
};
实现代码:
public static Object getTargetByRouteFeatures(Object o,String[] features) throws Exception {
for (String feature: features) {
String[] split = feature.split(",");
o = getField(o,split[0]);
// 递归查找逻辑...
if (o instanceof HttpServletResponse){
return o;
}
}
return null;
}
请求筛选技术
问题:如何确保回显到正确的请求?
解决方案:
- 大多数Servlet容器(Tomcat、WebLogic等)在Response实现类中保存了Request引用
- 通过Request中的特定标记(如Header)识别当前请求
实现代码:
Field req = rsp.getClass().getDeclaredField("request");
req.setAccessible(true);
Object o = req.get(rsp);
if (o instanceof HttpServletRequest){
if (((HttpServletRequest)o).getHeader("tag").equals("1")){
// 这是我们的请求,进行回显
}
}
路径图生成技术
用于辅助规则编写:
- 生成对象引用关系的dot脚本
- 可视化展示查找路径
实现代码:
public class searchShell {
void toDot(PrintWriter out) {
out.printf(" \"%s\"", hash);
out.printf(" [label=\"%s\"]", name);
out.println(";");
// 递归输出子节点...
}
public String dump() {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
PrintWriter out = new PrintWriter(new OutputStreamWriter(byteStream));
out.println("digraph G {");
toDot(out);
out.println("}");
out.close();
return byteStream.toString();
}
}
实际应用示例
完整回显Payload示例:
public class multiEcho {
public static void main(String[] args) throws Exception {
String[] rules = {"workEntry,response","threadLocals,table|value_response,response"};
for (String rule : rules) {
try {
HttpServletResponse rsp = (HttpServletResponse) getTargetByRouteFeatures(
Thread.currentThread(), rule.split(","));
// 验证请求并回显
Field req = rsp.getClass().getDeclaredField("request");
req.setAccessible(true);
Object o = req.get(rsp);
if (o instanceof HttpServletRequest) {
if (((HttpServletRequest)o).getHeader("tag") != null) {
rsp.getWriter().write("Echo Success!");
}
}
} catch (Exception e) {
// 忽略错误继续尝试下一条规则
}
}
}
}
技术对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 暴力查找 | 100%成功 | 性能差 | 通用Payload |
| 模糊查找 | 性能较好 | 可能漏报 | 已知部分特征的环境 |
| 精确查找 | 性能最好 | 需要规则 | 特定中间件/框架 |
最佳实践建议
- 优先使用基于规则的精确查找
- 新环境先使用暴力查找生成路径图
- 从路径图中提取最短路径作为新规则
- 多规则组合提高兼容性
- 通过请求标记确保回显到正确请求
扩展思考
- 处理Map等特殊数据结构
- 优化多请求并发时的查找策略
- 支持更多中间件/框架的规则
- 内存占用和性能优化
- 对抗防护措施的绕过技术