墨者防御联盟-提供超强DDoS高防/CC防护/大流量清洗服务!
当前位置:主页 > WEB安全 > 正文

Jenkins-LDAP (CVE-2016-9299) 反序列化漏洞分析

06-29 WEB安全

Jenkins-LDAP (CVE-2016-9299) 反序列化漏洞分析,那个漏洞在去年11月份官方公布通告的时候我当时关注过,当时自个儿向来在找 com.sun.jndi.ldap.LdapAttribute 那个类相关的反序列化,当时意识到那个类里面的 _getAttributeSyntaxDefinition()_ 想法和 _getAttributeDefinition()_ 大概会存在反序列化的咨询题,然而当时找了好多类,DDoS防护,发如今发序列化的时候都无法触发这两个想法,原本感觉是jdk里面自个儿的咨询题,最终就没然后跟下去了,中途有老外放出了一具ppt里面演示了那个漏洞,似乎看了下发觉是利用json来bypass Jenkins的白名单,当时向来在忙数据分析的情况,情况就搁浅了,前不大会儿刚好MSF上有Payload了,再加上年底了没这么多事了,于是就研究了下,那个漏洞依旧挺故意思的,涉及的知识面依旧略微广了一点,那个地点不得不佩服那些漏洞发觉者。

每当一具漏洞漏洞浮上的时候,DDoS防护,我就在想为啥自个儿不能发觉,当每次漏洞分析完的时候才发觉各方面的差距的确是不小。

技术在于分享,如此才干进步。漏洞简介

2016年11月16号Jenkins官方公布了一具安全通告,命名为 CVE-2016-9299 ,从通告上来看,该漏洞还是是个反序列的漏洞,只是那个漏洞的反序列化和LDAP有关,而且在反序列化后需要连接到一具恶意的LDAP服务器,Jenkins关于之前反序列化的修复想法算是对一些恶意的类加上黑名单,于是那个地点首先得Bypass官方的黑名单,关于该漏洞惟独那样多信息,而且在官方给的POC里面也仅仅是提到了 com.sun.jndi.ldap.LdapAttribute 那个类,那个漏洞的利用首先是不需要认证的,而且能任意代码执行,危害可见一斑。

漏洞分析

从官方的描述以及后面的Payload来看,咨询题和net.sf.json以及com.sun.jndi.ldap.LdapAttribute有关,经过分析对LdapAttribute那个类的分析,我们能够确定以下两个想法是触发反序列化漏洞的全然(对于下文中LDAP的反序列相关的知识请移步16年blackhat老外的Paper “us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE”)

getAttributeSyntaxDefinition getAttributeDefinition

这两个想法中都调用了该 _DirContext schema = getBaseCtx().getSchema(rdn);_ 代码片段其中getBaseCtx()想法定义如下:

\

该段代码使用jndi的方式去访咨询LDAP服务,那个地点我们能够操纵Context.PROVIDER_URL的参数,从而操纵jndi访咨询的LDAP服务器的地址。

getSchema(rdn)想法最后来会调用 com.sun.jndi.ldap.LdapBindingEnumeration.createItem(String, Attributes, Vector) 想法(调用关系太多,自个儿去调试),该想法的定义如下图

\

在该想法中最后来会调用 Obj.decodeObject(attrs) 想法,从而实现对象的反序列化。那个地点略微提下,com.sun.jndi.ldap.Obj对象中定义了几种对象序列化与反序列化的想法,有直截了当反序列化的,也有直截了当经过远程加载的,那个地点的的反序列化略微与其它地点的反序列化不同的点在于我们不能远程加载对象,因为com.sun.jndi.ldap.VersionHelper12.trustURLCodebase的默认值为false,于是直截了当决定了类加载器只能加载当前classpath下面的类,对于怎么去构造对象使得LDAP在反序列化能执行任意代码,请看下文。

到那个地点我们懂了com.sun.jndi.ldap.LdapAttribute中相关的想法能触发反序列化的漏洞,这么如今我们要做的算是去找到一具类在反序列化的时候能调用我们相应触发漏洞的函数,也算是在反序列化时能调用getAttributeSyntaxDefinition想法或者getAttributeDefinition想法的类,经过老外的PPT以及公开的gadgets,我们略微分析下就会发如今net.sf.json那个类库中存在能够调用类任意getXXX函数的地点,这么com.sun.jndi.ldap.LdapAttribute那个类中的getXXX想法是不是也能够经过这种方式来调用,首先我们先确定毕竟是这个类中的这个想法能调用getXXX函数,经过gadgets中的json Payload我们发觉最后来能调用对象的getXXX函数如下图(net.sf.json.JSONObject.defaultBeanProcessing(Object, JsonConfig))所示

上图中圈起来的两个地点算是能调用getXXX函数的地点,那个地点会先遍历javabean的所有属性,最终在挨个的调用。

弄知道了能函数调用的根源,下一步算是去找那个函数毕竟会怎么样触发。经过eclipse我们能够特别容易发觉如下调用方式。

\

如上图所示,我们能够看见defaultBeanProcessing想法最后来会被ConcurrentSkipListSet类中的equals想法调用,到那个地点特别多人大概会咨询了,这么多调用关系,DDoS防护,你为啥就找那个类的equals想法,那个地点大概会有一些经验在里面,因为关于和equals想法相关的东西太多了,关于java中的某些数据结构,例如Set,每次添加元素的时候都会推断当前key是否存在,还有算是比较两个对象是否相等的时候会去调用hashcode和equals想法,那个地点假如了解过其它反序列化的同学对此大概会稍有感触,例如jdk的这个反序列化的触发过程。假如这种经验没有的话,这么你只能一具一具的去找了。

{C}

最后来我们找到了一具类能够的某个想法能够调用我们的函数了,然而你大概会发如今eclipse中如此的函数调用关系大多是多态事情下的想法调用,于是我们还需要对equals想法中的想法调用举行分析,那个地点我们需要注意的是defaultBeanProcessing那个函数的直截了当调用对象是net.sf.json.JSONArray.fromObject(Object, JsonConfig)想法,我们来看下equals想法

\

在那个想法里面有两处调用了containsAll想法,我们要看看毕竟是这个大概会调用fromObject,我们再来看下fromObject的调用关系,如下图

\

你会发觉JSONArray调用了containsAll想法,

containsAll(c) && c.containsAll(this);

那个地点的第一具containsAll想法是触发不了的这个函数的,于是我们只要满脚对象o是JSONArray就行了,然而其实是不好了,因为那个对象o不是Set的子类,于是这条路到这差不多上就走不通了,于是我们还得然后找。

然后回到c.containsAll这里我们再找那些函数最后来调用了containsAll,那个地点我们发觉org.apache.commons.collections.collection.AbstractCollectionDecorator.containsAll(Collection)那个抽象类调用了,来看改函数的定义

protected Collection collection; .... public boolean containsAll(Collection coll) { return collection.containsAll(coll); }

那个地点最后来会调用collection.containsAll想法,假如那个地点我们将collection赋值为JSONArray对象的话不照样触发漏洞么,由于AbstractCollectionDecorator那个类是抽象的,无法实例化,于是我们得找一具它的子类,注意那个地点我们必须得满脚子类是实现了Set接口同时是能够序列化的,于是找到最终我们找到了org.apache.commons.collections.set.ListOrderedSet那个类。那个地点只需要满脚父类的collection是JSONArray就行了。

版权保护: 本文由 主页 原创,转载请保留链接: /web/183243.html


QQ客服

400-0797-119