Пример #1
0
    def test_directory(self, path):
        if self.verbose == 2:
            print(u"+ Testing directory {0}".format(path))
        test_page = HTTP.HTTPResource(path + "does_n0t_exist.htm")
        try:
            resp = self.HTTP.send(test_page)
            if resp.getCode() not in ["403", "404"]:
                # we don't want to deal with this at the moment
                return
            for i, candidate in enumerate(self.payloads):
                self.pbar.update(i + 1)
                url = path + candidate
                if url not in self.known_dirs and url not in self.known_pages and url not in self.new_resources:
                    page = HTTP.HTTPResource(path + candidate)
                    try:
                        resp = self.HTTP.send(page)
                        if resp.getCode() == "301":
                            loc = resp.getLocation()
                            if loc in self.known_dirs or loc in self.known_pages:
                                continue
                            self.logR("Found webpage {0}", loc)
                            self.new_resources.append(loc)
                        elif resp.getCode() not in ["403", "404"]:
                            self.logR("Found webpage {0}", page.path)
                            self.new_resources.append(page.path)
                    except requests.exceptions.Timeout:
                        continue

        except requests.exceptions.Timeout:
            pass
Пример #2
0
 def addStartURL(self, url):
     if self.__checklink(url):
         print(_("Invalid link argument: {0}").format(url))
         sys.exit(0)
     if self.__inzone(url) == 0:
         self.tobrowse.append(HTTP.HTTPResource(url))
     else:
         self.out_of_scope_urls.append(HTTP.HTTPResource(url))
Пример #3
0
    def attack(self, urls, forms):
        junk_string = "w" + "".join([random.choice("0123456789abcdefghjijklmnopqrstuvwxyz") for __ in range(0, 5000)])
        for l in self.nikto_db:
            match = match_or = match_and = False
            fail = fail_or = False

            osv_id = l[1]
            path = l[3]
            method = l[4]
            vuln_desc = l[10]
            post_data = l[11]

            path = path.replace("@CGIDIRS", "/cgi-bin/")
            path = path.replace("@ADMIN", "/admin/")
            path = path.replace("@NUKE", "/modules/")
            path = path.replace("@PHPMYADMIN", "/phpMyAdmin/")
            path = path.replace("@POSTNUKE", "/postnuke/")
            path = re.sub("JUNK\((\d+)\)", lambda x: junk_string[:int(x.group(1))], path)

            if path[0] == "@":
                continue
            if path[0] != "/":
                path = "/" + path

            url = ""
            try:
                url = "http://" + self.HTTP.server + path
            except UnicodeDecodeError:
                continue

            evil_req = None

            if method == "GET":
                evil_req = HTTP.HTTPResource(url)
            elif method == "POST":
                evil_req = HTTP.HTTPResource(url, post_params=post_data, method=method)
            else:
                evil_req = HTTP.HTTPResource(url, post_params=post_data, method=method)

            if self.verbose == 2:
                try:
                    if method == "GET":
                        print(u"+ {0}".format(evil_req.url))
                    else:
                        print(u"+ {0}".format(evil_req.http_repr))
                except Exception, e:
                    continue

            try:
                resp = self.HTTP.send(evil_req)
            except Exception, e:
                # requests bug
                print(e)
                continue
Пример #4
0
    def attackGET(self, http_res):
        url = http_res.path
        resp_headers = http_res.headers
        referer = http_res.referer
        headers = {}
        if referer:
            headers["referer"] = referer

        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":
                test_req = HTTP.HTTPResource(url)
                data1 = self.HTTP.send(test_req, 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)

                    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)
Пример #5
0
    def __init__(self, http, xmlRepGenerator):
        Attack.__init__(self, http, xmlRepGenerator)
        user_config_dir = os.getenv('HOME') or os.getenv('USERPROFILE')
        user_config_dir += "/config"
        if not os.path.isdir(user_config_dir):
            os.makedirs(user_config_dir)
        try:
            fd = open(os.path.join(user_config_dir, self.CONFIG_FILE))
            reader = csv.reader(fd)
            self.nikto_db = [l for l in reader if l != [] and l[0].isdigit()]
            fd.close()
        except IOError:
            try:
                print(_("Problem with local nikto database."))
                print(_("Downloading from the web..."))
                nikto_req = HTTP.HTTPResource("http://cirt.net/nikto/UPDATES/2.1.5/db_tests")
                resp = self.HTTP.send(nikto_req)
                page = resp.getRawPage()

                csv.register_dialect("nikto", quoting=csv.QUOTE_ALL, doublequote=False, escapechar="\\")
                reader = csv.reader(page.split("\n"), "nikto")
                self.nikto_db = [l for l in reader if l != [] and l[0].isdigit()]

                fd = open(os.path.join(user_config_dir, self.CONFIG_FILE), "w")
                writer = csv.writer(fd)
                writer.writerows(self.nikto_db)
                fd.close()
            except socket.timeout:
                print(_("Error downloading Nikto database"))
