示例#1
0
    def run(self, info):

        m_return = []

        if info.has_url_params:
            #param_dict = info.url_params
            for k, v in info.url_params.iteritems():
                key = to_utf8(k)
                value = to_utf8(v)

                for cmd_inject_case in cmd_inject_detect_test_cases:
                    p = payload_muntants(info,
                                         payload={
                                             'k': k,
                                             'pos': 1,
                                             'payload':
                                             cmd_inject_case['input'],
                                             'type': 0
                                         },
                                         bmethod=info.method,
                                         timeout=30.0)

                    if cmd_inject_case['target'] is not None:
                        if p is not None:
                            __ = re.search(cmd_inject_case['target'], p.data)
                            if __ is not None:
                                logger.log_verbose('[+] found cmd inject!')
                                return m_return

        if info.has_post_params:
            #param_dict = info.post_params
            for k, v in info.post_params.iteritems():
                key = to_utf8(k)
                value = to_utf8(v)

                for cmd_inject_case in cmd_inject_detect_test_cases:
                    p = payload_muntants(info,
                                         payload={
                                             'k': k,
                                             'pos': 1,
                                             'payload':
                                             cmd_inject_case['input'],
                                             'type': 0
                                         },
                                         bmethod=info.method,
                                         timeout=30.0)

                    if cmd_inject_case['target'] is not None:
                        if p is not None:
                            __ = re.search(cmd_inject_case['target'], p.data)
                            if __ is not None:
                                logger.log_verbose('[+] found cmd inject!')
                                return m_return

        # Send the results
        return m_return
示例#2
0
    def run(self, info, **kwargs):
        #if not info.has_url_params and not info.has_post_params:
        #    return

        m_return = []

        if info.has_url_params:
            '''
            cookie_dict = Config.audit_config.cookie
            print cookie_dict
            if hasattr(cookie_dict, "iteritems"):
                    cookie_params = {
                        to_utf8(k): to_utf8(v) for k, v in cookie_dict.iteritems()
                    }
                    cookie_param = ';'.join(
                        '%s=%s' % (k ,v) for (k, v) in sorted(cookie_params.iteritems())
                    )

            print cookie_param
            print "GET"

            '''

            method = kwargs.get('method', None)
            if method is None or not isinstance(method, str):
                raise LalascanValueError("run plugin param has not method!")

            param = kwargs.get('param', None)
            if param is None or not isinstance(param, dict):
                raise LalascanValueError("run plugin param has not param!")

            for any_file_read_case in any_file_read_detect_test_cases:
                p, payload_resource = payload_muntants(
                    info,
                    payload={
                        'k': param['param_key'],
                        'pos': 1,
                        'payload': any_file_read_case['input'],
                        'type': 1
                    },
                    bmethod=method)
                if p is not None:
                    __ = re.search(any_file_read_case['target'], p.data)
                    if __ is not None:
                        vul = WebVulnerability(
                            target=payload_resource,
                            vulparam_point=param['param_key'],
                            method=method,
                            payload=any_file_read_case['input'],
                            injection_type="ANY_FILE_READ")
                        vulresult.put_nowait(vul)
                        logger.log_success(
                            '[!+>>>] found %s reflect xss vulnerable!' %
                            payload_resource.url)

                        return m_return

        # Send the results
        return m_return
示例#3
0
                def delay_for(original_wait_time, delay):
                    time_payload = timing_test_case_dict['input'].replace(
                        "rndstr",
                        rand_str).replace('duration',
                                          str(delay)).replace('val', v)

                    delta = original_wait_time * DELTA_PERCENT
                    upper_bound = (delay * 2) + original_wait_time + delta + 1
                    lower_bound = original_wait_time + delay - delta

                    try:
                        time_sleep_rsp, payload_resource = payload_muntants(
                            url_info=url,
                            payload={
                                'k': k,
                                'pos': 1,
                                'payload': time_payload,
                                'type': 0
                            },
                            bmethod=method,
                            use_cache=False,
                            timeout=30.0,
                            payload_encode=payload_encode)
                        current_response_wait_time = time_sleep_rsp.elapsed
                        rsp_delay = int(math.ceil(current_response_wait_time))
                        lower_bound = delay + self.normal_rsp_time_average - TIME_STDEV_COEFF * self.normal_rsp_time_stdev  #正态分布
                        if timing_test_case_dict['case_id'] == 1100020137:
                            print current_response_wait_time
                            print time_payload
                            print delay, rsp_delay, lower_bound
                        rsp_delay_ratio = rsp_delay / delay
                        return rsp_delay >= lower_bound, rsp_delay, rsp_delay_ratio, payload_resource

                        #if upper_bound > current_response_wait_time > lower_bound:
                        #    return True
                    except Exception, e:
                        return False, 0, 0
