def attackGET(self, http_res): page = http_res.path resp_headers = http_res.headers referer = http_res.referer headers = {} if referer: headers["referer"] = referer url = page if url not in self.attackedGET: if self.verbose == 2: print(u"+ {0}".format(url)) err1 = self.__returnErrorByCode(resp_headers["status_code"]) if err1 != "ok": data1 = self.HTTP.send(url, headers=headers).getPage() # .htaccess protection detected if self.verbose >= 1: self.log(_("HtAccess protection found: {0}"), url) evil_req = HTTP.HTTPResource(url, method="ABC") data2, code2 = self.HTTP.send(evil_req, headers=headers).getPageCode() err2 = self.__returnErrorByCode(code2) if err2 == "ok": # .htaccess bypass success if self.verbose >= 1: self.logC(_("|HTTP Code: {0} : {1}"), resp_headers["status_code"], err1) if self.verbose == 2: self.logY(_("Source code:")) self.logW(data1) # report xml generator (ROMULUS) not implemented for htaccess self.logVuln(category=Vulnerability.HTACCESS, level=Vulnerability.HIGH_LEVEL, request=evil_req, info=_("{0} HtAccess").format(err1)) self.logR(_(" .htaccess bypass vulnerability: {0}"), evil_req.url) # print output informations by verbosity option if self.verbose >= 1: self.logC(_("|HTTP Code: {0}"), code2) if self.verbose == 2: self.logY(_("Source code:")) self.logW(data2) self.attackedGET.append(url)
def __end_element(self, name): if name == self.RESOURCE: http_res = HTTP.HTTPResource(self.path, method=self.method, encoding=self.encoding, referer=self.referer, get_params=self.get_params, post_params=self.post_params, file_params=self.file_params) http_res.setHeaders(self.headers) if self.array is self.toBrowse: self.toBrowse.append(http_res) else: if self.method == "GET": self.browsed.append(http_res) elif self.method == "POST": self.forms.append(http_res)
def attackGET(self, http_res): """This method performs the CRLF attack with method GET""" page = http_res.path params_list = http_res.get_params resp_headers = http_res.headers referer = http_res.referer headers = {} if referer: headers["referer"] = referer payload = self.HTTP.quote( "http://www.google.fr\r\nwapiti: SVN version") if not params_list: # Do not attack application-type files if not "content-type" in resp_headers: # Sometimes there's no content-type... so we rely on the document extension if (page.split(".")[-1] not in self.allowed) and page[-1] != "/": return elif not "text" in resp_headers["content-type"]: return url = page + "?" + payload if url not in self.attackedGET: evil_req = HTTP.HTTPResource(url) if self.verbose == 2: print(u"+ {0}".format(evil_req.url)) try: resp = self.HTTP.send(evil_req, headers=headers) if "wapiti" in resp.getHeaders(): self.logVuln(category=Vulnerability.CRLF, level=Vulnerability.HIGH_LEVEL, request=evil_req, info=self.MSG_VULN + " " + _("(QUERY_STRING)")) self.logR(Vulnerability.MSG_QS_INJECT, self.MSG_VULN, page) self.logR(Vulnerability.MSG_EVIL_URL, url) except requests.exceptions.Timeout: self.logAnom(category=Anomaly.RES_CONSUMPTION, level=Anomaly.MEDIUM_LEVEL, request=evil_req, info=self.MSG_VULN + " " + _("(QUERY_STRING)")) self.logO(Anomaly.MSG_TIMEOUT, page) self.logO(Anomaly.MSG_EVIL_URL, url) except requests.exceptions.HTTPError: # print("Error: The server did not understand this request") pass self.attackedGET.append(url) else: for i in range(len(params_list)): saved_value = params_list[i][1] # payload is already escaped, see at top params_list[i][1] = payload param_name = self.HTTP.quote(params_list[i][0]) url = page + "?" + self.HTTP.encode(params_list) if url not in self.attackedGET: self.attackedGET.append(url) evil_req = HTTP.HTTPResource(url) if self.verbose == 2: print(u"+ {0}".format(evil_req.url)) try: resp = self.HTTP.send(evil_req, headers=headers) if "wapiti" in resp.getHeaders(): self.logVuln(category=Vulnerability.CRLF, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter=param_name, info=self.MSG_VULN + " (" + param_name + ")") self.logR(Vulnerability.MSG_PARAM_INJECT, self.MSG_VULN, page, param_name) self.logR(Vulnerability.MSG_EVIL_URL, url) except requests.exceptions.Timeout: self.logAnom(category=Anomaly.RES_CONSUMPTION, level=Anomaly.MEDIUM_LEVEL, request=evil_req, parameter=param_name, info="Timeout (" + param_name + ")") self.logO(Anomaly.MSG_TIMEOUT, page) self.logO(Anomaly.MSG_EVIL_URL, url) except requests.exceptions.HTTPError: self.log( _("Error: The server did not understand this request" )) params_list[i][1] = saved_value
def attackPOST(self, form): """This method performs the cross site scripting attack (XSS attack) with method POST""" page = form.url referer = form.referer headers = {} if referer: headers["referer"] = referer if page not in self.PHP_SELF: evil_req = None if page.endswith("/"): evil_req = HTTP.HTTPResource(page + self.php_self_payload) elif page.endswith(".php"): evil_req = HTTP.HTTPResource(page + "/" + self.php_self_payload) if evil_req: if self.verbose == 2: print(u"+ {0}".format(evil_req.url)) data, http_code = self.HTTP.send( evil_req, headers=headers).getPageCode() if self._validXSSContentType( evil_req) and self.php_self_check in data: self.logR(Vulnerability.MSG_PATH_INJECT, self.MSG_VULN, page) self.logR(Vulnerability.MSG_EVIL_URL, evil_req.url) self.logVuln( category=Vulnerability.XSS, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter="PHP_SELF", info= _("XSS vulnerability found via injection in the resource path" )) self.PHP_SELF.append(page) # copies get_params = form.get_params post_params = form.post_params file_params = form.file_params for params_list in [get_params, post_params, file_params]: for i in xrange(len(params_list)): param_name = self.HTTP.quote(params_list[i][0]) saved_value = params_list[i][1] if params_list is file_params: params_list[i][1] = ["_XSS__", params_list[i][1][1]] else: params_list[i][1] = "__XSS__" # We keep an attack pattern to be sure a given form won't be attacked on the same field several times attack_pattern = HTTP.HTTPResource(form.path, method=form.method, get_params=get_params, post_params=post_params, file_params=file_params) if not attack_pattern in self.attackedPOST: self.attackedPOST.append(attack_pattern) code = self.random_string() if params_list is file_params: params_list[i][1][0] = code else: params_list[i][1] = code # will only memorize the last used payload (working or not) but the code will always be the good test_payload = HTTP.HTTPResource(form.path, method=form.method, get_params=get_params, post_params=post_params, file_params=file_params, referer=referer) self.POST_XSS[code] = (test_payload, param_name) try: resp = self.HTTP.send(test_payload) data = resp.getPage() except requests.exceptions.Timeout, timeout: data = "" resp = timeout # rapid search on the code to check injection if code in data: # found, now study where the payload is injected and how to exploit it payloads = self.generate_payloads(data, code) for payload in payloads: if params_list is file_params: params_list[i][1][0] = payload else: params_list[i][1] = payload evil_req = HTTP.HTTPResource( form.path, method=form.method, get_params=get_params, post_params=post_params, file_params=file_params, referer=referer) if self.verbose == 2: print(u"+ {0}".format(evil_req)) try: resp = self.HTTP.send(evil_req) dat = resp.getPage() except requests.exceptions.Timeout, timeout: dat = "" resp = timeout if self._validXSSContentType( evil_req ) and dat is not None and len(dat) > 1: if payload.lower() in dat.lower(): self.SUCCESSFUL_XSS[code] = payload self.logVuln( category=Vulnerability.XSS, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter=param_name, info=_( "XSS vulnerability found via injection" " in the parameter {0}").format( param_name)) self.logR(Vulnerability.MSG_PARAM_INJECT, self.MSG_VULN, evil_req.url, param_name) self.logR(Vulnerability.MSG_EVIL_REQUEST) self.logC(evil_req.http_repr) print('') # Stop injecting payloads and move to the next parameter break # restore the saved parameter in the list params_list[i][1] = saved_value
def attackGET(self, http_res): """This method performs the cross site scripting attack (XSS attack) with method GET""" # copies page = http_res.path params_list = http_res.get_params resp_headers = http_res.headers referer = http_res.referer headers = {} if referer: headers["referer"] = referer # Some PHP scripts doesn't sanitize data coming from $_SERVER['PHP_SELF'] if page not in self.PHP_SELF: evil_req = None if page.endswith("/"): evil_req = HTTP.HTTPResource(page + self.php_self_payload) elif page.endswith(".php"): evil_req = HTTP.HTTPResource(page + "/" + self.php_self_payload) if evil_req is not None: if self.verbose == 2: print(u"+ {0}".format(evil_req.url)) data, http_code = self.HTTP.send( evil_req, headers=headers).getPageCode() if self._validXSSContentType( evil_req) and self.php_self_check in data: self.logR(Vulnerability.MSG_PATH_INJECT, self.MSG_VULN, page) self.logR(Vulnerability.MSG_EVIL_URL, evil_req.url) self.logVuln( category=Vulnerability.XSS, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter="PHP_SELF", info= _("XSS vulnerability found via injection in the resource path" )) self.PHP_SELF.append(page) # page is the url of the script # params_list is a list of [key, value] lists if not params_list: # Do not attack application-type files if not "content-type" in resp_headers: # Sometimes there's no content-type... so we rely on the document extension if (page.split(".")[-1] not in self.allowed) and page[-1] != "/": return elif not "text" in resp_headers["content-type"]: return url = page + "?__XSS__" if url not in self.attackedGET: self.attackedGET.append(url) code = self.random_string() test_url = HTTP.HTTPResource(page + "?" + code) self.GET_XSS[code] = (test_url, "QUERY_STRING") try: resp = self.HTTP.send(test_url, headers=headers) data = resp.getPage() except requests.exceptions.Timeout: data = "" resp = None if code in data: payloads = self.generate_payloads(data, code) for payload in payloads: evil_req = HTTP.HTTPResource(page + "?" + self.HTTP.quote(payload)) if self.verbose == 2: print(u"+ {0}".format(evil_req)) try: resp = self.HTTP.send(evil_req, headers=headers) dat = resp.getPage() except requests.exceptions.Timeout, timeout: dat = "" resp = timeout param_name = "QUERY_STRING" if self._validXSSContentType( evil_req) and dat is not None and len(dat) > 1: if payload.lower() in dat.lower(): self.SUCCESSFUL_XSS[code] = payload self.logVuln( category=Vulnerability.XSS, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter=param_name, info= _("XSS vulnerability found via injection in the query string" )) self.logR(Vulnerability.MSG_QS_INJECT, self.MSG_VULN, page) self.logR(Vulnerability.MSG_EVIL_URL, evil_req.url) # No more payload injection break
def attackGET(self, http_res): """This method performs the SQL Injection attack with method GET""" page = http_res.path params_list = http_res.get_params resp_headers = http_res.headers referer = http_res.referer headers = {} if referer: headers["referer"] = referer # about this payload : http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string payload = "\xBF'\"(" vuln_found = 0 if not params_list: # Do not attack application-type files if not "content-type" in resp_headers: # Sometimes there's no content-type... so we rely on the document extension if (page.split(".")[-1] not in self.allowed) and page[-1] != "/": return elif not "text" in resp_headers["content-type"]: return err = "" payload = self.HTTP.quote(payload) url = page + "?" + payload if url not in self.attackedGET: self.attackedGET.append(url) evil_req = HTTP.HTTPResource(url) if self.verbose == 2: print(u"+ {0}".format(url)) try: resp = self.HTTP.send(evil_req, headers=headers) data, code = resp.getPageCode() except requests.exceptions.Timeout, timeout: # No timeout report here... launch blind sql detection later data = "" code = "408" err = "" resp = timeout else: err = self.__findPatternInResponse(data) if err != "": vuln_found += 1 self.logVuln( category=Vulnerability.SQL_INJECTION, level=Vulnerability.HIGH_LEVEL, request=evil_req, info=_("{0} via injection in the query string").format( err)) self.logR(Vulnerability.MSG_QS_INJECT, err, page) self.logR(Vulnerability.MSG_EVIL_URL, evil_req.url) self.vulnerableGET.append(page + "?" + "__SQL__") else: if code == "500": self.logAnom(category=Anomaly.ERROR_500, level=Anomaly.HIGH_LEVEL, request=evil_req, info=Anomaly.MSG_QS_500) self.logO(Anomaly.MSG_500, page) self.logO(Anomaly.MSG_EVIL_URL, evil_req.url)
# No more payload injection break # URL contains parameters else: for i in xrange(len(params_list)): saved_value = params_list[i][1] param_name = self.HTTP.quote(params_list[i][0]) params_list[i][1] = "__XSS__" url = page + "?" + self.HTTP.encode(params_list) if url not in self.attackedGET: self.attackedGET.append(url) code = self.random_string() params_list[i][1] = code test_url = HTTP.HTTPResource(page + "?" + self.HTTP.encode(params_list)) self.GET_XSS[code] = (test_url, param_name) try: resp = self.HTTP.send(test_url, headers=headers) data = resp.getPage() except requests.exceptions.Timeout, timeout: data = "" resp = timeout # is the random code on the webpage ? if code in data: # YES! But where exactly ? payloads = self.generate_payloads(data, code) for payload in payloads: params_list[i][1] = payload
info=Anomaly.MSG_QS_500) self.logO(Anomaly.MSG_500, page) self.logO(Anomaly.MSG_EVIL_URL, evil_req.url) else: for i in range(len(params_list)): err = "" param_name = self.HTTP.quote(params_list[i][0]) saved_value = params_list[i][1] params_list[i][1] = "__SQL__" pattern_url = page + "?" + self.HTTP.encode(params_list) if pattern_url not in self.attackedGET: self.attackedGET.append(pattern_url) params_list[i][1] = self.HTTP.quote(payload) url = page + "?" + self.HTTP.encode(params_list) evil_req = HTTP.HTTPResource(url) if self.verbose == 2: print(u"+ {0}".format(evil_req.url)) try: resp = self.HTTP.send(evil_req, headers=headers) data, code = resp.getPageCode() except requests.exceptions.Timeout, timeout: # No timeout report here... launch blind sql detection later data = "" code = "408" err = "" resp = timeout else: err = self.__findPatternInResponse(data) if err != "":
def attackPOST(self, form): """This method performs the SQL Injection attack with method POST""" payload = "\xbf'\"(" filename_payload = "'\"(" err = "" # copies get_params = form.get_params post_params = form.post_params file_params = form.file_params referer = form.referer for params_list in [get_params, post_params, file_params]: for i in xrange(len(params_list)): saved_value = params_list[i][1] if params_list is file_params: params_list[i][1] = ["_SQL__", params_list[i][1][1]] else: params_list[i][1] = "__SQL__" param_name = self.HTTP.quote(params_list[i][0]) attack_pattern = HTTP.HTTPResource(form.path, method=form.method, get_params=get_params, post_params=post_params, file_params=file_params) if attack_pattern not in self.attackedPOST: self.attackedPOST.append(attack_pattern) if params_list is file_params: params_list[i][1][0] = filename_payload else: params_list[i][1] = payload evil_req = HTTP.HTTPResource(form.path, method=form.method, get_params=get_params, post_params=post_params, file_params=file_params, referer=referer) if self.verbose == 2: print(u"+ {0}".format(evil_req)) try: resp = self.HTTP.send(evil_req) data, code = resp.getPageCode() except requests.exceptions.Timeout, timeout: # No timeout report here... launch blind sql detection later data = "" code = "408" resp = timeout else: err = self.__findPatternInResponse(data) if err != "": self.logVuln( category=Vulnerability.SQL_INJECTION, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter=param_name, info=_("{0} via injection in the parameter {1}" ).format(err, param_name)) self.logR(Vulnerability.MSG_PARAM_INJECT, err, evil_req.url, param_name) self.logR(Vulnerability.MSG_EVIL_REQUEST) self.logC(evil_req.http_repr) print('') self.vulnerablePOST.append(attack_pattern) else: if code == "500": self.logAnom( category=Anomaly.ERROR_500, level=Anomaly.HIGH_LEVEL, request=evil_req, parameter=param_name, info=Anomaly.MSG_PARAM_500.format(param_name)) self.logO(Anomaly.MSG_500, evil_req.url) self.logO(Anomaly.MSG_EVIL_REQUEST) self.logC(evil_req.http_repr) print('') params_list[i][1] = saved_value
def attackGET(self, http_res): """This method performs the file handling attack with method GET""" page = http_res.path params_list = http_res.get_params resp_headers = http_res.headers referer = http_res.referer headers = {} if referer: headers["referer"] = referer if not params_list: # Do not attack application-type files if not "content-type" in resp_headers: # Sometimes there's no content-type... so we rely on the document extension if (page.split(".")[-1] not in self.allowed) and page[-1] != "/": return elif not "text" in resp_headers["content-type"]: return timeouted = False warn = 0 inc = 0 err500 = 0 for payload in self.payloads: if "[VALUE]" in payload or "[DIRVALUE]" in payload or "[FILE_NAME]" in payload: continue err = "" url = page + "?" + self.HTTP.quote(payload) if url not in self.attackedGET: if self.verbose == 2: print(u"+ {0}".format(url)) self.attackedGET.append(url) evil_req = HTTP.HTTPResource(url) try: data, code = self.HTTP.send( evil_req, headers=headers).getPageCode() except requests.exceptions.Timeout: # Display a warning about timeout only once for a parameter if timeouted: continue data = "" code = "408" err = "" self.logAnom(category=Anomaly.RES_CONSUMPTION, level=Anomaly.MEDIUM_LEVEL, request=evil_req, info=Anomaly.MSG_QS_TIMEOUT) self.logO(Anomaly.MSG_TIMEOUT, page) self.logO(Anomaly.MSG_EVIL_URL, evil_req.url) timeouted = True else: err, inc, warn = self.__findPatternInResponse( data, warn) if err != "": self.logVuln( category=Vulnerability.FILE_HANDLING, level=Vulnerability.HIGH_LEVEL, request=evil_req, info=_("{0} via injection in the query string" ).format(err)) self.logR(Vulnerability.MSG_QS_INJECT, err) self.logR(Vulnerability.MSG_EVIL_URL) if inc: break else: if code == "500" and err500 == 0: err500 = 1 self.logAnom(category=Anomaly.ERROR_500, level=Anomaly.HIGH_LEVEL, request=evil_req, info=Anomaly.MSG_QS_500) self.logO(Anomaly.MSG_500, evil_req.path) self.logO(Anomaly.MSG_EVIL_URL, evil_req.url) for i in range(len(params_list)): timeouted = False warn = 0 inc = 0 err500 = 0 param_name = self.HTTP.quote(params_list[i][0]) saved_value = params_list[i][1] for payload in self.payloads: err = "" payload = payload.replace('[VALUE]', saved_value) payload = payload.replace('[DIRVALUE]', saved_value.rsplit('/', 1)[0]) payload = payload.replace('[FILE_NAME]', http_res.file_name) params_list[i][1] = self.HTTP.quote(payload) url = page + "?" + self.HTTP.encode(params_list) if url not in self.attackedGET: if self.verbose == 2: print(u"+ {0}".format(url)) self.attackedGET.append(url) evil_req = HTTP.HTTPResource(url) try: data, code = self.HTTP.send( evil_req, headers=headers).getPageCode() except requests.exceptions.Timeout: if timeouted: continue data = "" code = "408" err = "" self.logAnom( category=Anomaly.RES_CONSUMPTION, level=Anomaly.MEDIUM_LEVEL, request=evil_req, parameter=param_name, info=Anomaly.MSG_PARAM_TIMEOUT.format(param_name)) self.logO(Anomaly.MSG_TIMEOUT, page) self.logO(Anomaly.MSG_EVIL_URL, evil_req.url) timeouted = True else: err, inc, warn = self.__findPatternInResponse( data, warn) if err != "": self.logVuln( category=Vulnerability.FILE_HANDLING, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter=param_name, info=_("{0} via injection in the parameter {1}" ).format(err, param_name)) self.logR(Vulnerability.MSG_PARAM_INJECT, err, page, param_name) self.logR(Vulnerability.MSG_EVIL_URL, evil_req.url) if inc: break else: if code == "500" and err500 == 0: err500 = 1 self.logAnom( category=Anomaly.ERROR_500, level=Anomaly.HIGH_LEVEL, request=evil_req, parameter=param_name, info=Anomaly.MSG_PARAM_500.format(param_name)) self.logO(Anomaly.MSG_500, evil_req.path) self.logO(Anomaly.MSG_EVIL_URL, evil_req.url) params_list[i][1] = saved_value
def attackPOST(self, form): """This method performs the file handling attack with method POST""" # copies get_params = form.get_params post_params = form.post_params file_params = form.file_params referer = form.referer err = "" for params_list in [get_params, post_params, file_params]: for i in xrange(len(params_list)): timeouted = False warn = 0 inc = 0 err500 = 0 saved_value = params_list[i][1] param_name = self.HTTP.quote(params_list[i][0]) if params_list is file_params: params_list[i][1] = ["_FILE__", params_list[i][1][1]] else: params_list[i][1] = "__FILE__" attack_pattern = HTTP.HTTPResource(form.path, method=form.method, get_params=get_params, post_params=post_params, file_params=file_params) if attack_pattern not in self.attackedPOST: self.attackedPOST.append(attack_pattern) for payload in self.payloads: payload = payload.replace('[FILE_NAME]', form.file_name) if params_list is file_params: payload = payload.replace('[VALUE]', saved_value[0]) payload = payload.replace( '[DIRVALUE]', saved_value[0].rsplit('/', 1)[0]) params_list[i][1][0] = payload else: payload = payload.replace('[VALUE]', saved_value) payload = payload.replace( '[DIRVALUE]', saved_value.rsplit('/', 1)[0]) params_list[i][1] = payload evil_req = HTTP.HTTPResource(form.path, method=form.method, get_params=get_params, post_params=post_params, file_params=file_params, referer=referer) if self.verbose == 2: print(u"+ {0}".format(evil_req)) try: data, code = self.HTTP.send(evil_req).getPageCode() except requests.exceptions.Timeout: if timeouted: continue data = "" code = "408" self.logAnom(category=Anomaly.RES_CONSUMPTION, level=Anomaly.MEDIUM_LEVEL, request=evil_req, parameter=param_name, info=Anomaly.MSG_PARAM_TIMEOUT.format( param_name)) self.logO(Anomaly.MSG_TIMEOUT, evil_req.path) self.logO(Anomaly.MSG_EVIL_REQUEST) self.logC(evil_req.http_repr) print('') timeouted = True else: err, inc, warn = self.__findPatternInResponse( data, warn) if err != "": info_msg = _( "{0} via injection in the parameter {1}") self.logVuln(category=Vulnerability.FILE_HANDLING, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter=param_name, info=info_msg.format(err, param_name)) self.logR(Vulnerability.MSG_PARAM_INJECT, err, evil_req.url, param_name) self.logR(Vulnerability.MSG_EVIL_REQUEST) self.logC(evil_req.http_repr) print('') if inc: break else: if code == "500" and err500 == 0: err500 = 1 self.logAnom(category=Anomaly.ERROR_500, level=Anomaly.HIGH_LEVEL, request=evil_req, parameter=param_name, info=Anomaly.MSG_PARAM_500.format( param_name)) self.logO(Anomaly.MSG_500, evil_req.url) self.logO(Anomaly.MSG_EVIL_REQUEST) self.logC(evil_req.http_repr) print('') params_list[i][1] = saved_value
def attackGET(self, http_res): """This method performs the Blind SQL attack with method GET""" page = http_res.path params_list = http_res.get_params resp_headers = http_res.headers referer = http_res.referer headers = {} if referer: headers["referer"] = referer if not params_list: # Do not attack application-type files if not "content-type" in resp_headers: # Sometimes there's no content-type... so we rely on the document extension if (page.split(".")[-1] not in self.allowed) and page[-1] != "/": return elif not "text" in resp_headers["content-type"]: return pattern_url = page + "?__SQL__" if pattern_url in self.excludedGET: return if pattern_url not in self.attackedGET: self.attackedGET.append(pattern_url) err500 = 0 for payload in self.blind_sql_payloads: if "[VALUE]" in payload: continue payload = self.HTTP.quote( payload.replace("__TIME__", self.TIME_TO_SLEEP)) url = page + "?" + payload evil_req = HTTP.HTTPResource(url) if self.verbose == 2: print(u"+ {0}".format(evil_req.url)) try: resp = self.HTTP.send(evil_req, headers=headers) data, code = resp.getPageCode() except requests.exceptions.Timeout: self.logVuln( category=Vulnerability.BLIND_SQL_INJECTION, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter="QUERY_STRING", info=_("{0} via injection in the query string" ).format(self.MSG_VULN)) self.logR(Vulnerability.MSG_QS_INJECT, self.MSG_VULN, page) self.logR(Vulnerability.MSG_EVIL_URL, evil_req.url) break else: if code == "500" and err500 == 0: err500 = 1 self.logAnom(category=Anomaly.ERROR_500, level=Anomaly.HIGH_LEVEL, request=evil_req, parameter="QUERY_STRING", info=Anomaly.MSG_QS_500) self.logO(Anomaly.MSG_500, page) self.logO(Anomaly.MSG_EVIL_URL, evil_req.url) else: for i in range(len(params_list)): saved_value = params_list[i][1] param_name = self.HTTP.quote(params_list[i][0]) params_list[i][1] = "__SQL__" pattern_url = page + "?" + self.HTTP.encode(params_list) # This field was successfully attacked with a non-blind SQL injection if pattern_url in self.excludedGET: params_list[i][1] = saved_value continue if pattern_url not in self.attackedGET: self.attackedGET.append(pattern_url) err500 = 0 for payload in self.blind_sql_payloads: payload = payload.replace("[VALUE]", saved_value) params_list[i][1] = self.HTTP.quote( payload.replace("__TIME__", self.TIME_TO_SLEEP)) url = page + "?" + self.HTTP.encode(params_list) evil_req = HTTP.HTTPResource(url) if self.verbose == 2: print(u"+ {0}".format(evil_req.url)) try: resp = self.HTTP.send(evil_req, headers=headers) data, code = resp.getPageCode() except requests.exceptions.Timeout: self.logVuln( category=Vulnerability.BLIND_SQL_INJECTION, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter=param_name, info=_("{0} via injection in " "the parameter {1}").format( self.MSG_VULN, param_name)) self.logR(Vulnerability.MSG_PARAM_INJECT, self.MSG_VULN, page, param_name) self.logR(Vulnerability.MSG_EVIL_URL, evil_req.url) # One payload worked. Now jum to next field break else: if code == "500" and err500 == 0: err500 = 1 self.logAnom(category=Anomaly.ERROR_500, level=Anomaly.HIGH_LEVEL, request=evil_req, parameter=param_name, info=Anomaly.MSG_PARAM_500.format( param_name)) self.logO(Anomaly.MSG_500, page) self.logO(Anomaly.MSG_EVIL_URL, evil_req.url) params_list[i][1] = saved_value
def attackPOST(self, form): """This method performs the Blind SQL attack with method POST""" # copies get_params = form.get_params post_params = form.post_params file_params = form.file_params referer = form.referer for params_list in [get_params, post_params, file_params]: for i in xrange(len(params_list)): saved_value = params_list[i][1] param_name = self.HTTP.quote(params_list[i][0]) if params_list is file_params: params_list[i][1] = ["_SQL__", params_list[i][1][1]] else: params_list[i][1] = "__SQL__" attack_pattern = HTTP.HTTPResource(form.path, method=form.method, get_params=get_params, post_params=post_params, file_params=file_params) if attack_pattern in self.excludedPOST: params_list[i][1] = saved_value continue err500 = 0 if attack_pattern not in self.attackedPOST: self.attackedPOST.append(attack_pattern) for payload in self.blind_sql_payloads: if params_list is file_params: payload = payload.replace("[VALUE]", saved_value[0]) params_list[i][1][0] = payload.replace( "__TIME__", self.TIME_TO_SLEEP) else: payload = payload.replace("[VALUE]", saved_value) params_list[i][1] = payload.replace( "__TIME__", self.TIME_TO_SLEEP) evil_req = HTTP.HTTPResource(form.path, method=form.method, get_params=get_params, post_params=post_params, file_params=file_params, referer=referer) if self.verbose == 2: print(u"+ {0}".format(evil_req)) try: resp = self.HTTP.send(evil_req) data, code = resp.getPageCode() except requests.exceptions.Timeout: # Timeout means time-based SQL injection self.logVuln( category=Vulnerability.BLIND_SQL_INJECTION, level=Vulnerability.HIGH_LEVEL, request=evil_req, parameter=param_name, info=_("{0} via injection in the " "parameter {1}").format( self.MSG_VULN, param_name)) self.logR(Vulnerability.MSG_PARAM_INJECT, self.MSG_VULN, evil_req.url, param_name) self.logR(Vulnerability.MSG_EVIL_REQUEST) self.logC(evil_req.http_repr) print('') break else: if code == "500" and err500 == 0: err500 = 1 self.logAnom(category=Anomaly.ERROR_500, level=Anomaly.HIGH_LEVEL, request=evil_req, parameter=param_name, info=Anomaly.MSG_PARAM_500.format( param_name)) self.logO(Anomaly.MSG_500, evil_req.url) self.logO(Anomaly.MSG_EVIL_REQUEST) self.logC(evil_req.http_repr) print('') params_list[i][1] = saved_value
# Search for permanent XSS vulns which were injected via GET if self.doGET == 1: for code in self.GET_XSS: if code in data: # code found in the webpage ! code_url = self.GET_XSS[code][0].url page = self.GET_XSS[code][0].path param_name = self.GET_XSS[code][1] if code in self.SUCCESSFUL_XSS: # is this an already known vuln (reflected XSS) if self.validXSS(data, code, self.SUCCESSFUL_XSS[code]): # if we can find the payload again, this is a stored XSS evil_req = HTTP.HTTPResource( code_url.replace( code, self.SUCCESSFUL_XSS[code])) if param_name == "QUERY_STRING": self.logR(Vulnerability.MSG_QS_INJECT, self.MSG_VULN, page) else: self.logR(Vulnerability.MSG_PARAM_INJECT, self.MSG_VULN, page, param_name) self.logR(Vulnerability.MSG_EVIL_URL, code_url) self.logVuln( category=Vulnerability.XSS, level=Vulnerability.HIGH_LEVEL, request=evil_req, info=_("Found permanent XSS in {0}"