def main(): ''' handles user interface ''' colors.colored_print("[*] Default target list is ./data/ip_list.txt", colors.CYAN) SESSION.ip_list = SESSION.init_dir + '/data/ip_list.txt' futil.write_file(text=f"{os.getpid()}", filepath=SESSION.pidfile) while True: try: if os.getcwd() != core.MECROOT: os.chdir(core.MECROOT) input_cmd = rlinit.prompt(session=SESSION) try: cmd.cmd_handler(SESSION, input_cmd) except (KeyboardInterrupt, EOFError, SystemExit): sys.exit(0) except FileNotFoundError: console.print_error(f"[-] {core.MECROOT} not found???") sys.exit(1) except KeyboardInterrupt: answ = console.yes_no("\n[?] Are you sure to exit?") if answ: futil.check_kill_process('ss-proxy') sys.exit(0) else: continue
def run_censys(**kwargs): """ Crawler for Censys.io """ session = kwargs.get("session", None) try: output = censys.start() if console.yes_no("\n[?] Use collected URLs as target?"): session.ip_list = session.init_dir + "/" + output colors.colored_print( '[i] Target changed to {}'.format( session.ip_list), colors.BLUE) except BaseException: return
def run_exploits(**kwargs): """ List all usable exploits """ do_print = kwargs.get("do_print", True) exp_list = futil.list_exp() if len(exp_list) == 0: console.print_error("[-] No exploits found") if console.yes_no("[?] Perhaps you need to check `info`?"): run_info(session=kwargs.get("session")) if not do_print: return exp_list colors.colored_print(f"[+] {len(exp_list)} available exploits: ", colors.CYAN) for poc in exp_list: colors.colored_print(poc, colors.BLUE) return None
def run_baidu(**kwargs): """ Search via m.baidu.com """ session = kwargs.get("session") command = kwargs.get("args") try: dork = command[0] count = int(command[1]) os.chdir(session.out_dir) colors.colored_print('[*] Searching on Baidu...', colors.PURPLE) baidu.spider(dork, count) if console.yes_no("\n[?] Use collected URLs as target?"): session.ip_list = session.out_dir + "/result.txt" except (EOFError, KeyboardInterrupt, SystemExit): console.print_warning("[-] Interrupted") return except BaseException as exc: console.print_error(f"[-] Error: {exc}") console.debug_except()
def scan(self): ''' Execute exploit against given ip list ''' try: int(self.jobs) except BaseException: console.print_error("[-] Invalid config") return try: target_list = open(self.session.ip_list) except BaseException as exc: console.print_error('[-] Error occured: {}\n'.format(exc)) console.debug_except() return try: os.chdir('./exploits/' + self.work_path) except FileNotFoundError: console.print_error("[-] Can't chdir to " + self.work_path) console.debug_except() # you might want to cancel the scan to correct some errors if not console.yes_no('[?] Proceed?'): os.chdir(self.session.init_dir) return # save stdout to logfile try: logfile = open(self.session.logfile, "a+") except FileNotFoundError: console.print_error("[-] Log file not found") # needed for the loop procs = [] pool = [] # holds all processes, check if empty when finishing count = len(procs) # display help for viewing logs print(colors.CYAN + "[*] Use `tail -f {}` to view logs\n\n".format(self.session.logfile)) # use progress bar with open(self.session.ip_list) as iplistf: total = len([0 for _ in iplistf]) iplistf.close() pbar = tqdm.tqdm(total=total, ncols=80, desc="[*] Processing targets") # set `proxy.conf`, in case `target_ip.conf` fails if self.session.use_proxy: if not self.session.dynamic_proxy("proxy"): console.print_error("[-] Cannot get proxy from proxy_pool") return for line in target_list: target_ip = line.strip() proxyconf = f"{target_ip}.conf" # mark this loop as done count = len(procs) e_args = ['./' + self.exec_path] # dynamic exp args try: if self.session.use_proxy: if not self.session.dynamic_proxy(target_ip): proxyconf = "proxy.conf" e_args = [ 'proxychains4', '-q', '-f', f'/dev/shm/{proxyconf}', './' + self.exec_path] # add custom arguments for different exploits e_args += self.custom_args # the last argument is target host e_args += ['-t'] # start and display current process e_args += [target_ip] proc = subprocess.Popen(e_args, stdout=logfile, stderr=logfile) procs.append(proc) pool.append(proc) pbar.set_description( desc="[*] Processing {}".format(target_ip)) # continue to next target e_args.remove(target_ip) # sleep sleep_seconds time.sleep(float(self.sleep_seconds)) # process pool if count == self.jobs: for item in procs: if psutil.pid_exists(item.pid): timer_proc = Process( target=futil.proc_timer, args=(item, )) timer_proc.start() else: pool.remove(item) procs = [] except (EOFError, KeyboardInterrupt, SystemExit): console.print_error("[-] Task aborted") break except BaseException as exc: logfile.write("[-] Exception: " + str(exc) + "\n") finally: # check if any procs are done, remove them from pool, update progress bar try: for proc in pool: if proc.poll() is not None: pool.remove(proc) pbar.update(1) if self.session.use_proxy: # delete proxy config file try: os.remove(f"/dev/shm/{target_ip}.conf") except BaseException: pass except BaseException: logfile.write("[-] Exception: " + traceback.format_exc() + "\n") # make sure all processes are done if pool: for proc in pool: try: proc.terminate() proc.wait() except (EOFError, KeyboardInterrupt, SystemExit): pass # close logfile, exit progress bar, and print done flag logfile.close() pbar.close() os.chdir(self.session.init_dir) console.print_success('\n[+] All done!\n') # this fixes #37, because when parent gets killed, all zombie children die sys.exit()
def attack(self): ''' handles attack command ''' self.use_proxy = console.yes_no( '[?] Do you wish to use proxy_pool/proxychains?') if self.use_proxy: if shutil.which("proxychains4") is None: console.print_error("proxychains4 not found") return # sleep between two subprocess open sleep_seconds = console.input_check("\n[?] Wait how many seconds" + " before each process launch?\n" + " (Set it to 0 when you want to use 100% CPU" + " / bandwidth\n Recommened value: 0.1)\n" + "\n[=] Your input: ", check_type=float) answ = console.input_check( '\n[?] Do you wish to use\ \n\n [1] built-in exploits\ \n [2] or launch your own manually?\ \n\n[=] Your choice: ', choices=['1', '2', 'built-in', 'manually']) if answ in ['1', 'built-in']: print( colors.CYAN + colors.BOLD + '\n[?] Choose a module from: ' + colors.END + '\n') colors.colored_print(futil.BUILT_IN, colors.GREEN) module = console.input_check( "[?] Choose your exploit module: ", choices=futil.BUILT_IN.split('\n'), allow_blank=False) try: scanner_instance = exploit_exec.EXPLOIT_DICT.get(module)(self) if scanner_instance is None: return scanner_instance.sleep_seconds = sleep_seconds scanner_instance.scan() return except (EOFError, KeyboardInterrupt, SystemExit): return # run custom exploits print( colors.CYAN + colors.UNDERLINE + colors.BOLD + "\nWelcome, in here you can invoke your own exploit\n" + colors.END) cmd.run_exploits() exploit = console.input_check( "\n[*] Enter the path (eg. test/test) to your exploit: ", choices=futil.list_exp()) jobs = int( console.input_check("[?] How many processes each time? ", check_type=int)) custom_args = console.input_check( "[*] Addtional args for this exploit (other than `-t <target>`): ").strip().split() # parse user's exploit name exec_path = exploit.split('/')[1:] work_path = exploit.split('/')[:-1] exec_path = '/'.join(exec_path) work_path = '/'.join(work_path) # args as parameter for scanner scanner_instance = Scanner(work_path, exec_path, custom_args, jobs, sleep_seconds, self) # start scanner scanner_instance.scan()
def call_update(self, silent=False): """ update mec record update result and act accordingly """ if self.auto_update: console.print_success("[-] auto-update is enabled") def update(res): ''' check updates from https://github.com/jm33-m0/mec ''' # current version old_ver = get_version() if old_ver == "": res['status'] = "[-] cannot get version" return os.chdir(MECROOT) # pull all tags try: check = "git pull --tags" out = subprocess.check_output( ["/bin/sh", "-c", check], stderr=subprocess.STDOUT, timeout=30) check_res = out.decode("utf-8") except KeyboardInterrupt: return except BaseException: res['status'] = f"[-] Failed to check for updates:\n{traceback.format_exc()}" return if "Already up to date" in check_res: res['status'] = "[+] already up to date" return # pull if needed pull = "git pull" try: out = subprocess.check_output( ["/bin/sh", "-c", pull], stderr=subprocess.STDOUT, timeout=30) pull_res = out.decode("utf-8") except KeyboardInterrupt: return except BaseException: res['status'] = f"[-] Failed to update mec: {traceback.format_exc()}" return if "error:" in pull_res: res['status'] = f"[-] Failed to update mec:\n{pull_res}, press enter to continue..." return res['status'] = f"[+] mec has been updated:\n{old_ver}->{get_version()}" return # update in child process if silent: res = {} update_job = Process(target=update, args=(res,)) update_job.start() return # check for result res = Manager().dict() update_job = Process(target=update, args=(res,)) update_job.start() # print status console.print_status( "[*] fetching updates from github...", update_job) update_job.join() # wait for result try: status = res['status'] except BaseException: status = "" if "[+]" in status: console.print_success(status) if "already up to date" in status: return if console.yes_no("[?] Exit mec (to apply updates) ?"): sys.exit(0) elif "[-]" in status: console.print_error(status)