示例#4
0
    def xss_detect(self, url, method='GET', **kwargs):

        if not isinstance(url, URL):
            raise TypeError("Expected url type, type:%s" % type(url))

        k = kwargs.get("k", None)
        if k is None or not isinstance(k, str):
            raise ValueError("Except param has not key!")

        v = kwargs.get("v", None)

        for xss_test_case_dict in xss_reflection_detect_test_cases:
            #xss_test_case_dict = xss_reflection_detect_test_cases[12]

            rand_num = 900000000 + randint(1, 9999999)
            xss_payload = xss_test_case_dict['input'].replace(
                'rndstr', str(rand_num))
            xss_resp, payload_resource = payload_muntants(url,
                                                          payload={
                                                              'k': k,
                                                              'pos': 1,
                                                              'payload':
                                                              xss_payload,
                                                              'type': 1
                                                          },
                                                          bmethod=method)

            if xss_resp is None or xss_resp.data is None:
                return False, None

            tags_list, flags_list, targets_list = self._get_tags_flags(
                xss_test_case_dict['tag'], xss_test_case_dict['flag'],
                xss_test_case_dict['target'])
            flag_type = xss_test_case_dict['flag_type']
            compare = xss_test_case_dict['compare']

            for tag in tags_list:

                result = []

                for flag in flags_list:

                    #TODO BUG targets_list must be one
                    try:
                        assert len(targets_list) == 1
                        target = targets_list[0].replace(
                            'rndstr', str(rand_num))

                        #print tag , flag , flag_type , target, compare
                        ret_without_quote, txt_without_quote = self._search_in_html(
                            page=xss_resp.data,
                            tag=tag,
                            flag=flag,
                            flag_type=flag_type,
                            target=target,
                            compare=compare)

                        single_quote_closed = False
                        double_quote_closed = False
                        big_brace_closed = False
                        mid_brace_closed = False

                        if 'rndstr' in targets_list[0]:
                            single_quote_closed, double_quote_closed, big_brace_closed, mid_brace_closed = self._check_whether_quote_closed(
                                txt_without_quote, str(rand_num),
                                xss_test_case_dict['input'])
                        else:
                            single_quote_closed, double_quote_closed, big_brace_closed, mid_brace_closed = self._check_whether_quote_closed(
                                txt_without_quote, targets_list[0],
                                xss_test_case_dict['input'])

                        if txt_without_quote is not None:
                            if compare == 'match':
                                rgx = 'lt;\s*%s\s*>' % tag
                                if re.search(
                                        rgx, txt_without_quote
                                ) is not None or single_quote_closed == False or double_quote_closed == False:
                                    ret_without_quote = 0

                        if ret_without_quote > 0:
                            result.append(flag)

                    except AssertionError:
                        logger.log_verbose("targets list length must bu one!")
                        return False

                if len(result) > 0:

                    vul = WebVulnerability(target=payload_resource,
                                           vulparam_point=k,
                                           method=method,
                                           payload=xss_payload,
                                           injection_type="REFLECT_XSS")
                    vulresult.put_nowait(vul)
                    logger.log_success(
                        '[!+>>>] found %s reflect xss vulnerable!' %
                        payload_resource.url)

                    return True

        return False
