深入学习Java代码审计技巧—详细剖析某erp漏洞
字数 2246 2025-08-10 08:28:52

Java代码审计技巧与ERP系统漏洞深度剖析

1. 审计准备工作

1.1 项目结构分析

  • src/main/java:存放核心Java代码,包含controller、service、filter、dao等
  • src/main/resources:包含mybatis配置文件、properties等
  • erp_web:存放网站的html、css及js文件
  • docs:数据库文件及文档文件
  • test:项目测试目录
  • pom.xml:项目依赖配置

1.2 环境搭建

  1. 数据库创建:
mysql -u root -h 127.0.0.1 -p
create database jsh_erp;
use jsh_erp;
source /path/to/jsh_erp.sql
  1. 项目启动:
  • 配置application.properties中的数据库连接信息
  • 启动主类ErpApplication.java

2. 配置文件审计

2.1 关键配置文件

  • application.properties:Spring全局配置,包含server IP/port和数据库连接信息
  • pom.xml:组件依赖配置,重点检查已知漏洞组件

2.2 组件漏洞分析

Fastjson反序列化漏洞

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.55</version>
</dependency>
  • 1.2.55版本存在反序列化漏洞
  • 审计点:全局搜索parseObject方法

漏洞利用链:

  1. StringUtil.getInfo()调用JSONObject.parseObject()
  2. UserComponent.getUserList()调用StringUtil.getInfo()
  3. ResourceController.getList()最终调用UserComponent.getUserList()

测试Payload:

{"@type":"java.net.Inet4Address","val":"xxxxxx"}

Log4j漏洞

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-to-slf4j</artifactId>
    <version>2.10.0</version>
</dependency>
  • 2.10.0版本无相关漏洞

3. Filter分析

3.1 LogCostFilter分析

public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {
    // 具体过滤逻辑
}

免登录访问条件:

  1. URL包含/doc.html/register.html/login.html
  2. URL包含.css.js.jpg.png.gif.ico
  3. URL以/user/login/user/registerUser/v2/api-docs开头

4. 路由分析

4.1 特殊路由处理

  • ResourceController处理包含{apiName}的路径
  • 通过CommonQueryManagerComponent类进行路由分发

5. SQL注入漏洞

5.1 审计关键点

  • 关注createQuery()createSQLQuery()createNativeQuery()
  • 检查SQL语句是否直接拼接参数
  • MyBatis中搜索${}使用情况
  • JPA检查JpaSort.unsafe()使用

5.2 注入点1:用户查询

漏洞位置:UserMapperEx.xml

<select id="countsByUser" resultType="java.lang.Long">
    select count(user.id)
    FROM jsh_user user
    where 1=1
    <if test="userName != null">
        and user.username like '%${userName}%'
    </if>
    <if test="loginName != null">
        and user.login_name like '%${loginName}%'
    </if>
</select>

利用链:

  1. ResourceController.getList()接收search参数
  2. 传递到UserComponent.counts()
  3. 最终调用UserMapperEx.countsByUser()

测试Payload:

  • %'/**/And/**/SleeP(3)--

5.3 注入点2:消息状态查询

漏洞位置:MsgMapperEx.xml

<select id="getMsgCountByStatus" resultType="java.lang.Long">
    SELECT COUNT(id) FROM jsh_msg
    WHERE 1=1
    <if test="status != null">
        and status = '${status}'
    </if>
</select>

测试Payload:

  • 1'/**/and/**/1=1--
  • 1'/**/and/**/1=2--

6. XSS漏洞

6.1 审计关键点

  • 关键字:<%=${<c:outModelAndViewrequest.getParameter
  • 存储型XSS需寻找数据存储和显示两个点

6.2 漏洞点1:供应商信息更新

存储利用链:

  1. ResourceController.updateResource()接收beanJson
  2. 传递到SupplierComponent.update()
  3. 最终调用SupplierMapper.updateByPrimaryKeySelective()

显示利用链:

  1. ResourceController.getList()查询数据
  2. 前端supplier.js通过AJAX获取并显示数据

测试Payload:

{
  "supplier": "客户1",
  "description": "<script>alert('desc')</script>",
  "address": "<script>alert('address')</script>"
}

7. 信息泄露漏洞

7.1 Swagger API文档泄露

漏洞配置类:Swagger2Config.java

@Bean
public Docket createRestApi() {
    return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.any())
            .paths(PathSelectors.any())
            .build();
}

修复建议:

  • 限制请求处理程序和路径
  • 添加访问控制和身份验证

7.2 账号密码泄露

利用Filter的免登录条件直接访问敏感接口

8. 越权漏洞

8.1 密码重置越权

漏洞位置:UserController.resetPwd()

@PostMapping(value = "/resetPwd")
public String resetPwd(@RequestParam("id") Long id, HttpServletRequest request) {
    // 无权限校验直接重置
    int update = userService.resetPwd(md5Pwd, id);
}

测试方法:

  • 修改请求中的id参数为其他用户ID

8.2 用户删除越权

漏洞位置:UserController.deleteUser()

