23-hello-java-sec靶场搭建&Java Web常见漏洞

1、使用IDEA和PhpStudy搭建hello-java-sec 靶场并成功运行

  • 搭建靶场:

    • 下载 Hello Java Sec 靶场源码,解压后用IDEA打开(使用 JDK 1.8,由于MySQL5.7.26 不支持最新版的sql语法 ,源码建议用1.1版本)

    • 打开 PhpStudy,运行 MySQL5.7.26

    • 打开数据库工具 SQL_Front 导入数据库文件 src/main/resources/db.sql 配置数据库连接文件src/main/application-dev.properties

      image-20250306145122573

      image-20250306145150931

  • 运行成功(默认账号:admin/admin)

    image-20250306150550291

2、分析常见的java sql注入漏洞代码样例,包含jdbc、mybatis注入并结合靶场进行漏洞复现

JDBC

概述:JDBC 提供了一种标准的方法来连接数据库、发送查询和更新命令、以及处理查询结果。它为开发人员提供了一种统一的接口,使得他们可以使用相同的代码来访问不同的数据库系统。

  • Statemen注入:

    概述:Statement 对象用于执行静态 SQL 语句并返回它所生成的结果

    • 漏洞代码(使用 Statement 方法直接拼接了SQL语句,导致注入)

      image-20250306153646435

    • 漏洞利用

      payload:id=1' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)-- +

      image-20250306154355400

    • 解决方法:设置黑名单过滤

  • PrepareStatement注入

    概述:PrepareStatement 方法支持使用 ? 对变量位进行占位,在预编译阶段填入相应的值构造出完整的SQL语句,此时可以避免SQL注入的产生,但是采用直接拼接方式任然会造成SQL注入。

    • 漏洞代码

      image-20250306160319867

    • 漏洞利用

      payload:id=2 or 1=1

      image-20250306160809495

    • 解决方法:使用 ? 作为占位符来代替参数

MyBatis

概述:MyBatis 是一个支持自定义 SQL、存储过程和高级映射的持久层框架,简化了 Java 应用程序与数据库的交互。

  • order by 注入

    • 漏洞代码:(参数采用 ${} 直接拼接字符串,容易导致 SQL 注入)

      @GetMapping("/vul/order")
      public List<User> orderBy(String field, String sort) {
          return userMapper.orderBy(field, sort);
      }
      
      // 不安全的注解写法
      public interface UserMapper {
          @Select("select * from users order by ${field} ${sort}")
          List<User> orderBy(@Param("field") String field, @Param("sort") String sort);
      }
      
      // 不安全的XML映射写法
      <select id="orderBy" resultType="com.best.hello.entity.User">
          select * from users order by ${field} ${sort}
      </select>        
      
    • 漏洞利用

      payload:field=id&sort=desc,abs(111111)

      image-20250306164815158

    • 解决方法:使用 #{} 替换掉 ${} 或者使用Integer 强制类型转换

