Sec Hotspot 首页  排行榜  收藏本站  技术博客  RSS
统计信息
已收录文章数量:18974 篇
已收录公众号数量:91 个
本站文章为爬虫采集,如有侵权请告知
已收录微信公众号
阿里云先知 网安寻路人 网信中国 区块链大本营 白说区块链 区块链投资家 区块链官微 区块链铅笔Blockchain HACK学习呀 二道情报贩子 合天智汇 小白帽学习之路 小米安全中心 弥天安全实验室 SAINTSEC SecPulse安全脉搏 TideSec安全团队 360安全卫士 游侠安全网 计算机与网络安全 安全祖师爷 安全学习那些事 腾讯安全联合实验室 黑客技术与网络安全 安全圈 腾讯御见威胁情报中心 Python开发者 Python之禅 编程派 Python那些事 Python程序员 安全威胁情报 吾爱破解论坛 行长叠报 安在 i春秋 嘶吼专业版 E安全 MottoIN 网信防务 网安杂谈 数说安全 互联网安全内参 漏洞战争 安全分析与研究 邑安全 ChaMd5安全团队 天融信阿尔法实验室 安全牛 SecWiki 安全学术圈 信安之路 漏洞感知 浅黑科技 Secquan圈子社区 奇安信集团 奇安信 CERT 国舜股份 雷神众测 盘古实验室 美团安全应急响应中心 瓜子安全应急响应中心 顺丰安全应急响应中心 蚂蚁金服安全响应中心 携程安全应急响应中心 滴滴安全应急响应中心 字节跳动安全中心 百度安全应急响应中心 腾讯安全应急响应中心 网易安全应急响应中心 OPPO安全应急响应中心 京东安全应急响应中心 Bypass CNNVD安全动态 安恒应急响应中心 天融信每日安全简报 奇安信威胁情报中心 看雪学院 黑白之道 水滴安全实验室 安全客 木星安全实验室 云鼎实验室 绿盟科技安全预警 白帽汇 深信服千里目安全实验室 腾讯玄武实验室 长亭安全课堂 FreeBuf 绿盟科技 nmask
CVE-2020-2883——WebLogic反序列化初探
本文来自公众号:安全客   2021.01.25 18:04:23





原理



(一)概述

和CVE-2015-4852中构造的ChainedTransformer类似,ReflectionExtractor可以实现任意方法调用,这里用链式的ReflectionExtractor构造ChainedExtractor,调用其extract()同样可以实现任意代码执行;

BadAttributeValueExpException中的readObject()可以调用成员变量的toString,且这个成员变量是我们可控的;

控制BAVEE的成员变量为LimitFilter对象,通过LimitFilter.toString()触发ChainedExtractor的extract(),进而触发RCE。

(二)CVE-2020-2883

CVE-2020-2555的补丁(仅)去除了LimitFilter.toString()中的extract()调用,

大概情况是这样,

当然,这条链断的并不完整,只要有一处能调用到我们构造的ChainedExtractor的extract(),则仍能触发ReflectionExtractor带来的任意方法调用。

(三)原理

1.工具分析