Пример #6
0
 def attack(self, get_resources, forms):
     """This method searches XSS which could be permanently stored in the web application"""
     for http_resource in get_resources:
         if http_resource.method != "GET":
             continue
         url = http_resource.url
         target_req = HTTP.HTTPResource(url)
         referer = http_resource.referer
         headers = {}
         if referer:
             headers["referer"] = referer
         if self.verbose >= 1:
             print(u"+ {0}".format(url))
         try:
             resp = self.HTTP.send(target_req, headers=headers)
             data = resp.getPage()
         except requests.exceptions.Timeout:
             data = ""
         except socket.error, se:
             data = ""
             print(
                 _('error: {0} while attacking {1}').format(
                     repr(str(se[1])), url))
         except Exception, e:
             print(
                 _('error: {0} while attacking {1}').format(
                     repr(str(e[0])), url))
             continue
Пример #7
0
    def browse(self, web_resource):
        """Extract urls from a webpage and add them to the list of urls
        to browse if they aren't in the exclusion list.
        Returns True if the URL is kept for attacks."""

        # We are going too much deep, don't browse this link
        if web_resource.link_depth > self.max_link_depth:
            return False

        url = web_resource.url

        # We don't need destination anchors
        current_full_url = url.split("#")[0]
        # Url without query string
        current = current_full_url.split("?")[0]
        # Get the dirname of the file
        currentdir = web_resource.dir_name
        parrentdir = web_resource.parent_dir

        # Timeout must not be too long to block big documents
        # (for example a download script)
        # and not too short to give good results
        socket.setdefaulttimeout(self.timeout)

        if parrentdir not in self.custom_404:
            invalid_res = HTTP.HTTPResource(parrentdir + self.invalid_page)
            try:
                invalid_resp = self.h.send(invalid_res)
                invalid_code = invalid_resp.getCode()
                self.custom_404[parrentdir] = invalid_code
            except socket.error:
                pass

        try:
            resp = self.h.send(web_resource)
        except socket.timeout:
            self.excluded.append(url)
            return False
        except requests.exceptions.Timeout:
            self.excluded.append(url)
            return False
        except socket.error, msg:
            if msg.errno == 111:
                print(_("Connection refused!"))
            self.excluded.append(url)
            return False
Пример #8
0
    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.to_browse:
                self.to_browse.append(http_res)
            else:
                if self.method == "GET":
                    self.browsed_links.append(http_res)
                elif self.method == "POST":
                    self.browsed_forms.append(http_res)
Пример #9
0
    def __init__(self, root, http_engine=None):
        self.h = http_engine
        if root.startswith("-"):
            print(_("First argument must be the root url !"))
            sys.exit(0)
        if not "://" in root:
            root = "http://" + root
        if self.__checklink(root):
            print(_("Invalid protocol: {0}").format(root.split("://")[0]))
            sys.exit(0)
        if root[-1] != "/" and not "/" in root.split("://")[1]:
            root += "/"

        self.out_of_scope_urls = []
        self.browsed_links = []
        self.proxies = {}
        self.excluded = []
        self.browsed_forms = []
        self.uploads = []

        self.verbose = 0
        self.auth_basic = []
        self.bad_params = []
        self.timeout = 6.0
        self.global_headers = {}
        self.cookiejar = None
        self.scope = "folder"
        self.link_encoding = {}
        self.custom_404 = {}
        self.invalid_page = "zqxj{0}.html".format("".join(
            [choice(ascii_letters) for __ in xrange(0, 10)]))

        # 0 means no limits
        self.nice = 0
        self.max_link_depth = 40

        server = (root.split("://")[1]).split("/")[0]
        self.root = HTTP.HTTPResource(root)  # Initial URL
        self.server = server  # Domain (with potential :port)
        self.scope_url = root  # Scope of the analysis

        self.tobrowse = [self.root]
        self.persister = CrawlerPersister()
Пример #10
0
    def __init__(self, root, http_engine=None, crawlerFile=None):
        self.h = http_engine
        if root.startswith("-"):
            print(_("First argument must be the root url !"))
            sys.exit(0)
        if not "://" in root:
            root = "http://" + root
        if (self.__checklink(root)):
            print(_("Invalid protocol: {0}").format(root.split("://")[0]))
            sys.exit(0)
        if root[-1] != "/" and not "/" in root.split("://")[1]:
            root += "/"

        server = (root.split("://")[1]).split("/")[0]
        self.root = HTTP.HTTPResource(root)  # Initial URL
        self.server = server  # Domain
        self.scopeURL = root  # Scope of the analysis

        self.tobrowse.append(self.root)
        self.persister = CrawlerPersister()
