Cutting Edge, Part 2: Investigating Ivanti Connect Secure VPN Zero-Day Exploitation | Mandiant

Mandiant details widespread exploitation of Ivanti Connect Secure and Policy Secure appliances via multiple zero-days leading to remote unauthenticated command execution and deployment of several web shells and backdoors. Post-exploitation activity includes credential harvesting (WARPWIRE), multiple Perl/Python web shells (BUSHWALK, LIGHTWIRE, CHAINLINE, FRAMESTING), a stateful passive backdoor (ZIPLINE), and efforts to dump/exfiltrate configuration and logs. #UNC5221 #IvantiConnectSecure

Keypoints

  • Mandiant attributes early zero‑day exploitation of CVE-2023-46805 and CVE-2024-21887 (and later CVE-2024-21888/CVE-2024-21893) to UNC5221 beginning as early as Dec 3, 2023, enabling unauthenticated command execution on Ivanti appliances.
  • Multiple web shells were deployed: BUSHWALK (Perl in querymanifest.cgi), LIGHTWIRE (Perl in compcheckresult.cgi), CHAINLINE and FRAMESTING (Python in CAV package), each providing remote command execution and file write capabilities.
  • WARPWIRE is a credential-harvesting JavaScript family with many variants that exfiltrate encoded usernames/passwords to hard-coded C2 domains/IPs via GET or POST requests.
  • ZIPLINE is a stateful passive backdoor using AES-128-CBC (keys derived via SHA1 from server key material), HMAC-SHA1 for message integrity, and a custom binary protocol with strict message structure and command IDs (file upload/download, reverse shell, proxy/tunneling).
  • Post‑exploit procedures included patching dsls to reveal redacted config/cache, archiving dumps into web-accessible CSS/GIF files (staged under dana-na paths), timestomping, log clearing, and tampering with the internal Integrity Checker Tool (ICT) to evade detection.
  • Mandiant published YARA rules, ICT guidance, and recommended immediate mitigation/patching, integrity checks, credential resets, and hunting for listed IOCs (filenames, hashes, domains, IPs, and modified Python package paths).

MITRE Techniques

  • [T1190] Exploit Public-Facing Application – UNC5221 exploited Ivanti CS/PS zero-days to gain unauthenticated command execution. (‘Mandiant has identified zero-day exploitation of these vulnerabilities in the wild beginning as early as Dec. 3, 2023 by … UNC5221.’)
  • [T1505.003] Server Software Component: Web Shell – Multiple web shells were embedded in legitimate Ivanti files or Python packages to enable remote commands and file writes. (‘BUSHWALK is written in Perl and is embedded into a legitimate CS file, querymanifest.cgi.’ )
  • [T1059] Command and Scripting Interpreter – Web shells and injected code execute arbitrary OS commands (changeVersion executes commands and returns RC4-encrypted output). (‘If the decrypted payload contains change, BUSHWALK calls the changeData function to execute an arbitrary command on the compromised appliance.’)
  • [T1105] Ingress Tool Transfer – Attackers uploaded or wrote arbitrary files to the appliance (updateVersion and Python file creation such as health.py). (‘If the decrypted payload contains update, BUSHWALK calls the updateVersion function to write an arbitrary file to the server.’ )
  • [T1562] Impair Defenses – Actors tampered with the internal Integrity Checker Tool manifest and commented out scanner execution to evade detection. (‘Mandiant has observed threat actors attempting to tamper with the internal (built-in) ICT to evade detection.’ )
  • [T1567.001] Exfiltration Over Web Service – Configuration/cache dumps and webserver logs were staged into web-accessible files (CSS/GIF) for retrieval. (‘The command redirects the GIF header into logo.gif and then appends the Base64-encoded contents of /data/var/dlogs/cav_webserv.log into the same file.’ )

Indicators of Compromise

  • [Filename / Host-based] Web shells and indicators – health.py (MD5: 3045f5b3d355a9ab26ab6f44cc831a83 for CHAINLINE), compcheckresult.cgi (MD5: 3d97f55a03ceb4f71671aa2ecf5b24e9 for LIGHTWIRE), and category.py (MD5: 465600cece80861497e8c1c86a07a23e for FRAMESTING).
  • [File patterns / Paths] Staged exfiltration paths – /home/webserver/htdocs/dana-na/css/[a-fA-F0-9]{10}.css and /runtime/webserver/htdocs/dana-na/help/logo.gif used to store config/cache dumps or encoded logs.
  • [Domains] C2 domains for credential harvesters – symantke[.]com (WARPWIRE C2), miltonhouse[.]nl and duorhytm[.]fun (WARPWIRE variants).
  • [IPv4] Noted C2 / post-exploitation hosts – 146.0.228[.]66, 159.65.130[.]146, and 50.215.39[.]49 (post-exploitation activity).

Mandiant observed attackers exploiting Ivanti Connect Secure/Policy Secure zero-days to place and invoke multiple web shells and backdoors. BUSHWALK (Perl) is embedded in querymanifest.cgi; it decodes a Base64/RC4 payload from a “command” parameter and either executes the decrypted command (change -> runs via popen and RC4-encodes the output) or writes files (update -> Base64-decode then syswrite to specified path). LIGHTWIRE variants accept GET requests to compcheckresult.cgi and decrypt RC4/Base64 payloads to eval commands; hunters should search web logs and memory for the GET parameters shown. Python-based web shells (CHAINLINE, FRAMESTING) were implanted in the CAV package: CHAINLINE creates a new health.py REST endpoint (/api/v1/cav/client/health) that accepts base64+XOR/RC4-encrypted commands and returns base64-encoded results, while FRAMESTING registers a POST-only categories endpoint (/api/v1/cav/client/categories) that decrypts cookie or POST zlib data with AES and exec()s decompressed code.

ZIPLINE is a stateful passive backdoor: the C2 initial header uses an SSH-like signature plus 20-byte key material; keys combine server-sent keydata with hard-coded data, hashed with SHA1, and the first 16 bytes produce AES-128-CBC keys and HMAC keys (HMAC-SHA1). Messages require strict structure and an incrementing message index; acceptable first-message plaintext triggers a reply and subsequent command messages (IDs for file upload/download, reverse shell, proxy, tunneling) drive operations. Post-exploitation procedures include patching /home/bin/dsls to bypass redaction (patching a conditional jump to unconditional), running the patched dsls to dump config/cache into /home/webserver/htdocs/dana-na/css/.css or embedding base64 log content into logo.gif for exfiltration, timestomping, clearing config_rest_server.log, remounting filesystem read-only, and tampering with the internal ICT (manifest modifications or commenting out scanner execution) to evade detection. Read more: https://www.mandiant.com/resources/blog/investigating-ivanti-zero-day-exploitation