记详细的Java代码审计
字数 1610 2025-08-07 08:21:57
Java代码审计详细指南
一、过滤器基础
1.1 过滤器简介
Filter(过滤器)是Servlet技术中最实用的技术,WEB开发人员通过Filter技术可以对web服务器管理的所有web资源进行拦截,包括:
- JSP页面
- Servlet
- 静态图片文件
- 静态HTML文件
1.2 过滤器主要功能
- URL级别的权限访问控制
- 过滤敏感词汇
- 压缩响应信息
- 对用户请求进行预处理
- 对HttpServletResponse进行后处理
1.3 过滤器运行原理
- 客户端发送请求时,过滤器可以:
- 改变请求内容
- 重新设置请求协议信息
- 服务器端响应时,过滤器可以:
- 修改响应内容
- 重新设置响应信息
- 多个过滤器可以组成过滤器链,请求在这些过滤器之间传递
二、无框架类代码审计(以jeesns1.3为例)
2.1 审计步骤
- 查找web.xml文件
- 定位XSS过滤代码
<filter>
<filter-name>XssSqlFilter</filter-name>
<filter-class>com.lxinet.jeesns.core.filter.XssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XssSqlFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
2.2 分析XssHttpServletRequestWrapper类
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
// 过滤参数值数组
@Override
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values==null) return null;
String[] encodedValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
// 过滤单个参数
@Override
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
if (value == null) return null;
return cleanXSS(value);
}
// 过滤头部信息
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null) return null;
return cleanXSS(value);
}
// 实际XSS清理方法
private String cleanXSS(String value) {
value = HtmlUtils.htmlEscape(value);
// 需要过滤的脚本事件关键字
String[] eventKeywords = { "onmouseover", "onmouseout", "onmousedown",
"onmouseup", "onmousemove", "onclick", "ondblclick",
"onkeypress", "onkeydown", "onkeyup", "ondragstart",
"onerrorupdate", "onhelp", "onreadystatechange", "onrowenter",
"onrowexit", "onselectstart", "onload", "onunload",
"onbeforeunload", "onblur", "onerror", "onfocus", "onresize",
"onscroll", "oncontextmenu", "alert" };
// 滤除脚本事件代码
for (int i = 0; i < eventKeywords.length; i++) {
value = value.replaceAll("(?i)" + eventKeywords[i],"_" + eventKeywords[i]);
}
return value;
}
}
2.3 漏洞发现
- 过滤不严谨:仅过滤关键字,未使用正则表达式
- 绕过方法:使用
<Script>prompt(/xss/)</Script>可以绕过过滤器
三、框架类代码审计(以Struts2为例)
3.1 框架执行流程
- 请求先经过过滤器(Filter)
- 然后经过拦截器(Interceptor)
- 最后到达Action
3.2 过滤器与拦截器区别
| 特性 | Filter | Interceptor |
|---|---|---|
| 实现方式 | 基于函数回调 | 基于Java反射 |
| 依赖 | Servlet容器 | 不依赖Servlet容器 |
| 作用范围 | 几乎所有请求 | 只能对action起作用 |
| 访问上下文 | 不能访问action上下文 | 可以访问action上下文 |
| 执行顺序 | 先执行 | 后执行 |
3.3 审计步骤
- 获取框架版本信息
- 查找struts.xml配置文件
- 检查拦截器配置
<interceptor name="interceptorName" class="interceptorClass">
<param name="paramName">paramValue</param>
</interceptor>
- 查找包含文件(如struts-default.xml)
- 分析web.xml中的过滤器配置
3.4 漏洞发现与绕过
- 关键发现:当请求中包含特定关键字时,会绕过过滤器和拦截器
- method
- action
- redirect
- redirectAction
- 利用Ognl表达式漏洞:
- 在提交数据前添加上述关键字
- 传入符合Ognl表达式语法的字符串
- Struts2会将其当做Ognl表达式在ValueStack中执行
四、Java代码审计通用思路
4.1 确定框架类型
- 检查web.xml
- 查看导入的jar包或pom.xml
- 分析配置文件:
- Spring: applicationContext.xml
- Hibernate: Hibernate.cfg.xml
- Mybaits: mybatis-config.xml
- Struts2: struts.xml
4.2 检查拦截器
- 查看web.xml文件
- 确定是否配置相关拦截器
4.3 分析流程
- 无框架类:直接分析过滤器代码
- 框架类:
- 熟悉框架执行流程
- 使用断点调试分析
- 关注框架特定关键字和行为
五、总结
- 无框架类审计相对简单,重点关注web.xml和过滤器实现
- 框架类审计需要:
- 理解框架执行流程
- 掌握拦截器配置方式
- 熟悉框架特有漏洞模式
- 通用技巧:
- 使用反编译工具分析jar包
- 善用断点调试
- 关注过滤器和拦截器的绕过方法
六、附录
6.1 常见XSS绕过技巧
- 大小写混合:
<sCript>alert(1)</scRipt> - 使用HTML实体编码
- 利用未过滤的事件属性
- 使用SVG/HTML5新标签
6.2 Ognl表达式漏洞参考
6.3 工具推荐
- JD-GUI:Java反编译工具
- Burp Suite:拦截和修改请求
- IDEA/Eclipse:代码分析和调试