Java 升级之路(七)JNDI注入

 


Java 升级之路(七)JNDI注入Naming ReferenceJNDI注入JNDI注入利用RMI攻击原理CORBA攻击原理LDAP攻击原理JNDI注入攻击简单例子

Naming Reference

java为了将object对象存储在Naming或者Directory服务下,提供了Naming Reference功能,对象可以通过绑定Reference存储在Naming和Directory服务下,比如(rmi,ldap等)。在使用Reference的时候,我们可以直接把对象写在构造方法中,当被调用的时候,对象的方法就会被触发。

 

JNDI注入

不应使用不受信任的数据执行JNDI查找

其攻击过程如下

  1. 攻击者将Payload绑定到攻击者自己的命名/目录服务
  2. 攻击者注入易受攻击的JNDI查找方法
  3. 应用程序执行查找
  4. 应用程序连接到攻击者控制的JNDI服务并返回Payload
  5. 应用程序解码响应并触发有效负载

当攻击者可控数据为<ATTACKER-CONTROLLED>

Context.PROVIDER_URL初始参数为本地的1099端口,如果这个参数被攻击者可控,于是就能实现远程加载恶意的对象,动态协议转化时会出现如下情况:

这样就会导致JNDI注入漏洞,攻击者可能构造如下绝对URL来达成攻击

 

PS. 不仅仅是InitialContext.lookup()方法会受到影响,其他方法例如InitialContext.rename()InitialContext.lookupLink()最后也调用了InitialContext.lookup()。还有其他包装了JNDI的应用,例如Apache’s Shiro JndiTemplateSpring’s JndiTemplate也会调用InitialContext.lookup()

 

JNDI注入利用

主要有三种角度来实现RCE

 

RMI攻击原理

Naming Manager 解密方法:

如果加载了攻击者自行构造的远程恶意类就可能导致RCE

 

CORBA攻击原理

IOR远程获取实现类, 控制IOR可以指定其控制下的IDL接口和代码库位置,从而RCE

IOR (Interoperable Object Reference, 可互操作对象引用): 是一个CORBARMI-IIOP引用

IIOP (Internet Inter-ORB Protocol, 互联网内部对象请求代理协议)

IDL (Interface Definition Language, 接口定义语言), 是一种分布式对象技术, 可实现网络上不同平台上的对象相互之间的交互

 

IOR可以是一个二进制格式或序列化并十六进制后的字符串

反序列化时的代码如下:

 

LDAP攻击原理

LDAP可以用来存储Java对象

存储方法有如下几种:

Nameing Managerdecode这些对象的时候可能会导致RCE

search()lookup()经常用在LDAP操作中

LDAP search()可以使用SearchControls对象来指定搜索范围和搜索结果返回的内容

res:

如果搜索是请求返回条目的对象(SearchControls.setReturningObjFlag()true),则SearchResult将包含一个表示entry的对象...

如果java.io.SerializableReferenceableReference object先前绑定到该LDAP上,这条entryattributes将重建该对象...

否则,entry中的attributes将用于创建表示LDAP条目的DirContext实例。

 

如果搜索是请求返回条目的对象(SearchControls.setReturningObjFlag()true),则SearchResult将包含一个表示该项的对象

可以构造如下攻击payload(序列化对象):

如果com.sun.jndi.ldap.object.trustURLCodebasetrue,攻击者可以提供自己的类,否则只能用classpath中可用的gadgets

还可构造(JNDI References):

使用JNDI引用使用远程工厂类:

javaCodebase:位置, javaFactory: 名称, javaClassName:被引用类的名称

而对于lookup()操作来说,攻击代码还可以是这种:

此时服务端代码如下

 

 

JNDI注入攻击简单例子

Vuln.java(假设其中的uri是上面提到的攻击者可控点<ATTACKER-CONTROLLED>)

 

Exp.java

 

Bind.java

 

当有Vuln通过 lookup("xxx")获取远程对象时,获得到一个Reference类的存根 由于获取的是一个Reference实例, 客户端会首先去本地的CLASSPATH去寻找被标识为Exp的类, 如果本地未找到,则会去请求 http://127.0.0.1/Exp.class 动态加载classes并调用Exp构造方法

当然,如果当前目录下有Exp.class就不用开启http服务了