Пример #11
0
    def attackGET(self, http_res):
        if http_res.file_name == "":
            return

        page = http_res.path
        headers = http_res.headers

        # Do not attack application-type files
        if not "content-type" in 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 headers["content-type"]:
            return

        for payload in self.payloads:
            payload = payload.replace("[FILE_NAME]", http_res.file_name)
            url = page.replace(http_res.file_name, payload)

            if self.verbose == 2:
                print(u"+ {0}".format(url))

            if url not in self.attackedGET:
                self.attackedGET.append(url)
                try:
                    evil_req = HTTP.HTTPResource(url)

                    resp = self.HTTP.send(evil_req)
                    data, code = resp.getPageCode()
                    err = self.__returnErrorByCode(code)
                    if err == "ok":
                        self.logR(_("Found backup file !"))
                        self.logR(u"    -> {0}".format(evil_req.url))
                        self.logVuln(category=Vulnerability.BACKUP,
                                     level=Vulnerability.HIGH_LEVEL,
                                     request=evil_req,
                                     info=_("Backup file {0} found for {1}").format(url, page))

                except socket.timeout:
                    break
Пример #12
0
    def attackGET(self, http_res):
        url = http_res.path

        if self.verbose == 2:
            print(u"+ {0}".format(url))

        if url not in self.attackedGET:
            self.attackedGET.append(url)
            try:
                evil_req = HTTP.HTTPResource(url)

                resp = self.HTTP.send(evil_req, headers=self.hdrs)
                data, code = resp.getPageCode()
                if "".join(self.random_bytes) in data:
                    self.logR(_("URL {0} seems vulnerable to Shellshock attack !").format(url))

                    self.logVuln(category=Vulnerability.EXEC,
                                 level=Vulnerability.HIGH_LEVEL,
                                 request=evil_req,
                                 info=_("URL {0} seems vulnerable to Shellshock attack").format(url))

            except socket.timeout:
                return
Пример #13
0
    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 = {}
        http_code = ""
        if referer:
            headers["referer"] = referer

        param_name = "PHP_SELF"

        # 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))
                try:
                    data, http_code = self.HTTP.send(evil_req, headers=headers).getPageCode()
                except requests.exceptions.Timeout:
                    data = ""
                    self.logO(Anomaly.MSG_TIMEOUT, evil_req.url)
                    self.logO(Anomaly.MSG_EVIL_REQUEST)
                    self.logC(evil_req.http_repr)
                    print('')
                    self.logAnom(category=Anomaly.RES_CONSUMPTION,
                                 level=Anomaly.MEDIUM_LEVEL,
                                 request=evil_req,
                                 parameter=param_name,
                                 info=Anomaly.MSG_PARAM_TIMEOUT.format(param_name))

                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=param_name,
                                 info=_("XSS vulnerability found via injection in the resource path"))
                elif http_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(Vulnerability.MSG_EVIL_REQUEST)
                    self.logC(evil_req.http_repr)
                    print('')
            self.PHP_SELF.append(page)

        timeouted = False
        returned500 = False

        # 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_req = HTTP.HTTPResource(page + "?" + code)
                self.GET_XSS[code] = (test_req, "QUERY_STRING")
                try:
                    data, http_code = self.HTTP.send(test_req, headers=headers).getPageCode()
                except requests.exceptions.Timeout:
                    data = ""

                if code in data:
                    # Simple text injection worked, let's try with JS code
                    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:
                            dat, http_code = self.HTTP.send(evil_req, headers=headers).getPageCode()
                        except requests.exceptions.Timeout:
                            dat = ""
                            if timeouted:
                                continue
                            self.logO(Anomaly.MSG_TIMEOUT, evil_req.url)
                            self.logO(Anomaly.MSG_EVIL_REQUEST)
                            self.logC(evil_req.http_repr)
                            print('')
                            self.logAnom(category=Anomaly.RES_CONSUMPTION,
                                         level=Anomaly.MEDIUM_LEVEL,
                                         request=evil_req,
                                         parameter=param_name,
                                         info=Anomaly.MSG_PARAM_TIMEOUT.format(param_name))
                            timeouted = True
                        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

                        elif http_code == "500" and not returned500:
                            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(Vulnerability.MSG_EVIL_REQUEST)
                            self.logC(evil_req.http_repr)
                            print('')
                            returned500 = True

        # URL contains parameters
        else:
            for i in xrange(len(params_list)):
                saved_value = params_list[i][1]
                if saved_value is None:
                    saved_value = ""
                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_req = HTTP.HTTPResource(page + "?" + self.HTTP.encode(params_list))
                    self.GET_XSS[code] = (test_req, param_name)
                    try:
                        data, http_code = self.HTTP.send(test_req, headers=headers).getPageCode()
                    except requests.exceptions.Timeout:
                        data = ""
                    # 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

                            evil_req = HTTP.HTTPResource(page + "?" + self.HTTP.encode(params_list))
                            if self.verbose == 2:
                                print(u"+ {0}".format(evil_req))
                            try:
                                dat, http_code = self.HTTP.send(evil_req, headers=headers).getPageCode()
                            except requests.exceptions.Timeout:
                                dat = ""
                                if timeouted:
                                    continue
                                self.logO(Anomaly.MSG_TIMEOUT, evil_req.url)
                                self.logO(Anomaly.MSG_EVIL_REQUEST)
                                self.logC(evil_req.http_repr)
                                print('')
                                self.logAnom(category=Anomaly.RES_CONSUMPTION,
                                             level=Anomaly.MEDIUM_LEVEL,
                                             request=evil_req,
                                             parameter=param_name,
                                             info=Anomaly.MSG_PARAM_TIMEOUT.format(param_name))
                                timeouted = True

                            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,
                                              page,
                                              param_name)

                                    self.logR(Vulnerability.MSG_EVIL_URL, evil_req.url)
                                    # stop trying payloads and jum to the next parameter
                                    break
                            elif http_code == "500" and not returned500:
                                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(Vulnerability.MSG_EVIL_REQUEST)
                                self.logC(evil_req.http_repr)
                                print('')
                                returned500 = True

                # Restore the value of this argument before testing the next one
                params_list[i][1] = saved_value