3、分析常见的命令注入漏洞代码样例,并说明什么情况下才可以利用以及原理。

  • ProcessBuilder

    • 漏洞代码

      // String dir = "xxxx";
      String[] cmdList = new String[]{"sh", "-c", "ls -lh " + dir}; // ; | & ``$()
      ProcessBuilder builder = new ProcessBuilder(cmdList);
      builder.redirectErrorStream(true);
      Process process = builder.start();
      printOutput(process.getInputStream());
      
    • 原理:java.lang.ProcessBuilderstart() 方法可以执行系统命令,命令和参数可以通过构造方法的 String List 或 String 数组来传入

    • 利用条件:需要代码中创建 shell 来执行命令,并且参数可控或存在拼接

  • Runtime

    • 漏洞代码

      public static String vul(String cmd) {
          StringBuilder sb = new StringBuilder();
          try {
              Process proc = Runtime.getRuntime().exec(cmd);
              InputStream fis = proc.getInputStream();
              InputStreamReader isr = new InputStreamReader(fis);
              BufferedReader br = new BufferedReader(isr);
           ...
      
      • 代码底层逻辑:直接传入 String 时,会先经过 StringTokenizer 的分隔处理,然后在使用 ProcessBuilde 也就是说传入的参数如果是A b的话,系统会执行A命令且把 b 当中 A 的参数处理
    • 原理:java.lang.Runtimeexec() 函数同样可以执行系统命令,命令参数支持 String 和 String 数组两种方式,同时支持设置环境变量、子进程工作目录 (working directory) 参数。

    • 利用条件:手动创建 shell 执行命令,可执行 -c 的参数值的命令,但注入的命令内不能有空格、\t\n\r\f 分隔符,否则会被分割。

4、分析代码执行漏洞、表达式注入漏洞、SSTI模板注入漏洞样例并理解原理

代码执行漏洞

概述:Java是编译型语言,该漏洞主要是指脚本引擎代码注入。

  • 漏洞代码

    // 通过加载远程js文件来执行代码,如果加载了恶意js则会造成任意命令执行
    // 远程恶意js: var a = mainOutput(); function mainOutput() { var x=java.lang.Runtime.getRuntime().exec("open -a Calculator");}
    public void jsEngine(String url) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
        Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
        String payload = String.format("load('%s')", url);
        engine.eval(payload, bindings);
    }
    
  • 原理: Java的javax.script.ScriptEngineManager类的 eval函数可以被控制用于执行代码(Java 8 之后便删除了)

表达式注入漏洞

概述:表达式注入漏洞类似远程代码执行漏洞,但远程代码执行漏洞是直接注入代码原生语句,而表达式注入漏洞是基于代码之上构建的执行逻辑。

  • SpEL 表达式注入

    概述:Spring Expression Language(简称 SpEL)是一种功能强大的表达式语言、用于在运行时查询和操作对象图。

    • 漏洞代码

       @GetMapping("/spel")
       public String rce(String ex) {
        ExpressionParser parser = new SpelExpressionParser();
        String result = parser.parseExpression(ex).getValue().toString();
        System.out.println(result);
        return result;
       }
      

      payload:T(java.lang.Runtime).getRuntime().exec(%27cmd.exe%20/c%20whoami%27)

    • 原理:SpelExpressionParser,会将用户输入的表达式被直接解析和执行

  • OGNL注入漏洞

    概述:OGNL全称Object-Graph Navigation Language即对象导航图语言,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能

    • 漏洞代码(Struts2框架使用ognl表达式)

      import ognl.Ognl;
      import ognl.OgnlContext;
      public class Test {
          public static void main(String[] args) throws Exception {
              // 创建⼀个OGNL上下⽂对象
              OgnlContext context = new OgnlContext();
              // getValue()触发
              // @[类全名(包括包路径)]@[⽅法名|值名]
              Ognl.getValue("@java.lang.Runtime@getRuntime().exec('calc')",context,context.getRoot());
              // setValue()触发
      // Ognl.setValue(Runtime.getRuntime().exec("calc"), context, context.getRoot());
      	}
      }
      
    • 原理:Ognl,也会将用户输入的表达式被直接解析和执行

  • EL表达式注入

    概述:EL 是 JSP 内置的表达式语言,用以访问页面的上下文以及不同作用域中的对象 ,取得对象属性的值,

    或执行简单的运算或判断操作。

SSTI模板注入漏洞

  • 原理:服务端接收攻击者的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的⼀部分,模板引擎在进行目标编译渲染的过程中,执行了攻击者插入的可以破坏模板的语句,从而达到攻击者的目的

    • Thymeleaf

      概述:Thymeleaf 是用于Web和独立环境的现代服务器端Java模板引擎且Thymeleaf 是 spring boot 的推荐引擎。

      漏洞代码:

      /**
       * 模板文件参数可控,造成模板注入漏洞
       */
      @GetMapping("/thymeleaf/vul")
      public String thymeleafVul(@RequestParam String lang) {
          return "lang/" + lang;
      

      分析:lang 变量的值是直接从请求参数 @RequestParam String lang 获取的。return "lang/" + lang; 直接将用户输入拼接到返回值上,导致 Thymeleaf 解析为模板路径。

5、理解常见的信息泄露漏洞,如actuator、swagger等

actuator

概述:Spring Boot Actuator 模块提供了健康检查,审计,指标收集,HTTP 跟踪等,是帮助我们监控和管理Spring Boot 应用的模块

  • Actuator 使用:加入下面依赖即可

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
        <version>2.7.0</version>
    </dependency>
    

    加上actuator依赖后,SpringBoot 在运行时会自动开启/actuator/health/actuator/info这两个endpoint,如下所示

    management.endpoints.shutdown.enabled=true
    management.endpoints.web.exposure.include=*
    
  • 漏洞危害:

    • 敏感数据泄露:如/env端点可能暴露数据库密码、API密钥等环境变量。
    • 堆转储分析:/heapdump可下载JVM内存快照,通过工具分析提取明文敏感信息。
    • HTTP跟踪泄露:/httptrace记录请求头,可能泄露Cookie或Token。
  • 攻击方式

    • 访问/actuator列出所有开放端点。

    • 利用/heapdump获取内存文件,使用MAT工具分析查找敏感字段。

swagger

概述: Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务,由于未开启页面访问限制或严格的Authorize认证导致接口信息泄漏。

  • 漏洞危害:若存在相关的配置缺陷,攻击者可以未授权翻查Swagger接⼝⽂档,得到系统功能API接口的详细参数,再构造参数发包,通过回显获取系统大量的敏感信息。

  • 攻击方式:访问http://target.com/swagger-ui.html查看所有API。

6、复习常见的逻辑漏洞,重点是越权漏洞

概述:逻辑漏洞就是指攻击者利用业务/功能上的设计缺陷,获取敏感信息或破坏业务的完整性。⼀般出现在密码修改、越权访问、密码找回、交易支付金额等功能处。

越权漏洞

  1. 分类

    • 水平越权

      • 定义:同权限用户之间非法访问或操作他人数据(如用户A访问用户B的数据)。
      • 案例:修改URL中的用户ID参数获取他人订单信息。
    • 垂直越权

      • 定义:低权限用户执行高权限操作(如普通用户访问管理后台)。
      • 案例:普通用户猜测管理员URL路径进入后台删除用户。
  2. 产生原因

    • 隐藏URL暴露:管理页面未严格校验权限,仅通过隐藏URL控制访问。

    • 直接对象引用:未校验用户参数(如ID、文件名),攻击者篡改参数访问未授权资源。

    • 多阶段功能缺陷:流程分步验证不完整(如密码重置第一步通过后,第二步未二次验证身份)。

    • 静态文件泄露:付费文档URL泄露或被猜解,导致未授权下载。

    • 平台配置错误:访问控制策略(ACL)配置失误,允许越权访问。

  3. 修复建议

    • 双重验证:前后端均校验用户输入及权限。

    • 敏感操作确认:关键操作(如支付、密码修改)需二次验证(密码、短信验证码)。

    • 加密标识:

      • 使用不可预测的Token或哈希值替代用户ID存储在Session/Cookie中。
      • 资源ID加密(如将document_id=123加密为不可逆哈希)。
    • 输入校验:永远不要相信来自用户的输入,对于可控参数进行严格的检查与过滤。

密码重置漏洞

  • 关键风险点:验证码暴力破解、参数篡改(邮箱/手机号)
  • 防御措施:服务端读取用户信息,限制验证码错误次数。

验证码漏洞

  • 关键风险点:前端绕过、未刷新验证码、Token可预测。
  • 防御措施:服务端控制验证码生命周期,绑定用户身份。

支付漏洞

  • 关键风险点:金额/数量篡改、越权支付、接口替换。
  • 防御措施:校验订单金额一致性,签名验证交易参数。

投票积分抽奖漏洞

  • 关键风险点:Cookie/IP伪造、批量注册账号刷票。
  • 防御措施:基于Session读取用户信息,限制设备/IP请求频率。
posted @ 2025-03-06 20:46  荔枝在敲诈  阅读(1397)  评论(0)    收藏  举报