仍然是Y4er师傅的[PoC][ https://github.com/Y4er/CVE-2020-2883/ ],

将其放到weblogic_cmd的com/supeream/下即可。

相关内容在下面结合调试过程一起讲。

记录一下感觉很奇怪的事情,

PoC运行到这里,

queue的显示是这样的,看不到成员变量,很烦,

但若是计算queue.comparator,

也是有值的,虽然跟一下就能发现这个问题,不影响调试,但看起来总有些不舒服。

仔细一想,发现了问题之所在,

不知哪一次为了看字节流方便,将View as 改了,改回Object之后,就恢复正常了。

2.原理

补丁虽然remove了LimitFilter.toString()中的extract,仍然有几个类可以调用到ChainedExtractor.extract()。比如MultiExtractor继承了AbstractExtractor ,其内的compare()就可以调用到ChainedExtractor.extract()。

另一方面,PriorityQueue也是反序列化常用的基类,通过readObject()->heapify()->siftDown()->siftDownUsingComparator(),进而触发this.comparator.compare()




调试



(一)环境搭建

同CVE-2020-2555,不再赘述。

(二)复现

运行PoC,

(三)调试

先上这个PoC的调用栈,

extract:104, ReflectionExtractor (com.tangosol.util.extractor)extract:105, ChainedExtractor (com.tangosol.util.extractor)compare:71, ExtractorComparator (com.tangosol.util.comparator)siftDownUsingComparator:722, PriorityQueue (java.util)siftDown:688, PriorityQueue (java.util)heapify:737, PriorityQueue (java.util)readObject:797, PriorityQueue (java.util)invoke0:-1, NativeMethodAccessorImpl (sun.reflect)invoke:62, NativeMethodAccessorImpl (sun.reflect)invoke:43, DelegatingMethodAccessorImpl (sun.reflect)invoke:498, Method (java.lang.reflect)invokeReadObject:1158, ObjectStreamClass (java.io)readSerialData:2173, ObjectInputStream (java.io)readOrdinaryObject:2064, ObjectInputStream (java.io)readObject0:1568, ObjectInputStream (java.io)readObject:428, ObjectInputStream (java.io)readObject:73, InboundMsgAbbrev (weblogic.rjvm)read:45, InboundMsgAbbrev (weblogic.rjvm)readMsgAbbrevs:325, MsgAbbrevJVMConnection (weblogic.rjvm)init:219, MsgAbbrevInputStream (weblogic.rjvm)dispatch:557, MsgAbbrevJVMConnection (weblogic.rjvm)dispatch:666, MuxableSocketT3 (weblogic.rjvm.t3)dispatch:397, BaseAbstractMuxableSocket (weblogic.socket)readReadySocketOnce:993, SocketMuxer (weblogic.socket)readReadySocket:929, SocketMuxer (weblogic.socket)process:599, NIOSocketMuxer (weblogic.socket)processSockets:563, NIOSocketMuxer (weblogic.socket)run:30, SocketReaderRequest (weblogic.socket)execute:43, SocketReaderRequest (weblogic.socket)execute:147, ExecuteThread (weblogic.kernel)run:119, ExecuteThread (weblogic.kernel)

ChainedExtractor.extract()往上的部分就比较熟悉了,情况一致,不再赘述,重点关注从ChainedExtractor往下到PriorityQueue.readObject的片段,

接下来是从PriorityQueue.readObject()到PriorityQueue.siftDownUsingComparator()的部分,

1.this.queue

首先是queue的赋值,

会进入heapify(),

可以看出,在size>=2时,可以进入for的内部,进而进入siftDown函数,

这一部分在PoC中的体现如下,

PriorityQueue queue = new PriorityQueue(2, new ExtractorComparator(chainedExtractor1));queue.add("1");queue.add("1");m_aExtractor.set(chainedExtractor1, valueExtractors);
Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");queueArray[0] = Runtime.class;queueArray[1] = "1";

2.this.comparator

进入siftDown,我们看到,接下来的流程和comparator的值有关,跟踪之,

是个private,可以在构造函数中设定,

显然进入if,

跟进,因为size为2,前面的内容都可顺利走过,进入,此时x即为Runtime,c为1,

o1、o2对应x、c,

接下来即可进入this.m_extractor.extract,

先跟踪一下这个变量,

也是可以在构造函数里设定的,

对应着PoC中的如下部分,

Field m_aExtractor = clazz.getDeclaredField("m_aExtractor");m_aExtractor.setAccessible(true);
m_aExtractor.set(chainedExtractor1, valueExtractors);

接下来进入extract(),这一部分和之前一模一样,不再赘述。

个人感觉CVE-2020-2883的整个利用链和CVE-2020-2555相比仍有一定的相似度,前者的利用链是套路A+ReflectionExtractor任意方法调用,后者是套路B+ReflectionExtractor任意方法调用。CVE-2020-2555的补丁破坏了套路B,但ReflectionExtractor的任意方法调用部分仍然是可用的,只要找到别的触发点,仍可以利用。




收获和启示



因为之前粗略学习过CVE-2020-14645,感觉CVE-2020-2883可谓是“政启开元,治宏贞观”,其利用链的一部分继承了CVE-2020-2555中ReflectionExtractor的利用链,另一部分找到了PriorityQueue可达的、新的extract()的调用点,为CVE-2020-14645做了准备。

学到现在,有一个直观的感受是:最开始的CVE-2015-4852是开篇,后面的都是它的再发展(包括它的重现、它的绕过和它的绕过的绕过),所谓发展主要是指反序列化触发点的切换。从最开始2015时CC1链及其变种,到现在出现了新的利用类ReflectionExtractor,又一次告诉我们要封一类,而不能只封一个。


- End -
精彩推荐
BUGKU Reverse bingo题解
bypass AV 探索一
PWNHUB双蛋赛pwn题解


戳“阅读原文”查看更多内容