示例#5
0
    def _boolean_sql_detect(self, **kwargs):
        '''
        bool 型注入探测(盲注)
        :return:
        '''
        k = kwargs.get("k", None)
        if k is None or not isinstance(k, str):
            raise ValueError("Except param has not key!")

        v = kwargs.get("v", None)

        url = kwargs.get("url", None)
        if url is None or not isinstance(url, URL):
            raise ValueError("Except param has not req_uri")

        method = kwargs.get('method', None)
        #TODO method str

        for boolean_test_case_dict in sql_inject_detect_boolean_test_cases:
            rand_num = randint(10, 9999)
            true_case = boolean_test_case_dict['true_case'].replace(
                "val", str(v)).replace("num", str(rand_num))
            false_case = boolean_test_case_dict['false_case'].replace(
                "val", str(v)).replace("num", str(rand_num))
            confirm_true_case = boolean_test_case_dict[
                'confirm_true_case'].replace("val", str(v)).replace(
                    "num", str(rand_num))
            confirm_false_case = boolean_test_case_dict[
                'confirm_false_case'].replace("val", str(v)).replace(
                    "num", str(rand_num))

            body_true_response = ""
            body_false_response = ""
            try:
                body_true_resp, payload_resource = payload_muntants(
                    url_info=url,
                    payload={
                        'k': k,
                        'pos': 1,
                        'payload': true_case,
                        'type': 1
                    },
                    bmethod=method)
                if body_true_resp is not None:
                    body_true_response = body_true_resp.data

                body_false_resp, _ = payload_muntants(url_info=url,
                                                      payload={
                                                          'k': k,
                                                          'pos': 1,
                                                          'payload':
                                                          false_case,
                                                          'type': 1
                                                      },
                                                      bmethod=method)
                if body_false_resp is not None:
                    body_false_response = body_false_resp.data

                self.add_normal_rsp_time(body_true_resp.elapsed)
            except AttributeError:
                continue

            if body_true_response == body_false_response:
                continue

            compare_diff = False
            #print 'Comparing body_true_response and body_false_response.'
            if self.__equal_with_limit(body_true_response, body_false_response,
                                       compare_diff):

                compare_diff = True

            body_confirm_true_response = ""
            body_confirm_false_response = ""
            try:
                body_confirm_true_resp, _ = payload_muntants(
                    url_info=url,
                    payload={
                        'k': k,
                        'pos': 1,
                        'payload': confirm_true_case,
                        'type': 1
                    },
                    bmethod=method)
                body_confirm_true_response = body_confirm_true_resp.data if body_confirm_true_resp is not None else None

                body_confirm_false_resp, _ = payload_muntants(
                    url_info=url,
                    payload={
                        'k': k,
                        'pos': 1,
                        'payload': confirm_false_case,
                        'type': 1
                    },
                    bmethod=method)
                body_confirm_false_response = body_confirm_false_resp.data if body_confirm_false_resp is not None else None
            except AttributeError:
                continue

            if self.__equal_with_limit(body_true_response,
                                       body_confirm_false_response,
                                       compare_diff):
                continue

            if not self.__equal_with_limit(body_confirm_true_response,
                                           body_true_response, compare_diff):
                continue

            if self.__equal_with_limit(body_confirm_false_response,
                                       body_false_response, compare_diff):

                vulresult.put_nowait(
                    WebVulnerability(target=payload_resource,
                                     vulparam_point=k,
                                     method=method,
                                     payload=true_case,
                                     injection_type="SQLI"))
                logger.log_success(
                    '[!+>>>] found %s boolean sql inject vulnerable!' %
                    payload_resource.url)
                return True

        return False