@PostMapping("/deleteUser")
public Object deleteUser(@RequestParam("ids") String ids) {
    // 无权限校验直接删除
    userService.batDeleteUser(ids);
}

9. 总结与建议

9.1 审计经验总结

  1. 组件分析优先:从pom.xml入手,检查已知漏洞组件
  2. SQL注入重点检查:
    • MyBatis中的${}使用
    • 模糊查询、排序、IN条件等场景
  3. XSS漏洞需同时分析存储和显示逻辑
  4. 越权漏洞需检查每个接口的权限控制

9.2 修复建议

  1. 升级存在漏洞的组件版本
  2. MyBatis中使用#{}替代${}
  3. 添加全局XSS过滤器
  4. 实现完善的权限控制机制
  5. 限制Swagger等开发工具的访问

9.3 进阶审计工具

  • 静态分析工具:CodeQL、Fortify
  • 动态测试工具:Yakit、Burp Suite
  • 代码搜索技巧:关键API和特征关键字搜索
Java代码审计技巧与ERP系统漏洞深度剖析 1. 审计准备工作 1.1 项目结构分析 src/main/java :存放核心Java代码,包含controller、service、filter、dao等 src/main/resources :包含mybatis配置文件、properties等 erp_web :存放网站的html、css及js文件 docs :数据库文件及文档文件 test :项目测试目录 pom.xml :项目依赖配置 1.2 环境搭建 数据库创建: 项目启动: 配置 application.properties 中的数据库连接信息 启动主类 ErpApplication.java 2. 配置文件审计 2.1 关键配置文件 application.properties :Spring全局配置,包含server IP/port和数据库连接信息 pom.xml :组件依赖配置,重点检查已知漏洞组件 2.2 组件漏洞分析 Fastjson反序列化漏洞 1.2.55版本存在反序列化漏洞 审计点:全局搜索 parseObject 方法 漏洞利用链: StringUtil.getInfo() 调用 JSONObject.parseObject() UserComponent.getUserList() 调用 StringUtil.getInfo() ResourceController.getList() 最终调用 UserComponent.getUserList() 测试Payload: Log4j漏洞 2.10.0版本无相关漏洞 3. Filter分析 3.1 LogCostFilter分析 免登录访问条件: URL包含 /doc.html 、 /register.html 或 /login.html URL包含 .css 、 .js 、 .jpg 、 .png 、 .gif 、 .ico URL以 /user/login 、 /user/registerUser 、 /v2/api-docs 开头 4. 路由分析 4.1 特殊路由处理 ResourceController 处理包含 {apiName} 的路径 通过 CommonQueryManager 和 Component 类进行路由分发 5. SQL注入漏洞 5.1 审计关键点 关注 createQuery() 、 createSQLQuery() 、 createNativeQuery() 检查SQL语句是否直接拼接参数 MyBatis中搜索 ${} 使用情况 JPA检查 JpaSort.unsafe() 使用 5.2 注入点1:用户查询 漏洞位置: UserMapperEx.xml 利用链: ResourceController.getList() 接收 search 参数 传递到 UserComponent.counts() 最终调用 UserMapperEx.countsByUser() 测试Payload: %'/**/And/**/SleeP(3)-- 5.3 注入点2:消息状态查询 漏洞位置: MsgMapperEx.xml 测试Payload: 1'/**/and/**/1=1-- 1'/**/and/**/1=2-- 6. XSS漏洞 6.1 审计关键点 关键字: <%= 、 ${ 、 <c:out 、 ModelAndView 、 request.getParameter 存储型XSS需寻找数据存储和显示两个点 6.2 漏洞点1:供应商信息更新 存储利用链: ResourceController.updateResource() 接收 beanJson 传递到 SupplierComponent.update() 最终调用 SupplierMapper.updateByPrimaryKeySelective() 显示利用链: ResourceController.getList() 查询数据 前端 supplier.js 通过AJAX获取并显示数据 测试Payload: 7. 信息泄露漏洞 7.1 Swagger API文档泄露 漏洞配置类: Swagger2Config.java 修复建议: 限制请求处理程序和路径 添加访问控制和身份验证 7.2 账号密码泄露 利用Filter的免登录条件直接访问敏感接口 8. 越权漏洞 8.1 密码重置越权 漏洞位置: UserController.resetPwd() 测试方法: 修改请求中的 id 参数为其他用户ID 8.2 用户删除越权 漏洞位置: UserController.deleteUser() 9. 总结与建议 9.1 审计经验总结 组件分析优先:从 pom.xml 入手,检查已知漏洞组件 SQL注入重点检查: MyBatis中的 ${} 使用 模糊查询、排序、IN条件等场景 XSS漏洞需同时分析存储和显示逻辑 越权漏洞需检查每个接口的权限控制 9.2 修复建议 升级存在漏洞的组件版本 MyBatis中使用 #{} 替代 ${} 添加全局XSS过滤器 实现完善的权限控制机制 限制Swagger等开发工具的访问 9.3 进阶审计工具 静态分析工具:CodeQL、Fortify 动态测试工具:Yakit、Burp Suite 代码搜索技巧:关键API和特征关键字搜索