Пример #14
0
    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 saved_value is None:
                    saved_value = ""

                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
                        code = "408"
                    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
Пример #15
0
    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'\"("

        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

            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:
                    # No timeout report here... launch blind sql detection later
                    code = "408"
                    err = ""
                else:
                    err = self.__findPatternInResponse(data)
                if err != "":
                    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)
        else:
            for i in range(len(params_list)):
                param_name = self.HTTP.quote(params_list[i][0])
                saved_value = params_list[i][1]
                if saved_value is None:
                    saved_value = ""
                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:
                        # No timeout report here... launch blind sql detection later
                        code = "408"
                        err = ""
                    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,
                                  page,
                                  param_name)
                        self.logR(Vulnerability.MSG_EVIL_URL, evil_req.url)
                        self.vulnerableGET.append(pattern_url)

                    elif 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, page)
                            self.logO(Anomaly.MSG_EVIL_URL, evil_req.url)
                params_list[i][1] = saved_value
Пример #16
0
                        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]
                if saved_value is None:
                    saved_value = ""
                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 != "":
Пример #17
0
    def attackGET(self, http_res):

        dir_name = http_res.dir_name
        headers = http_res.headers

        for payload in self.payloads:
            if self.verbose == 2:
                print(u"+ {0} detecting...".format(payload['title']))
            for rule in payload['rules']:
                for case in switch(rule['type']):
                    if self.verbose == 2:
                        print(u"  type: {0}".format(rule['type']))
                    if case(1):
                        url = dir_name
                        if self.verbose == 2:
                            print(u"  name: {0}".format(rule['name']))
                            print(u"  url: {0}".format(url))
                            print(u"  matching pattern: {0}".format(
                                rule['match']))
                            print("")
                        try:
                            #data = requests.get(url, allow_redirects=True)
                            evil_req = HTTP.HTTPResource(url)

                            resp = self.HTTP.send(evil_req)
                            data, code = resp.getPageCode()

                            err = self.__returnErrorByCode(code)
                            if err == "ok":
                                d = pq(data)
                                for element in d(''.join([
                                        rule['name'], "[", rule['attributes'],
                                        "]"
                                ])).items():
                                    if re.search(
                                            rule['match'].lower(),
                                            element.attr(rule['attributes']).
                                            lower()) is not None:
                                        self.logR(_("Found fingerprint !"))
                                        self.logR(u"    -> {0}".format(
                                            evil_req.url))
                                        self.logR("Framework: {0} !".format(
                                            payload['title'])
                                                  )  # wait to internalization
                                        self.logVuln(
                                            category=Vulnerability.FINGERPRINT,
                                            level=Vulnerability.LOW_LEVEL,
                                            request=evil_req,
                                            info=_("Framework {0} used in {1}"
                                                   ).format(
                                                       payload['title'],
                                                       dir_name))
                                        self.fingerprint_flag = True
                                        #err = self.__findPatternInResponse(d.text())
                                        return
                            elif err == "Moved":
                                self.logR(
                                    "This site might be moved to \"{0}\". Try again."
                                    .format(
                                        requests.get(
                                            url, allow_redirects=True).url))
                                self.fingerprint_flag = True
                                return
                        except socket.timeout:
                            break
                        break
                    if case(3):
                        if rule['name'] == "URL":
                            url = dir_name + rule['attributes']
                            if self.verbose == 2:
                                print(u"  name: {0}".format(rule['name']))
                                print(u"  url: {0}".format(url))
                                print(u"  matching pattern: {0}".format(
                                    rule['match']))
                                print("")
                            try:
                                evil_req = HTTP.HTTPResource(url)

                                resp = self.HTTP.send(evil_req)
                                data, code = resp.getPageCode()

                                err = self.__returnErrorByCode(code)
                                if err == "ok":
                                    d = pq(data)
                                    if rule['match'] in d.text():
                                        self.logR(_("Found fingerprint !"))
                                        self.logR(u"    -> {0}".format(
                                            evil_req.url))
                                        self.logR("Framework: {0} !".format(
                                            payload['title'])
                                                  )  # wait to internalization
                                        self.logVuln(
                                            category=Vulnerability.FINGERPRINT,
                                            level=Vulnerability.LOW_LEVEL,
                                            request=evil_req,
                                            info=_("Framework {0} used in {1}"
                                                   ).format(
                                                       payload['title'],
                                                       dir_name))
                                        self.fingerprint_flag = True
                                        #err = self.__findPatternInResponse(d.text())
                                        return
                            except socket.timeout:
                                break
                        else:
                            url = dir_name
                            if self.verbose == 2:
                                print(u"  name: {0}".format(rule['name']))
                                print(u"  url: {0}".format(url))
                                print(
                                    u"  matching pattern: {0} in html tag '{1}'"
                                    .format(rule['match'], rule['name']))
                                print("")
                            try:
                                #data = requests.get(url, allow_redirects=True)
                                evil_req = HTTP.HTTPResource(url)

                                resp = self.HTTP.send(evil_req)
                                data, code = resp.getPageCode()

                                err = self.__returnErrorByCode(code)
                                if err == "ok":
                                    d = pq(data)
                                    if re.search(rule['match'],
                                                 d(rule['name']).text()
                                                 ) is not None:
                                        self.logR(_("Found fingerprint !"))
                                        self.logR(u"    -> {0}".format(
                                            evil_req.url))
                                        self.logR("Framework: {0} !".format(
                                            payload['title'])
                                                  )  # wait to internalization
                                        self.logVuln(
                                            category=Vulnerability.FINGERPRINT,
                                            level=Vulnerability.LOW_LEVEL,
                                            request=evil_req,
                                            info=_("Framework {0} used in {1}"
                                                   ).format(
                                                       payload['title'],
                                                       dir_name))
                                        self.fingerprint_flag = True
                                        #err = self.__findPatternInResponse(d.text())
                                        return
                                elif err == "Moved":
                                    self.logR(
                                        "This site might be moved to \"{0}\". Try again."
                                        .format(
                                            requests.get(
                                                url,
                                                allow_redirects=True).url))
                                    self.fingerprint_flag = True
                                    return
                            except socket.timeout:
                                break
                        break
                    if case(8):
                        break