示例#6
0
    def _union_sql_detect(self, **kwargs):
        '''
        union 注入
        :param kwargs:
        :return:
        '''
        k = kwargs.get("k", None)
        if k is None or not isinstance(k, str):
            raise ValueError("Except param has not key!")

        v = kwargs.get("v", None)

        url = kwargs.get("url", None)
        if url is None or not isinstance(url, URL):
            raise ValueError("Except param has not req_uri")

        method = kwargs.get('method', None)

        max_column = 20
        orig_rsp = request_muntants(url=url, allow_redirects=False)

        if orig_rsp is None or orig_rsp.status != '200':
            return False

        union_payload = None
        table_columns = 0
        first_union_payload_rsp_data = None

        for index in range(1, max_column):
            if index == 1:
                union_payload = " union select 1"
            else:
                union_payload = "{0},{1}".format(union_payload, index)
            print union_payload

            union_payload_rsp, payload_resource = payload_muntants(
                url_info=url,
                payload={
                    'k': k,
                    'pos': 1,
                    'payload': union_payload,
                    'type': 0
                },
                bmethod=method)

            if union_payload_rsp is not None:
                if index == 1:
                    first_union_payload_rsp_data = union_payload_rsp.data

                else:
                    if (union_payload_rsp.data != first_union_payload_rsp_data
                        ) and (union_payload_rsp.data != orig_rsp.data):
                        #TODO Maybe WAF, union_payload_rsp.data != orig_rsp.data
                        if index == 2:
                            table_columns = [1, 2]
                        else:
                            table_columns = index
                        break
            else:
                break

        if table_columns != 0 and isinstance(table_columns, int):
            for inject_index in range(table_columns):
                union_list = [x + 1 for x in range(table_columns)]
                union_list[inject_index] = ORDER_BY_SIGN
                union_payload = ' union select {0}'.format(','.join(
                    map(str, union_list)))
                union_payload_rsp = None
                try:
                    union_payload_rsp, payload_resource = payload_muntants(
                        url_info=url,
                        payload={
                            'k': k,
                            'pos': 1,
                            'payload': union_payload,
                            'type': 0
                        },
                        bmethod=method,
                        use_cache=False)

                    if union_payload_rsp is not None and ORDER_BY_MD5_VAL in union_payload_rsp.data:
                        vulresult.put_nowait(
                            WebVulnerability(target=payload_resource,
                                             vulparam_point=k,
                                             method=method,
                                             payload=union_payload,
                                             injection_type="SQLI"))
                        logger.log_success(
                            '[!+>>>] found %s union_by sql inject vulnerable!'
                            % payload_resource.url)
                        return True

                except LalascanAttributeError:
                    return False
        elif isinstance(table_columns, list):
            union_payload_list = [
                ' union select {0}'.format(ORDER_BY_SIGN),
                ' union select {0},2'.format(ORDER_BY_SIGN),
                ' union select 1, {0}'.format(ORDER_BY_SIGN)
            ]
            for union_payload in union_payload_list:
                try:
                    union_payload_rsp, payload_resource = payload_muntants(
                        url_info=url,
                        payload={
                            'k': k,
                            'pos': 1,
                            'payload': union_payload,
                            'type': 0
                        },
                        bmethod=method,
                        use_cache=False)

                    if union_payload_rsp is not None and ORDER_BY_MD5_VAL in union_payload_rsp.data:
                        vulresult.put_nowait(
                            WebVulnerability(target=payload_resource,
                                             vulparam_point=k,
                                             method=method,
                                             payload=union_payload,
                                             injection_type="SQLI"))
                        logger.log_success(
                            '[!+>>>] found %s union_by sql inject vulnerable!'
                            % payload_resource.url)
                        return True

                except LalascanAttributeError:
                    continue
            return False
