def do_use(self, plugin): """ 加载插件 :param plugin: string, 插件名称 :return: """ #在use新插件的时候要清除已经设置的变量以及结果 initializeKb() ClearConf() kb.CurrentPlugin = plugin zsp = PluginBase(package='zsplugins') plugin_zsp = zsp.make_plugin_source( searchpath=[paths.ZEROSCAN_PLUGINS_PATH]) expNames = plugin_zsp.list_plugins() if kb.CurrentPlugin: if plugin in expNames: self.prompt = "ZEROScan exploit({color}{content}{color_reset}) > ".format( color=Fore.RED, content=kb.CurrentPlugin, color_reset=Fore.RESET) else: log.error("plugin is not exist!") else: log.error("use <plugin>")
def do_options(self, line): """ 插件设置项 :return: """ try: if kb.CurrentPlugin: rn = ShowOptions() if isinstance(rn, str): log.error(rn) else: l_ist = [] l_tmp = [] l_ist.append( list(("Name", "Current Setting", "Required", "Description"))) for option in rn: l_tmp.append(option["Name"]) l_tmp.append(option["Current Setting"]) l_tmp.append(option["Required"]) l_tmp.append(option["Description"]) l_ist.append(l_tmp) l_tmp = [] print print(tabulate(l_ist, headers="firstrow")) except: log.error("Select a plugin first.")
def _createTargetDirs(): """ Create the output directory. """ if not os.path.isdir(paths.ZEROSCAN_OUTPUT_PATH): try: if not os.path.isdir(paths.ZEROSCAN_OUTPUT_PATH): os.makedirs(paths.ZEROSCAN_OUTPUT_PATH, 0755) warnMsg = "using '%s' as the output directory" % paths.ZEROSCAN_OUTPUT_PATH log.error(warnMsg) except (OSError, IOError), ex: try: tempDir = tempfile.mkdtemp(prefix="ZEROScanoutput") except Exception, _: errMsg = "unable to write to the temporary directory ('%s'). " % _ errMsg += "Please make sure that your disk is not full and " errMsg += "that you have sufficient write permissions to " errMsg += "create temporary files and/or directories" raise ZEROScanSystemException(errMsg) warnMsg = "unable to create regular output directory " warnMsg += "'%s' (%s). " % (paths.ZEROSCAN_OUTPUT_PATH, getUnicode(ex)) warnMsg += "Using temporary directory '%s' instead" % getUnicode(tempDir) log.error(warnMsg) paths.POCUSITE_OUTPUT_PATH = tempDir
def do_options(self, line): """ 插件设置项 :return: """ try: if kb.CurrentPlugin: rn = ShowOptions() if isinstance(rn, str): log.error(rn) else: l_ist = [] l_tmp = [] l_ist.append(list(("Name","Current Setting", "Required", "Description"))) for option in rn: l_tmp.append(option["Name"]) l_tmp.append(option["Current Setting"]) l_tmp.append(option["Required"]) l_tmp.append(option["Description"]) l_ist.append(l_tmp) l_tmp = [] print print(tabulate(l_ist,headers="firstrow")) except: log.error("Select a plugin first.")
def do_run(self, line): """ 执行插件 :return: """ if kb.CurrentPlugin: ExecPlugin() else: log.error("Select a plugin first.")
def exceptionHandledFunction(threadFunction): try: threadFunction() except KeyboardInterrupt: kb.threadContinue = False kb.threadException = True raise except Exception, errMsg: # thread is just going to be silently killed log.error("thread %s: %s" % (threading.currentThread().getName(), errMsg))
def default(self, line): """ 无法识别命令时 :param line: :return: """ try: log.process("exec: %s" % line) SubCmd = subprocess.Popen(line, shell=True, stdout=subprocess.PIPE) print print SubCmd.communicate()[0] except: log.error("Unknown command: %s" % line)
def post(self, data): headers = { "Content-Type": "text/xml;charset=UTF-8", "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50" } payload = "/wls-wsat/CoordinatorPortType" vulnurl = self.url + payload try: req = requests.post(vulnurl, data=data, headers=headers, timeout=10, verify=False) except Exception: log.error("[-] Connection Error") if self.confirm_sucess(): self.result = "[!] %s is vuln" % vulnurl
def runThreads(numThreads, threadFunction, forwardException=True, startThreadMsg=True): threads = [] numThreads = int(numThreads) kb.multiThreadMode = True kb.threadContinue = True kb.threadException = False try: if numThreads > 1: if startThreadMsg: infoMsg = "starting %d threads" % numThreads log.process(infoMsg) else: threadFunction() return for numThread in xrange(numThreads): thread = threading.Thread(target=exceptionHandledFunction, name=str(numThread), args=[threadFunction]) setDaemon(thread) try: thread.start() except threadError, errMsg: errMsg = "error occurred while starting new thread ('%s')" % errMsg log.error(errMsg) break threads.append(thread) # And wait for them to all finish alive = True while alive: alive = False for thread in threads: if thread.isAlive(): alive = True time.sleep(0.1)
def setMultipleTarget(): #urlFile if not conf.urlFile: target_urls = [] if conf.url: if conf.url.endswith('/24'): try: socket.inet_aton(conf.url.split('/')[0]) base_addr = conf.url[:conf.url.rfind('.') + 1] target_urls = [ '{}{}'.format(base_addr, i) for i in xrange(1, 255 + 1) ] except socket.error: errMsg = 'only id address acceptable' log.error(errMsg) else: target_urls = conf.url.split(',') for url in target_urls: if url: kb.targets.put((url)) else: errMsg = 'the url needs to be set' log.error(errMsg) return if paths.ZEROSCAN_TARGET_PATH in conf.urlFile: conf.urlFile = safeExpandUser(conf.urlFile) infoMsg = "parsing multiple targets list from '%s'" % conf.urlFile log.process(infoMsg) else: conf.urlFile = paths.ZEROSCAN_TARGET_PATH + '/' + conf.urlFile conf.urlFile = safeExpandUser(conf.urlFile) infoMsg = "parsing multiple targets list from '%s'" % conf.urlFile log.process(infoMsg) if not os.path.isfile(conf.urlFile): errMsg = "the specified file does not exist" raise ZEROScanFilePathException(errMsg) for line in getFileItems(conf.urlFile): kb.targets.put(line.strip())
def do_info(self,plugin): """ 插件信息 :param plugin: string, 插件名称 :return: 插件信息 """ if not plugin: try: plugin = kb.CurrentPlugin except: log.error("info <plugin>") return if InfoPlugin(plugin): Infomation = InfoPlugin(plugin) print "\n%s: %s" % ("appName", Infomation["appName"]) print "%s: %s" % ("appVersion", Infomation["appVersion"]) print "Author:\n\t%s\n" % Infomation["author"] print "Description:\n\t%s\n" % Infomation["description"] print "Reference:\n\t%s\n" % Infomation["references"] else: log.error("Invalid plugin: %s" % plugin)
def do_search(self, keyword): """ 搜索插件 :param keyword: string, 关键字 :return: """ if keyword: l_ist = [] l_tmp = [] l_ist.append(list(("expName","appName", "appVersion", "description"))) for ListPlugin in SearchPlugin(keyword): l_tmp.append(ListPlugin["expName"]) l_tmp.append(ListPlugin["appName"]) l_tmp.append(ListPlugin["appVersion"]) l_tmp.append(ListPlugin["description"]) l_ist.append(l_tmp) l_tmp = [] print "\nMatching Modules\n================\n" print(tabulate(l_ist,headers="firstrow")) else: log.error("search <keyword>")
def do_info(self, plugin): """ 插件信息 :param plugin: string, 插件名称 :return: 插件信息 """ if not plugin: try: plugin = kb.CurrentPlugin except: log.error("info <plugin>") return if InfoPlugin(plugin): Infomation = InfoPlugin(plugin) print "\n%s: %s" % ("appName", Infomation["appName"]) print "%s: %s" % ("appVersion", Infomation["appVersion"]) print "Author:\n\t%s\n" % Infomation["author"] print "Description:\n\t%s\n" % Infomation["description"] print "Reference:\n\t%s\n" % Infomation["references"] else: log.error("Invalid plugin: %s" % plugin)
def do_use(self, plugin): """ 加载插件 :param plugin: string, 插件名称 :return: """ #在use新插件的时候要清除已经设置的变量以及结果 initializeKb() ClearConf() kb.CurrentPlugin = plugin zsp = PluginBase(package='zsplugins') plugin_zsp = zsp.make_plugin_source(searchpath=[paths.ZEROSCAN_PLUGINS_PATH]) expNames = plugin_zsp.list_plugins() if kb.CurrentPlugin: if plugin in expNames: self.prompt = "ZEROScan exploit({color}{content}{color_reset}) > ".format( color=Fore.RED, content=kb.CurrentPlugin, color_reset=Fore.RESET) else: log.error("plugin is not exist!") else: log.error("use <plugin>")
def setMultipleTarget(): #urlFile if not conf.urlFile: target_urls = [] if conf.url: if conf.url.endswith('/24'): try: socket.inet_aton(conf.url.split('/')[0]) base_addr = conf.url[:conf.url.rfind('.') + 1] target_urls = ['{}{}'.format(base_addr, i) for i in xrange(1, 255 + 1)] except socket.error: errMsg = 'only id address acceptable' log.error(errMsg) else: target_urls = conf.url.split(',') for url in target_urls: if url: kb.targets.put((url)) else: errMsg = 'the url needs to be set' log.error(errMsg) return if paths.ZEROSCAN_TARGET_PATH in conf.urlFile: conf.urlFile = safeExpandUser(conf.urlFile) infoMsg = "parsing multiple targets list from '%s'" % conf.urlFile log.process(infoMsg) else: conf.urlFile = paths.ZEROSCAN_TARGET_PATH +'/'+ conf.urlFile conf.urlFile = safeExpandUser(conf.urlFile) infoMsg = "parsing multiple targets list from '%s'" % conf.urlFile log.process(infoMsg) if not os.path.isfile(conf.urlFile): errMsg = "the specified file does not exist" raise ZEROScanFilePathException(errMsg) for line in getFileItems(conf.urlFile): kb.targets.put(line.strip())
def do_set(self, arg): """ 设置参数 :param arg: string, 以空格分割 option, value :return: """ try: initializeKb() if kb.CurrentPlugin: if len(arg.split()) == 2: option = arg.split()[0] value = arg.split()[1] rn = SetOption(option, value) if rn.startswith("Invalid option:"): log.error(rn) else: print rn else: log.error("set <option> <value>") else: log.error("Select a plugin first.") except: log.error("Select a plugin first.")
if forwardException: raise except (ZEROScanConnectionException, ZEROScanValueException), errMsg: print kb.threadException = True log.process("thread %s: %s" % (threading.currentThread().getName(), errMsg)) except: from lib.core.common import unhandledExceptionMessage print kb.threadException = True errMsg = unhandledExceptionMessage() log.error("thread %s: %s" % (threading.currentThread().getName(), errMsg)) traceback.print_exc() finally: kb.multiThreadMode = False kb.bruteMode = False kb.threadContinue = True kb.threadException = False #前台线程(默认),都终止才终止;后台线程,前终止后立即终止 def setDaemon(thread): # Reference: http://stackoverflow.com/questions/190010/daemon-threads-explanation if PYVERSION >= "2.6": thread.daemon = True else: thread.setDaemon(True)
if forwardException: raise except (ZEROScanConnectionException, ZEROScanValueException), errMsg: print kb.threadException = True log.process("thread %s: %s" % (threading.currentThread().getName(), errMsg)) except: from lib.core.common import unhandledExceptionMessage print kb.threadException = True errMsg = unhandledExceptionMessage() log.error("thread %s: %s" % (threading.currentThread().getName(), errMsg)) traceback.print_exc() finally: kb.multiThreadMode = False kb.bruteMode = False kb.threadContinue = True kb.threadException = False #前台线程(默认),都终止才终止;后台线程,前终止后立即终止 def setDaemon(thread): # Reference: http://stackoverflow.com/questions/190010/daemon-threads-explanation if PYVERSION >= "2.6": thread.daemon = True else:
def main(): vuln_classes = utils.get_vulnerability_classes() vulns_list = [(_class.name, _class.keyname) for _class in vuln_classes] print(BANNER) parser = argparse.ArgumentParser(usage='%(prog)s [options]') parser.error = log.error parser.add_argument('-p', '--path', help='php project path', dest='path', metavar='') parser.add_argument('-f', '--file', help='specific file to check', dest='file', metavar='') parser.add_argument( '-v', '--vulns', help='common vulnerabilities to look for. Default: all', dest='included', metavar='', default=','.join(x[1] for x in vulns_list)) parser.add_argument('--exclude', help='exclude common vulnerabilities', dest='excluded', metavar='') parser.add_argument('--list-vulns', help='list common vulnerabilities', dest='list_vulns', action='store_true') args = parser.parse_args() if len(sys.argv) < 2: parser.print_usage() exit() if args.list_vulns: print('list of valid vulnerabilities:') print('\n'.join(f' {Fore.YELLOW}{x[1]:<8}{Fore.RESET}{x[0]}' for x in vulns_list)) exit(0) if not args.path and not args.file: log.error('missing mandatory option: -p/--path or -f/--file') if args.path: args.file = None if not os.path.exists(args.path) or not os.path.isdir(args.path): log.error('directory not found') else: if not os.path.exists(args.file) or not os.path.isfile( args.file) or not args.file.endswith( '.php') and not args.file.endswith('.html'): log.error('php file not found') if not args.included: log.error('no vulnerabilities to check is selected') included_vulns = args.included.lower().split(',') excluded_vulns = args.excluded.lower().split(',') if args.excluded else [] for vuln in excluded_vulns: if not [_class for _class in vuln_classes if _class.keyname == vuln]: log.error(f'unrecognized common vulnerability: {vuln}') exit(0) included_vulns.remove(vuln) for vuln in included_vulns: if not [_class for _class in vuln_classes if _class.keyname == vuln]: log.error(f'unrecognized common vulnerability: {vuln}') exit(0) global found if args.path: for root, _, directory in os.walk(args.path): for file in directory: if not file.endswith('.php') and not file.endswith('.html'): continue file_path = os.path.join(root, file) for vuln in included_vulns: Vulnerability = [ _class for _class in vuln_classes if _class.keyname == vuln ][0] vuln_obj = Vulnerability(file_path) for line, no, vuln_part in vuln_obj.find(): log.found(file_path, line, no, vuln_part, vuln_obj.name) found += 1 else: for vuln in included_vulns: Vulnerability = [ _class for _class in vuln_classes if _class.keyname == vuln ][0] vuln_obj = Vulnerability(args.file) for line, no, vuln_part in vuln_obj.find(): log.found(args.file, line, no, vuln_part, vuln_obj.name) found += 1 if found > 0: log.info( f'phpvuln finished with {Fore.GREEN}{found} {Fore.RESET}potential vulnerabilit{"y" if found == 1 else "ies"} found' ) else: log.info( f'phpvuln finished, but no potential vulnerabilities were found')