Пример #18
0
                try:
                    flash_parser = swf_parser.swf_parser(data)
                    swf_links = flash_parser.getLinks()
                except Exception, err_data:
                    swf_links = err_data[1]
            elif "/x-javascript" in mime_type or "/x-js" in mime_type or "/javascript" in mime_type:
                js_links = lamejs.lamejs(data).getLinks()
            data = ""

        # Manage redirections
        if "location" in info:
            redir = self.correctlink(info["location"], current, current_full_url, currentdir, proto, None)
            if redir is not None:
                if self.__inzone(redir) == 0:
                    self.link_encoding[redir] = self.link_encoding[url]
                    redir = HTTP.HTTPResource(redir, link_depth=current_depth+1)
                    # Is the document not visited yet and not forbidden ?
                    if (redir not in self.browsed_links and
                        redir not in self.tobrowse and
                            not self.isExcluded(redir)):
                        self.tobrowse.append(redir)

        if not web_resource.is_root and self.custom_404.get(parrentdir, "404") == code:
            self.excluded.append(url)
            return False

        html_source = data
        bs = BeautifulSoup(html_source)
        # Look for a base tag with an href attribute
        if bs.head:
            for base in bs.head.findAll("base"):
Пример #19
0
    def attackPOST(self, form):
        """This method performs the command execution 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]
                if saved_value is None:
                    saved_value = ""
                timeouted = False
                warned = 0
                cmd = 0
                err500 = 0
                param_name = self.HTTP.quote(params_list[i][0])

                if params_list is file_params:
                    params_list[i][1] = ["_EXEC__", params_list[i][1][1]]
                else:
                    params_list[i][1] = "__EXEC__"

                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:
                        # no quoting: send() will do it for us
                        if params_list is file_params:
                            payload = payload.replace("[VALUE]", saved_value[0])
                            params_list[i][1][0] = payload
                        else:
                            payload = payload.replace("[VALUE]", saved_value)
                            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))
                        err = ""
                        try:
                            data, code = self.HTTP.send(evil_req).getPageCode()
                        except requests.exceptions.Timeout:
                            if timeouted:
                                continue
                            data = ""
                            code = "408"
                            self.logO(Anomaly.MSG_TIMEOUT, evil_req.url)
                            self.logO(Anomaly.MSG_EVIL_REQUEST)
                            self.logC(evil_req.http_repr)
                            print('')
                            self.logAnom(category=Anomaly.RES_CONSUMPTION,
                                         level=Anomaly.MEDIUM_LEVEL,
                                         request=evil_req,
                                         parameter=param_name,
                                         info=Anomaly.MSG_PARAM_TIMEOUT.format(param_name))
                            timeouted = True
                        else:
                            err, cmd, warned = self.__findPatternInResponse(data, warned)

                        if err != "":
                            self.logVuln(category=Vulnerability.EXEC,
                                         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('')

                            if cmd:
                                # Successful command execution, go to the 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, evil_req.url)
                                self.logO(Vulnerability.MSG_EVIL_REQUEST)
                                self.logC(evil_req.http_repr)
                                print('')
                params_list[i][1] = saved_value
Пример #20
0
    def attackGET(self, http_res):
        """This method performs the command execution 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
            warned = 0
            cmd = 0
            err500 = 0

            for payload in self.payloads:
                if "[VALUE]" in payload:
                    continue

                err = ""
                url = page + "?" + self.HTTP.quote(payload)

                if url not in self.attackedGET:
                    evil_req = HTTP.HTTPResource(url)
                    if self.verbose == 2:
                        print(u"+ {0}".format(url))
                    self.attackedGET.append(url)
                    try:
                        data, code = self.HTTP.send(evil_req, headers=headers).getPageCode()
                    except requests.exceptions.Timeout:
                        if timeouted:
                            continue
                        data = ""
                        code = "408"
                        err = ""
                        self.logO(Anomaly.MSG_TIMEOUT, page)
                        self.logO(Anomaly.MSG_EVIL_URL, evil_req.url)
                        self.logAnom(category=Anomaly.RES_CONSUMPTION,
                                     level=Anomaly.MEDIUM_LEVEL,
                                     request=evil_req,
                                     info=Anomaly.MSG_QS_TIMEOUT)
                        timeouted = True
                    else:
                        err, cmd, warned = self.__findPatternInResponse(data, warned)
                    if err != "":
                        self.logVuln(category=Vulnerability.EXEC,
                                     level=Vulnerability.HIGH_LEVEL,
                                     request=evil_req,
                                     info=Vulnerability.MSG_QS_INJECT.format(err, page))
                        self.logR(Vulnerability.MSG_QS_INJECT, err, page)
                        self.logR(Vulnerability.MSG_EVIL_URL, evil_req.url)
                    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, page)
                            self.logO(Anomaly.MSG_EVIL_URL, evil_req.url)
                    if cmd:
                        break

        for i in range(len(params_list)):
            timeouted = False
            warned = 0
            cmd = 0
            err500 = 0

            saved_value = params_list[i][1]
            if saved_value is None:
                saved_value = ""
            params_list[i][1] = "__EXEC__"
            url = page + "?" + self.HTTP.encode(params_list)
            param_name = self.HTTP.quote(params_list[i][0])

            if url not in self.attackedGET:
                self.attackedGET.append(url)

                for payload in self.payloads:
                    err = ""
                    payload = payload.replace("[VALUE]", saved_value)
                    params_list[i][1] = self.HTTP.quote(payload)
                    evil_req = HTTP.HTTPResource(page + "?" + self.HTTP.encode(params_list))

                    if self.verbose == 2:
                        print(u"+ {0}".format(evil_req.url))

                    try:
                        data, code = self.HTTP.send(evil_req, headers=headers).getPageCode()
                    except requests.exceptions.Timeout:
                        if timeouted:
                            continue
                        data = ""
                        code = "408"
                        err = ""
                        self.logO(Anomaly.MSG_TIMEOUT, page)
                        self.logO(Anomaly.MSG_EVIL_URL, evil_req.url)
                        self.logAnom(category=Anomaly.RES_CONSUMPTION,
                                     level=Anomaly.MEDIUM_LEVEL,
                                     request=evil_req,
                                     parameter=param_name,
                                     info=Anomaly.MSG_PARAM_TIMEOUT.format(param_name))
                        timeouted = True
                    else:
                        err, cmd, warned = self.__findPatternInResponse(data, warned)

                    if err != "":
                        self.logVuln(category=Vulnerability.EXEC,
                                     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 cmd:
                            # Successful command execution, go to the 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
Пример #21
0
    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: 2.3.0 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]
                if saved_value is None:
                    saved_value = ""
                # 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
