CVE-2024-40898 SSL证书验证绕过漏洞扫描器
本项目是一个专业的Python漏洞扫描工具,用于检测CVE-2024-40898漏洞——Apache HTTP Server中允许攻击者绕过SSL证书验证的安全问题。该漏洞可能使攻击者通过中间人(MitM)攻击破坏TLS连接的安全性。
✨ 功能特性
- 漏洞检测核心:通过创建禁用证书验证的SSL上下文,模拟攻击者行为,检测目标是否存在SSL证书验证绕过漏洞
- 多线程扫描:支持可配置的线程数(默认10),大幅提升大规模目标扫描效率
- 灵活的目标管理:从文本文件读取
host:port格式的目标列表,支持批量检测 - 精确状态判断:解析HTTP响应状态码,以
200 OK作为潜在漏洞的关键指标 - 完整日志记录:支持将扫描结果输出到日志文件,便于后续分析和审计
- 详细输出模式:可选启用详细输出,便于调试和实时监控扫描进度
📦 安装指南
系统要求
- Python 3.x
依赖项
本项目仅使用Python标准库,无需安装第三方依赖包:
ssl- TLS/SSL连接处理socket- 网络连接argparse- 命令行参数解析concurrent.futures- 多线程支持
安装步骤
- 克隆或下载项目文件到本地:
git clone https://github.com/your-repo/cve-2024-40898-scanner.git
cd cve-2024-40898-scanner
- (可选)创建虚拟环境:
python3 -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows
- 准备目标列表文件(参见使用说明)
🚀 使用说明
基础使用
- 准备目标文件:创建
ssl-ports.txt文件,每行一个目标(格式:主机:端口):
api.example.com:443
www.target-site.org:443
secure.internal.service:8443
- 运行扫描:
python3 cve_2024_40898_scanner.py
高级选项
# 使用自定义目标文件,启用详细输出
python3 cve_2024_40898_scanner.py -f targets.txt -v
# 使用20个线程,并保存结果到日志文件
python3 cve_2024_40898_scanner.py -f ssl-ports.txt -t 20 -o scan_results.log
# 完整参数示例
python3 cve_2024_40898_scanner.py -f targets.txt -t 50 -v -o output.log
命令行参数
| 参数 | 说明 | 默认值 |
|---|---|---|
-f, --file | 输入文件路径(包含host:port) | ssl-ports.txt |
-t, --threads | 并发线程数 | 10 |
-v, --verbose | 启用详细输出模式 | False |
-o, --output | 输出日志文件路径 | None |
输出示例
[VULNERABLE] api.example.com:443 (HTTP/1.1 200 OK)
[SAFE] secure.service.net:443 (HTTP/1.1 403 Forbidden)
[ERROR] unreachable.host:443 => timed out
[VULNERABLE] vulnerable-site.org:8443 (HTTP/1.1 200 OK)
💎 核心代码
漏洞检测核心函数
def detect_ssl_verification_bypass(target_host, target_port, verbose=False, log_file=None):
"""
检测目标是否存在SSL证书验证绕过漏洞
工作原理:
1. 创建禁用证书验证的SSL上下文(check_hostname=False, verify_mode=CERT_NONE)
2. 建立TLS连接并发送HTTP HEAD请求
3. 检查响应状态码,200 OK表示可能存在漏洞
参数:
target_host: 目标主机名或IP
target_port: 目标端口
verbose: 是否启用详细输出
log_file: 日志文件路径(可选)
"""
# 创建不验证证书的SSL上下文(漏洞检测关键)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False # 禁用主机名验证
context.verify_mode = ssl.CERT_NONE # 禁用证书验证
try:
# 建立TCP连接
with socket.create_connection((target_host, target_port), timeout=5) as sock:
# TLS包装socket
with context.wrap_socket(sock, server_hostname=target_host) as ssock:
# 发送HTTP请求
request = f"HEAD / HTTP/1.1\r\nHost: {target_host}\r\nConnection: close\r\n\r\n"
ssock.sendall(request.encode())
response = ssock.recv(4096).decode(errors="ignore")
status_line = response.split("\r\n")[0]
# 判断漏洞存在性
if "200 OK" in status_line:
message = f"[VULNERABLE] {target_host}:{target_port} ({status_line})"
else:
message = f"[SAFE] {target_host}:{target_port} ({status_line})"
except Exception as e:
message = f"[ERROR] {target_host}:{target_port} => {e}"
print(message)
if log_file:
with open(log_file, "a") as f:
f.write(message + "\n")
if verbose:
print("-" * 60)
多线程任务调度器
def main():
"""
主函数:解析参数、加载目标并执行多线程扫描
"""
parser = argparse.ArgumentParser(description="Detect SSL verification bypass vulnerabilities (threaded)")
parser.add_argument("-f", "--file", default="ssl-ports.txt",
help="Input file with host:port per line")
parser.add_argument("-v", "--verbose", action="store_true",
help="Enable verbose output")
parser.add_argument("-o", "--output",
help="Output log file")
parser.add_argument("-t", "--threads", type=int, default=10,
help="Number of threads (default: 10)")
args = parser.parse_args()
# 解析目标列表
targets = parse_targets(args.file)
if not targets:
print("[ERROR] No valid targets found.")
return
# 使用线程池执行并发扫描
with ThreadPoolExecutor(max_workers=args.threads) as executor:
futures = []
for host, port in targets:
futures.append(executor.submit(
detect_ssl_verification_bypass,
host, port, args.verbose, args.output
))
# 等待所有任务完成并处理异常
for future in as_completed(futures):
try:
future.result()
except Exception as e:
print(f"[THREAD ERROR] {e}")
目标文件解析器
def parse_targets(file_path):
"""
从文件中解析host:port格式的目标列表
文件格式示例:
example.com:443
192.168.1.1:8443
api.service.net:443
返回:
List[Tuple[str, int]]: 包含(主机, 端口)元组的列表
"""
targets = []
try:
with open(file_path, "r") as file:
lines = file.read().splitlines()
for line in lines:
if ":" in line:
host, port = line.split(":")
host, port = host.strip(), int(port.strip())
targets.append((host, port))
except FileNotFoundError:
print(f"[ERROR] File not found: {file_path}")
return targets
⚠️ 重要提示
- 合法使用:本工具仅应用于您拥有授权或拥有合法测试权限的系统
- 漏洞原理:通过禁用SSL证书验证模拟攻击行为,准确识别CVE-2024-40898漏洞
- 性能优化:支持多线程并发,适合大规模扫描场景,可根据网络状况调整线程数
- 准确性说明:
200 OK响应仅表示潜在漏洞,建议结合人工验证确认结果 6HFtX5dABrKlqXeO5PUv/9NUGll7Bk1aj874HOttuvSMJtyp1jWdz/Xi7CsnBrzF