示例#7
0
    def _orderby_sql_detect(self, **kwargs):
        '''
        order by 注入
        :param kwargs:
        :return:
        '''
        k = kwargs.get("k", None)
        if k is None or not isinstance(k, str):
            raise ValueError("Except param has not key!")

        v = kwargs.get("v", None)

        url = kwargs.get("url", None)
        if url is None or not isinstance(url, URL):
            raise ValueError("Except param has not req_uri")

        method = kwargs.get('method', None)

        max_bound = 100
        min_bound = -1

        lower_index, high_index = 0, max_bound

        table_column = 0

        for keyword in ['or', 'and']:
            max_order_column_payload = ' {0} 1=2 order by {1}--'.format(
                keyword, max_bound)
            min_order_column_payload = ' {0} 1=2 order by {1}--'.format(
                keyword, min_bound)

            p = request_muntants(url=url, allow_redirects=False)

            if p is None or p.status != '200':
                return False

            orig_resp_body = p.data

            max_order_column_payload_rsp, _ = payload_muntants(
                url_info=url,
                payload={
                    'k': k,
                    'pos': 1,
                    'payload': max_order_column_payload,
                    'type': 0
                },
                bmethod=method)
            min_order_column_payload_rsp, _ = payload_muntants(
                url_info=url,
                payload={
                    'k': k,
                    'pos': 1,
                    'payload': min_order_column_payload,
                    'type': 0
                },
                bmethod=method)

            if max_order_column_payload_rsp is not None and min_order_column_payload_rsp is not None:
                self.add_normal_rsp_time(max_order_column_payload_rsp.elapsed)
            else:
                return False

            if max_order_column_payload_rsp.data != None and min_order_column_payload_rsp.data != None and (
                    orig_resp_body != max_order_column_payload_rsp.data) and (
                        orig_resp_body == min_order_column_payload_rsp.data):
                #maybe exist sql_inject

                while lower_index <= high_index:
                    #二分法
                    col = int(math.ceil((lower_index + high_index) / 2))
                    column_payload = ' order by {0}--'.format(col)
                    print column_payload
                    column_payload_rsp = None
                    column_payload_rsp, _ = payload_muntants(
                        url_info=url,
                        payload={
                            'k': k,
                            'pos': 1,
                            'payload': column_payload,
                            'type': 0
                        },
                        bmethod=method,
                        use_cache=False)

                    if column_payload_rsp != None and column_payload_rsp.data != orig_resp_body:
                        if (lower_index + 1) == high_index:
                            break
                        high_index = col
                    else:
                        if (lower_index + 1) == high_index:
                            table_column = lower_index
                            print '*' * 50
                            break
                        elif lower_index == high_index:
                            table_column = high_index
                            break
                        lower_index = col

            if table_column != 0:

                logger.log_verbose("[+!>>>] %s maybe has order by inject!" %
                                   url.url)
                for inject_index in range(table_column):
                    union_list = [x + 1 for x in range(table_column)]
                    union_list[inject_index] = ORDER_BY_SIGN
                    union_payload = ' {0} 1=2 union select {1}'.format(
                        keyword, ','.join(map(str, union_list)))
                    union_payload_rsp = None
                    try:
                        union_payload_rsp, payload_resource = payload_muntants(
                            url_info=url,
                            payload={
                                'k': k,
                                'pos': 1,
                                'payload': union_payload,
                                'type': 0
                            },
                            bmethod=method,
                            use_cache=False)

                        if union_payload_rsp is not None and ORDER_BY_MD5_VAL in union_payload_rsp.data:
                            vulresult.put_nowait(
                                WebVulnerability(target=payload_resource,
                                                 vulparam_point=k,
                                                 method=method,
                                                 payload=union_payload,
                                                 injection_type="SQLI"))
                            logger.log_success(
                                '[!+>>>] found %s order_by sql inject vulnerable!'
                                % payload_resource.url)
                            return True

                    except LalascanAttributeError:
                        return False

        return False