Пример #22
0
    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]
                if saved_value is None:
                    saved_value = ""
                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
Пример #23
0
    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

        param_name = "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:
                if self.verbose == 2:
                    print(u"+ {0}".format(evil_req.url))
                try:
                    data, http_code = self.HTTP.send(evil_req, headers=headers).getPageCode()
                except requests.exceptions.Timeout:
                    data = ""
                    self.logO(Anomaly.MSG_TIMEOUT, evil_req.url)
                    self.logO(Anomaly.MSG_EVIL_REQUEST)
                    self.logC(evil_req.http_repr)
                    print('')
                    self.logAnom(category=Anomaly.RES_CONSUMPTION,
                                 level=Anomaly.MEDIUM_LEVEL,
                                 request=evil_req,
                                 parameter=param_name,
                                 info=Anomaly.MSG_PARAM_TIMEOUT.format(param_name))

                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=param_name,
                                 info=_("XSS vulnerability found via injection in the resource path"))
                elif http_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(Vulnerability.MSG_EVIL_REQUEST)
                    self.logC(evil_req.http_repr)
                    print('')
            self.PHP_SELF.append(page)

        timeouted = False
        returned500 = False

        # 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 saved_value is None:
                    saved_value = ""
                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:
                        data, http_code = self.HTTP.send(test_payload).getPageCode()
                    except requests.exceptions.Timeout:
                        data = ""
                    # 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:
                                dat, http_code = self.HTTP.send(evil_req).getPageCode()
                            except requests.exceptions.Timeout:
                                dat = ""
                                if timeouted:
                                    continue
                                self.logO(Anomaly.MSG_TIMEOUT, evil_req.url)
                                self.logO(Anomaly.MSG_EVIL_REQUEST)
                                self.logC(evil_req.http_repr)
                                print('')
                                self.logAnom(category=Anomaly.RES_CONSUMPTION,
                                             level=Anomaly.MEDIUM_LEVEL,
                                             request=evil_req,
                                             parameter=param_name,
                                             info=Anomaly.MSG_PARAM_TIMEOUT.format(param_name))
                                timeouted = True

                            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
                            elif http_code == "500" and not returned500:
                                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(Vulnerability.MSG_EVIL_REQUEST)
                                self.logC(evil_req.http_repr)
                                print('')
                                returned500 = True

                # restore the saved parameter in the list
                params_list[i][1] = saved_value
