def version_check(): PYVERSION = sys.version.split()[0] if PYVERSION <= "3.4": msg = '''[CRITICAL] incompatible Python version detected ('%s'). For successfully running this project, you'll have to use version > 3.4.(visit 'http://www.python.org/download/')''' % PYVERSION logger.error(msg) common.scanner_status = False
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)
def queryTarget(payloadTemplate=None, replacements={}): if payloadTemplate: payload = payloadParser.renderValue(payloadTemplate, target.paramName, target.origValue, target.origValue_negative, replacements=replacements) payload = payloadParser.renderSQL(orig=payload, replacements=replacements) get = urlencode({target.paramName: payload}) url = target.url_without_testParam rn.lastQueryPayload = payload else: get = None url = target.originalUrl start = time.time() try: page, headers, code = connect.getPage(url=url, get=get, method=target.method) except ConnectionException as ex: logger.error('query target: ' + ex.msg) raise except DecodeError as ex: logger.error('query target: ' + ex.msg) raise queryDuration = time.time() - start return page, headers, code, queryDuration
def initOptions(): #init target if options.cmdArgs: dict_target = argumentParser.parseArgumentsToTarget(options.cmdArgs) if dict_target: for key in dict_target: setattr(target, key, dict_target[key]) #TODO if target.origValue.isdigit(): target.origValue_negative = '-{}'.format(randomInt()) else: target.origValue_negative = '' msg = '---\n' msg += 'Target:\n' msg += '\tUrl: {} ({})\n'.format(target.originalUrl, target.method) msg += '\tParameter:\n' msg += '\t\tName: {}\n'.format(target.paramName) msg += '\t\tOrigValue: {}\n'.format(target.origValue) msg += '\t\tOrigValue_negative: {}\n'.format( target.origValue_negative) msg += '---' logger.puts(msg) else: errorMsg = 'parse arguments failed' logger.error(errorMsg) raise QuitException else: errorMsg = 'options not found' logger.error(errorMsg) raise QuitException
def load_config(): with open(CHECK_CONF_FILE) as con: try: common.conf = json.load(con) return True except: logger.error("conf.json error, please download another one and replace it.") exit()
def load_modules(): _path = SCRIPT_PATH scanner.module_obj = [] if not used_pocs: msg = "No Poc scripts are loaded. Scanner Stopped." logger.error(msg) common.scanner_status = False for _name in used_pocs: __name = "script." + _name _load_module(__name, os.path.join(_path, _name) + ".py")
def check_requirements(): try: import tornado import redis import gevent import treelib import requests except ImportError as e: logger.error("Fail to import required libray."+str(e)) exit(0)
def create_scanner(): """ Main function of POC-T when running from command line. """ try: load_modules() scanner.controller = Controller() scanner.controller.run() except Exception: print(traceback.format_exc()) logger.error("Error in initializing the controller.")
def parse(self, result): request, module_name, module_info, scan_result = result[0], result[ 1], result[2], result[3] scanner.task_manager.update(request.id, module_name, "FINISHED") if scan_result["Success"]: self.process_vulnerability(request, module_name, module_info, scan_result) if scan_result["Error"]: msg = 'Error in Executing the %s poc for URL %s. Error Message is %s' % ( module_name, request.url, scan_result["Error"]) logger.error(msg)
def redis_connection_check(): try: redis.build_connection() except Exception as e: msg = "Fail to build connection with Redis. Please modify the configure file, check the redis status and " \ "restart. " logger.error(msg) return False else: logger.success("Build connection with redis") return True
def retrieve_request(self, request_id): _request = self.conn.hget("request", request_id) try: request = base64.b64decode(_request) request_decoded = request.decode("utf8", "ignore") except Exception as e: logger.error( "Error in decoding the request or getting the request : %s" % request_id) return None else: return [request_id, request_decoded]
def _load_module(_name, _path): msg = 'Load custom script: %s at %s' % (_name, _path) logger.success(msg) try: spec = imp.find_spec(_name, [_path]) module = imp.module_from_spec(spec) spec.loader.exec_module(module) module_check(module) scanner.module_obj.append(module) except ImportError as e: error_msg = "Fail to import [%s.py] at %s\n%s" \ % (_name, _path, '[Error Msg]: ' + str(e)) sys.exit(logger.error(error_msg)) except AttributeError as e: error_msg = "Fail to find [%s.py] at %s\n%s" \ % (_name, _path, '[Error Msg]: ' + str(e)) sys.exit(logger.error(error_msg))
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))
def get(self): try: request_hash = self.get_argument("hash") request = json.loads( base64.b64decode(redis.conn.hget("request", request_hash))) protocol = request['protocol'] port = request["port"] path = request['path'] host = request['host'] query = request['query'] packet = base64.b64decode(request['requestRaw']) request['url_encode'] = "" url = protocol + "://" + host + ":" + port + path + ( '?' + query if query != "" else "") return self.render("req.html", request=request, packet=packet, url=url) except Exception as e: logger.error(str(e)) return self.write(str(e))
def get(self): if "restore" in self.request.arguments: try: with open(DEFAULT_CONF_FILE, 'r') as handler: default_configuration = json.loads(handler.read()) update_config(default_configuration, CHECK_CONF_FILE) except Exception as e: logger.error("Fail to restore the default configuration.%s" % str(e)) update_config(common.conf, CHECK_CONF_FILE) else: common.conf = default_configuration logger.success("Restored default configuration.") scan_methods = {"GET": "", "POST": "", "DELETE": "", "PUT": ""} options = common.conf["scan_methods"].split(",") for m in options: if m.upper() in scan_methods: scan_methods[m] = "checked" return self.render("config.html", config=common.conf, scan_methods=scan_methods)
def module_check(module): for each in ESSENTIAL_MODULE_METHODS: if not hasattr(module, each): errorMsg = "Can't find essential method:'%s()' in %s script,Please modify your script/PoC." % ( each, module.__name__) sys.exit(logger.error(errorMsg)) for each in ESSENTIAL_POC_INFO: if not hasattr(module, each): errorMsg = "Can't find essential valuables:'%s' in %s script,Please modify your script/PoC." % ( each, module.__name__) sys.exit(logger.error(errorMsg)) # basic info must be defined : # module.poc_info, module.poc_info["poc"], module.poc_info["vul"], # module.poc_info["poc"]["Name"], module.poc_info["vul"]["Product"], module.poc_info["vul"]["Severity"] try: for each in ESSENTIAL_VALUABLES: eval("module.%s" % each) except Exception: errorMsg = "Can't find essential valuables:'%s' in %s script,Please modify your script/PoC." % ( each, module.__name__) sys.exit(logger.error(errorMsg)) return True
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
def get(self): try: score = self.get_argument("id") scan_result = json.loads( base64.b64decode( redis.conn.zrangebyscore("vulnerable", score, score)[0])) request_hash = scan_result["task_id"] vulnerability_severity = scan_result[ "vulnerability_severity"].lower() vulnerability_name = scan_result["vulnerability_name"] url = scan_result["url"] vulnerability_product = scan_result["vulnerability_product"] vulnerability_extra_info = scan_result["vulnerability_extra_info"] module_name = scan_result["module_name"] # raw packet request = json.loads( base64.b64decode(redis.conn.hget("request", request_hash))) packet = base64.b64decode(request['requestRaw']) # split the url in 80 chars url_encode = "" for i in range(int(len(url) / 80) + 1): url_encode += url[i * 80:i * 80 + 80] + "\n" return self.render( "bug.html", url=url, id=score, url_encode=url_encode, vulnerability_severity=vulnerability_severity, vulnerability_name=vulnerability_name, vulnerability_product=vulnerability_product, vulnerability_extra_info=vulnerability_extra_info, module_name=module_name, packet=packet) except Exception as e: logger.error(str(e)) return self.write(str(e))
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