0x01前言
前段非常火的weblogic挖矿相信大家依旧记忆犹新,毕竟当时预警信息满天飞。今天我们就分析分析weblogic是因为什么原因导致任意命令执行,下载了恶意的挖矿脚本的。
0x02漏洞描述
Oracle Fusion Middleware中的Oracle WebLogic Server组件的WLS Security子组件存在安全漏洞。使用精心构造的xml数据可能造成任意代码执行,攻击者只需要发送精心构造的xml恶意数据,就可以拿到目标服务器的权限。
影响版本
Oracle WebLogic Server 10.3.6.0.0版本
Oracle WebLogic Server 12.1.3.0.0版本
Oracle WebLogic Server 12.2.1.1.0版本
0x03漏洞分析
既然网上说的是因为Weblogic的WLS Security组件产生了问题,那我们就这开始分析吧。
首先查看组件的路由映射,很快就发现了熟悉的东西CoordinatorPortType。看到这个不就是poc的请求路径吗?当时记得漏洞刚出来的时候,有的poc请求的CoordinatorPortType11路径,当时比较纳闷,加了11路径不就变了吗?那怎么还可以请求到组件,并且执行命令。于是自己又把11换成了12。结果更纳闷了………………..失败了,302。这块在那时被拍脑袋想了好久都没明白。
直到我在路由映射中看到了它,相信写过javaweb的都能看懂,下面是一个简单的servlet映射。而其中配置文件中就有一条的url-pattern中有个CoordinatorPortType11
也就是说WLS Security组件内的所有映射都可以触发漏洞,下面我将其中的映射全部都摘录了出来,一共8条。以后想怎么换就怎么换。妈妈再也不用担心我的路径了。在这解决了我当时的第一个疑点。
基础补充
在我们动态分析以前,首先引入一个东西XMLDecoder。XMLDecoder 类用于读取使用 XMLEncoder 创建的 XML 文档,用途类似于 ObjectInputStream。当构造恶意的xml时,使用XMLEncoder解析,进行反序列化时,将会触发命令执行。
这是我们构造的恶意的poc
将其以流的方式传给XMLDecoder,并对他进行反序列化。然后成功弹出了计算器。
0x04动态分析
Weblogic不是开源的,所以不能直接下载源码去分析。只能对其jar包进行反编译。所以动态分析的时候好多坑。
首先请求先会进入handel方法,handel方法又会执行super.handle(var1, var2, var3);方法,这个方法对servlet的容器和request和response进行了封装。
继续跟进。
发现先会对var1的内容判断是否为空,不为空的话,会取出xml中的header,也就是我们poc中的。
<soapenv:Header>
work:WorkContextxmlns:work="http://bea.com/2004/06/soap/workarea/"
<java>
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
<void index="0">
<string>cmd</string>
</void>
<void index="1">
<string>/c</string>
</void>
<void index="2">
<string>calc</string>
</void>
</array>
<void method="start"/>
</void>
</java>
</work:WorkContext>
</soapenv:Header>
然后将获取的header传入readHeaderOld方法。 跟进readHeaderOld方法,发现将hander中的数据以字节流的形式传给WorkContextXmlInputAdapter,而var4中就是我们构造的xml恶意数据。 WorkContextXmlInputAdapter对象会将传入的xml恶意数据转化为XMLDecoder,看到是不是想起我们前面那个小Demo了。对他进行反序列化后就会代码执行。 继续跟进,发现在weblogic.workarea.spi. WorkContextEntryImpl中的readEntry方法中,对var0进行了readUTF()方法。 而var0就是XMLDecoder对象。继续跟进readUTF方法 发现最终执行了readObject方法,对XMLDecoder对象进行了反序列化,导致了远程命令执行。
0x05poc分析
请求的url路径在刚开始的时候已经分析,在此就不多说了。下来好好分析分析xml
ProcessBuilder是什么? ,ProcessBuilder类是J2SE1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法。
说白了它能执行本地命令,但是它提供的功能更加丰富,能够设置工作目录、环境变量。
演示一个简单的小Demo
计算机弹的没意思了,咱们弹一个记事本。当执行上述main函数时会调用notepad命令。并将test.txt参数入进去。
继续分析,是不是poc猛的一看上去还是很懵逼,虽然格式缩进很漂亮,但毕竟还是给机器看的格式,不是很好理解。所以对上面的xml数据进行了java代码转化。
对标签分析,转化成java代码。这样对应起来看,是不是一下就明白了。也不用我详细赘述。
0x06补丁分析
至于补丁的化可以去oracle官网去找,但是需要注册挺麻烦的。下面我就直接把更新的摘要给大家摘出来
private void validate(InputStream is) {
WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
try {
SAXParser parser = factory.newSAXParser();
parser.parse(is, new DefaultHandler() {
public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase(“object”)){
throw newIllegalStateException(“Invalid context type: object”);
}
}
});
} catch (ParserConfigurationException var5) {
throw new IllegalStateException(“Parser Exception”, var5);
} catch (SAXException var6) {
throw new IllegalStateException(“Parser Exception”, var6);
} catch (IOException var7) {
throw new IllegalStateException(“Parser Exception”, var7);
}
}
上面这个是CVE-2017-3506的补丁,再对xml解析时,如果qName的值是Object时将抛出异常,采用的黑名单的方式。所以就出现了今天的分析的CVE-2017-10271。
public void startElement(String uri, StringlocalName, String qName, Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase(“object”)){
throw newIllegalStateException(“Invalid element qName:object”);
} else if(qName.equalsIgnoreCase(“new”)){
throw newIllegalStateException(“Invalid element qName:new”);
} else if(qName.equalsIgnoreCase(“method”)){
throw newIllegalStateException(“Invalid element qName:method”);
} else {
if(qName.equalsIgnoreCase(“void”)) {
for(int attClass = 0; attClass< attributes.getLength(); ++attClass) {
if(!”index”.equalsIgnoreCase(attributes.getQName(attClass))) {
throw newIllegalStateException(“Invalid attribute for element void:” +attributes.getQName(attClass));
}
}
}
上面是CVE-2017-10271补丁,分别对 Object new method void进行了判断,进行了防护。导致poc攻击失效。
0x07总结
CVE-2017-3506因为黑名单,导致可以绕过命令执行。所以感觉黑名单这个东西到底还是不靠谱。所以建议大家以后还是在能使用白名单的情况下,尽可能的去使用白名单。从而大大的降低被攻击的风险。