Пример #24
0
                                            param_name)
                                        if v == code:
                                            if params_list is file_params:
                                                params_list[i][1][
                                                    0] = self.SUCCESSFUL_XSS[
                                                        code]
                                            else:
                                                params_list[i][
                                                    1] = self.SUCCESSFUL_XSS[
                                                        code]

                                            # we found the xss payload again -> stored xss vuln
                                            evil_req = HTTP.HTTPResource(
                                                code_req.path,
                                                method="POST",
                                                get_params=get_params,
                                                post_params=post_params,
                                                file_params=file_params,
                                                referer=referer)

                                            self.logVuln(
                                                category=Vulnerability.XSS,
                                                level=Vulnerability.HIGH_LEVEL,
                                                request=evil_req,
                                                parameter=param_name,
                                                info=_(
                                                    "Found permanent XSS attacked by {0} with fields"
                                                    " {1}").format(
                                                        evil_req.url,
                                                        self.HTTP.encode(
                                                            post_params)))
Пример #25
0
class mod_permanentxss(Attack):
    """
    This class implements a cross site scripting attack
    """

    # magic strings we must see to be sure script is vulnerable to XSS
    # payloads must be created on those patterns
    script_ok = [
        "alert('__XSS__')", "alert(\"__XSS__\")",
        "String.fromCharCode(0,__XSS__,1)"
    ]

    # simple payloads that doesn't rely on their position in the DOM structure
    # payloads injected after closing a tag attribute value (attrval) or in the
    # content of a tag (text node like between <p> and </p>)
    # only trick here must be on character encoding, filter bypassing, stuff like that
    # form the simplest to the most complex, Wapiti will stop on the first working
    independant_payloads = []

    name = "permanentxss"
    require = ["xss"]
    PRIORITY = 6

    # two dict for permanent XSS scanning
    GET_XSS = {}
    POST_XSS = {}

    # key = xss code, valid = payload
    SUCCESSFUL_XSS = {}

    CONFIG_FILE = "xssPayloads.txt"

    MSG_VULN = _("Stored XSS vulnerability")

    def __init__(self, http, xmlRepGenerator):
        Attack.__init__(self, http, xmlRepGenerator)
        self.independant_payloads = self.loadPayloads(
            os.path.join(self.CONFIG_DIR, self.CONFIG_FILE))

    # permanent XSS
    def attack(self, get_resources, forms):
        """This method searches XSS which could be permanently stored in the web application"""
        for http_resource in get_resources:
            if http_resource.method != "GET":
                continue
            url = http_resource.url
            target_req = HTTP.HTTPResource(url)
            referer = http_resource.referer
            headers = {}
            if referer:
                headers["referer"] = referer
            if self.verbose >= 1:
                print(u"+ {0}".format(url))
            try:
                resp = self.HTTP.send(target_req, headers=headers)
                data = resp.getPage()
            except requests.exceptions.Timeout:
                data = ""
            except socket.error, se:
                data = ""
                print(
                    _('error: {0} while attacking {1}').format(
                        repr(str(se[1])), url))
            except Exception, e:
                print(
                    _('error: {0} while attacking {1}').format(
                        repr(str(e[0])), url))
                continue

            # 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}"
                                           " with {1}").format(
                                               page,
                                               self.HTTP.escape(evil_req.url)))
                                # we reported the vuln, now search another code
                                continue

                        # we where able to inject the ID but will we be able to inject javascript?
                        else:
                            timeouted = False
                            returned500 = False

                            for xss in self.independant_payloads:
                                payload = xss.replace("__XSS__", code)
                                evil_req = HTTP.HTTPResource(
                                    code_url.replace(code, payload))
                                try:
                                    http_code = self.HTTP.send(
                                        evil_req).getCode()
                                    dat = self.HTTP.send(target_req).getPage()
                                except requests.exceptions.Timeout:
                                    dat = ""
                                    if timeouted:
                                        continue
                                    self.logO(Anomaly.MSG_TIMEOUT,
                                              evil_req.url)
                                    self.logO(Anomaly.MSG_EVIL_REQUEST)
                                    self.logC(evil_req.http_repr)
                                    print('')
                                    self.logAnom(
                                        category=Anomaly.RES_CONSUMPTION,
                                        level=Anomaly.MEDIUM_LEVEL,
                                        request=evil_req,
                                        parameter=param_name,
                                        info=Anomaly.MSG_PARAM_TIMEOUT.format(
                                            param_name))
                                    timeouted = True

                                except Exception, e:
                                    print(
                                        _('error: {0} while attacking {1}').
                                        format(repr(str(e[0])), url))
                                    continue

                                if self.validXSS(dat, code, payload):
                                    # injection successful :)
                                    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,
                                              evil_req.url)

                                    self.logVuln(
                                        category=Vulnerability.XSS,
                                        level=Vulnerability.HIGH_LEVEL,
                                        request=evil_req,
                                        info=_("Found permanent XSS in {0}"
                                               " with {1}").format(
                                                   url,
                                                   self.HTTP.escape(
                                                       evil_req.url)))
                                    # look for another code in the webpage
                                    break
                                elif http_code == "500" and not returned500:
                                    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(Vulnerability.MSG_EVIL_REQUEST)
                                    self.logC(evil_req.http_repr)
                                    print('')
                                    returned500 = True