示例#8
0
    def deal_param_payload(self, sql_detect_type, url, method='GET', **kwargs):
        '''
        insert payload into param
        :return:
        '''

        if not isinstance(sql_detect_type, str):
            raise TypeError("Expected sql_detect_type string, type:%s" %
                            type(sql_detect_type))

        if not isinstance(url, URL):
            raise TypeError("Expected url type, type:%s" % type(url))

        #if not isinstance(param_dict, dict):
        #    raise TypeError("Expected param_dict string, type:%s" % type(param_dict))

        #if method == 'GET':
        #    param_dict = url.url_params
        #elif method == 'POST':
        #    param_dict = url.post_params

        param_dict = kwargs['param']

        is_timing_stable = True
        short_duration = 1

        def __check_if_rsp_stable_on_orig_input():
            p = request_muntants(url=url, allow_redirects=False)
            if p.status != '200':
                is_timing_stable = False

            orig_first_time = p.elapsed
            orig_first_resp_body = p.data

            time.sleep(2)

            p = request_muntants(url=url, allow_redirects=False)
            if p.status != '200':
                is_timing_stable = False

            orig_second_time = p.elapsed
            orig_second_resp_body = p.data

            min_resp_time = min(orig_first_time, orig_second_time)
            max_resp_time = max(orig_first_time, orig_second_time)

            short_duration = max(RSP_SHORT_DURATION, max_resp_time) + 1
            long_duration = short_duration * 2

            if (max_resp_time - min_resp_time) > short_duration:
                is_timing_stable = False
            else:
                is_timing_stable = True

            if orig_first_resp_body != orig_second_resp_body:
                is_timing_stable = False

        def __check_if_rsp_stable_on_invalid_input():
            #TODO judge url is stable
            is_timing_stable = True

        #__check_if_rsp_stable_on_orig_input()
        '''
        if sql_detect_type == "ERR_MSG_DETECT":
            for k,v in param_dict.iteritems():

                key = to_utf8(k)
                value = to_utf8(v)

                for test_case_dict in sql_inject_detect_err_msg_test_cases:

                    p, payload_resource = payload_muntants(url, payload = {'k': k , 'pos': 1, 'payload':test_case_dict['input'], 'type': 0}, bmethod = method)
                    if self._err_msg_sql_detect(p, test_case_dict['target']):
                        #print '[+] found sql inject in url:{0}, payload:{1}'.format(req_uri, payload_param_dict)
                        vulresult.put_nowait(WebVulnerability(target = payload_resource, vulparam_point = key, method = method, payload = test_case_dict['input'], injection_type = "SQLI"))

                        logger.log_success('[!+>>>] found %s err_msg sql inject vulnerable!' % payload_resource.url)
                        return True

        elif sql_detect_type == 'ORDER_BY_DETECT':
            for k, v in param_dict.iteritems():

                key = to_utf8(k)
                value = to_utf8(v)

                if self._orderby_sql_detect(k = key, v = value , url = url, method = method):
                    return True


        elif sql_detect_type == "ECHO_DETECT":
            self._echo_sql_detect()

        elif sql_detect_type == "BOOLEAN_DETECT":
            print '----------- BOOLEAN_DETECT -----------------------'
            for k, v in param_dict.iteritems():

                key = to_utf8(k)
                value = to_utf8(v)

                if self._boolean_sql_detect(k = key, v = value , url = url, method = method):
                   return True

        elif sql_detect_type == "TIMING_DETECT":
            print '-----------TIMING_DETECT -----------------------'

            if is_timing_stable == True:
                for k, v in param_dict.iteritems():

                    key = to_utf8(k)
                    value = to_utf8(v)
                    if self._timing_sql_detect(k = k, v = value, url = url, method = method, short_duration = short_duration):
                        #print '[+] found time_based sql inject!'
                        return True

        '''
        if sql_detect_type == "ERR_MSG_DETECT":
            for test_case_dict in sql_inject_detect_err_msg_test_cases:
                p, payload_resource = payload_muntants(
                    url,
                    payload={
                        'k': param_dict['param_key'],
                        'pos': 1,
                        'payload': test_case_dict['input'],
                        'type': 0
                    },
                    bmethod=method)
                if self._err_msg_sql_detect(p, test_case_dict['target']):
                    #print '[+] found sql inject in url:{0}, payload:{1}'.format(req_uri, payload_param_dict)
                    vulresult.put_nowait(
                        WebVulnerability(
                            target=payload_resource,
                            vulparam_point=param_dict['param_key'],
                            method=method,
                            payload=test_case_dict['input'],
                            injection_type="SQLI"))
                    logger.log_success(
                        '[!+>>>] found %s err_msg sql inject vulnerable!' %
                        payload_resource.url)
                    return True

        elif sql_detect_type == "ORDER_BY_DETECT":
            if self._orderby_sql_detect(k=param_dict['param_key'],
                                        v=param_dict['param_value'],
                                        url=url,
                                        method=method):
                return True

        elif sql_detect_type == "UNION_BY_DETECT":
            if self._union_sql_detect(k=param_dict['param_key'],
                                      v=param_dict['param_value'],
                                      url=url,
                                      method=method):
                return True

        elif sql_detect_type == "ECHO_DETECT":
            self._echo_sql_detect()

        elif sql_detect_type == "BOOLEAN_DETECT":
            print '----------- BOOLEAN_DETECT -----------------------'

            if self._boolean_sql_detect(k=param_dict['param_key'],
                                        v=param_dict['param_value'],
                                        url=url,
                                        method=method):
                return True

        elif sql_detect_type == "TIMING_DETECT":
            print '-----------TIMING_DETECT -----------------------'

            if self._timing_sql_detect(k=param_dict['param_key'],
                                       v=param_dict['param_value'],
                                       url=url,
                                       method=method,
                                       short_duration=short_duration):
                #print '[+] found time_based sql inject!'
                return True