Пример #26
0
            # 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}"
Пример #27
0
    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]
                if saved_value is None:
                    saved_value = ""
                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
Пример #28
0
    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, page)
                        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,
                                         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]
            if saved_value is None:
                saved_value = ""
            params_list[i][1] = "__FILE__"
            url = page + "?" + self.HTTP.encode(params_list)

            if url not in self.attackedGET:
                self.attackedGET.append(url)
                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 self.verbose == 2:
                        print(u"+ {0}".format(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
Пример #29
0
    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]
                if saved_value is None:
                    saved_value = ""

                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
Пример #30
0
                    swf_links = flash_parser.getLinks()
                except Exception, err_data:
                    swf_links = err_data[1]
                data = ""
            elif "/x-javascript" in mime_type or "/x-js" in mime_type or "/javascript" in mime_type:
                js_links = lamejs.lamejs(data).getLinks()
                data = ""

        # Manage redirections
        if "location" in info:
            redir = self.correctlink(info["location"], current,
                                     current_full_url, currentdir, proto, None)
            if redir is not None:
                if self.__inzone(redir) == 0:
                    self.link_encoding[redir] = self.link_encoding[url]
                    redir = HTTP.HTTPResource(redir)
                    # Is the document already visited of forbidden ?
                    if (redir in self.browsed) or (redir in self.tobrowse) or \
                            self.isExcluded(redir):
                        pass
                    else:
                        # No -> Will browse it soon
                        self.tobrowse.append(redir)

        htmlSource = data
        if page_encoding:
            bs = BeautifulSoup.BeautifulSoup(htmlSource)
            # Look for a base tag with an href attribute
            if bs.head:
                baseTags = bs.head.findAll("base")
                for base in baseTags: