#!/usr/bin/python3 # -*- coding: utf-8 -*- import os, sys, signal from threading import Thread from termcolor import colored from cmd import Cmd from time import sleep from lib.main import main_run from lib.main import valid_protos from lib.main import print_error from warriors.general import General class LegionPrompt(Cmd): intro = """\ ██╗ ███████╗ ██████╗ ██╗ ██████╗ ███╗ ██╗ ██║ ██╔════╝██╔════╝ ██║██╔═══██╗████╗ ██║ ██║ █████╗ ██║ ███╗██║██║ ██║██╔██╗ ██║ ██║ ██╔══╝ ██║ ██║██║██║ ██║██║╚██╗██║ ███████╗███████╗╚██████╔╝██║╚██████╔╝██║ ╚████║ ╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ v2.0"""+colored("\nI wanted to destroy everything beautiful I'd never have\n", 'red', attrs=['bold']) prompt = '('+colored("legion", 'blue', attrs=['bold'])+') > ' def __init__(self, parser, proto, host, workdir, port, intensity, username, ulist, plist, notuse, extensions, path, password, ipv6, domain, verbose): Cmd.__init__(self) self.all_values = {"proto": proto, "host": host, "workdir": workdir, "port": port, "intensity": intensity, "username": username, "ulist": ulist, "plist": plist, "notuse": notuse, "extensions": extensions, "path": path, "password": password, "ipv6": ipv6, "domain": domain, "verbose": verbose, "reexec": False} self.priv_values = {"interactive": True, "protohelp": False, "executed": [], "exec": ""} self.parser = parser self.ws = [] self.general = "" self.msgs = {} def emptyline(self): pass def do_exit(self, inp): '''exit the application''' print("Bye!") self.stop_procs() os.kill(os.getpid(), signal.SIGTERM) def do_quit(self, inp): '''exit the application''' print("Bye!") self.stop_procs() os.kill(os.getpid(), signal.SIGTERM) def do_stopall(self, inp): '''Stop ALL running processes''' self.stop_procs() def do_stop(self, procname): '''Stop a process given the name''' self.stop_p(procname) def do_protos(self, args): '''List the name of valid protocols''' c = 0 for i, p in enumerate(valid_protos): clr = "green" if p not in ["scanner"] else "blue" myend = "\t\t" if len(p) < 8 else "\t" if c % 3 != 0: print(colored(p, clr, attrs=['bold']), end=myend) else: print("\n"+colored(p, clr, attrs=['bold']), end=myend) c += 1 print() print(colored("There are a total of "+str(len(valid_protos))+" supported protocols", "yellow", attrs=['bold'])) def do_set(self, args): '''Set variable value: set proto http''' if len(args.split(" ")) < 2: print_error("set <variable> <value>") else: variable = args.split(" ")[0].lower() value = args.split(" ")[1].strip() if variable == "proto" and value.lower() not in valid_protos: print_error("Not valid protocol: "+value) elif variable in ["port", "intensity"] and not value.isdigit(): print_error("Please set a number: "+value) elif variable in ["reexec", "verbose"] and not value.lower() in ["true", "false"]: print_error("Please set a boolean(true or false): "+value) elif variable.lower() in self.all_values: value = value if not value.lower() in ["true", "false"] else (True if value.lower() == "true" else False) self.all_values[variable] = value print(colored(variable.capitalize(), "blue", attrs=['bold']) + ": " + colored(str(value), "yellow", attrs=['bold'])) else: print_error(variable + " is not valid") def do_unset(self, args): '''Set variable to null''' if len(args.split(" ")) < 1: print_error("unset <variable>") else: variable = args.split(" ")[0].lower() if variable.lower() in self.all_values: self.all_values[variable] = "" print(colored(variable.capitalize(), "blue", attrs=['bold']) + ": " + colored("Null", "magenta", attrs=['bold'])) else: print_error(variable + " is not valid") def do_get(self, args): '''Get variable value: get proto''' variable = args.split(" ")[0].lower() if variable.lower() in self.all_values: print(variable + ": " + str(self.all_values[variable])) else: print_error(variable + " is not valid") def do_options(self, _): '''Get all Parameters and their value''' for key, value in sorted(self.all_values.items()): if key == "proto": print(colored(str(key) + ": ", 'yellow', attrs=['bold']) + str(value)) else: print(colored(str(key)+": ", 'cyan', attrs=['bold'])+str(value)) def do_procs(self, _): '''Get information about running and run processes''' self.print_procs(self.ws) if self.general != "": print() print(colored("Warriors sent by the General:", "blue", attrs=['bold', 'underline'])) self.print_procs(self.general.get_warriors()) print("") def do_out(self, filename): '''Get the output of a executed tool: getout smbclient''' name = filename + ".out" for root, dirs, files in os.walk(self.all_values["workdir"]+"/"+self.all_values["host"]): if name in files: with open(os.path.join(root, name), 'r') as f: print(f.read()) break def do_err(self, filename): '''Get the error of a executed tool: geterr smbclient''' name = filename + ".err" for root, dirs, files in os.walk(self.all_values["workdir"]): if name in files: with open(os.path.join(root, name), 'r') as f: print(f.read()) break def do_info(self, _): '''Get info of the selected protocol''' self.priv_values["protohelp"] = True self.initW() self.priv_values["protohelp"] = False def do_run(self, _): '''Execute the confiured protocol attack''' self.priv_values["protohelp"] = False self.update_executed() warrior = self.initW() if warrior != -1: # If -1, then something went wrong creating the warrior self.ws.append(warrior) thread = Thread(target=warrior.run) thread.start() else: print_error("Something went wrong, nothing is going to be executed") def do_exec(self, args): '''Execute the indicated cmd''' if len(args.split(" ")) != 1: print_error("exec <CMDname>") else: cmd = args.split(" ")[0].lower() self.priv_values["exec"] = cmd warrior = self.initW() self.priv_values["exec"] = "" if warrior != -1: # If -1, then something went wrong creating the warrior self.ws.append(warrior) thread = Thread(target=warrior.run) thread.start() else: print_error("Something went wrong, nothing is going to be executed") def do_startGeneral(self, _): '''Star a General that will help. Automatize the scan and launch of scripts depending on the discovered services. Only one at the same time is allowed.''' if self.general == "": print(colored("Starting General", "blue", attrs=['bold'])) self.general = General(self.parser, self.all_values["host"], "0", self.all_values["workdir"], "/", self.all_values["intensity"], self.all_values["username"], self.all_values["ulist"], self.all_values["password"], self.all_values["plist"], self.all_values["notuse"], self.all_values["extensions"], self.all_values["path"], self.all_values["reexec"], self.all_values["ipv6"], self.all_values["domain"], self.priv_values["interactive"], self.all_values["verbose"], self.priv_values["executed"], self.priv_values["exec"]) thread = Thread(target=self.general.run) thread.start() else: print(colored("general is already running... You can stop it with stopGeneral",'blue')) def do_stopGeneral(self, _): '''Stop the general''' print(colored("Stopping General...", 'blue', attrs=['bold'])) self.general.stop_general() self.general = "" def initW(self): '''Initialize the current Warrior''' return main_run(self.parser, self.all_values["proto"], self.all_values["host"], self.all_values["workdir"], self.all_values["port"], self.all_values["intensity"], self.all_values["username"], self.all_values["ulist"], self.all_values["plist"], self.priv_values["protohelp"], self.all_values["notuse"], self.all_values["extensions"], self.all_values["path"], self.all_values["password"], self.all_values["ipv6"], self.all_values["domain"], self.priv_values["interactive"], self.all_values["verbose"], self.all_values["reexec"], self.priv_values["executed"], self.priv_values["exec"]) def print_procs(self, ws): last = "" ws = sorted(ws, key=lambda x: x.get_proto()) for w in ws: if type(w) is int: print_error("An INT was found as a WARRIOR, TAKE A LOOK!") continue if last != w.get_proto(): print() print(colored(w.get_proto(), 'blue', attrs=['reverse', 'bold'])) last = w.get_proto() procs, ch = w.get_procs_info() procs = sorted(procs, key=lambda x: x["name"]) for p in procs: if p["proc"].is_alive(): print(colored(p["name"] + ": ", 'yellow', attrs=['blink', 'bold']) + p["cmd"]) else: print(colored(p["name"] + ": ", 'green', attrs=['bold']) + p["cmd"]) if ch: print(colored("Command require sequencial object, waiting for execute next commnad...", 'red', attrs=['bold'])) def get_pids(self): for w in self.ws: self.msgs = {**self.msgs, **w.get_all_queue()} if self.general != "": for w in self.general.get_warriors(): self.msgs = {**self.msgs, **w.get_all_queue()} def stop_p(self, param_name): self.get_pids() self.kill_pbyname(param_name) def stop_procs(self): self.proc_stop_procs(self.ws) if self.general != "": self.proc_stop_procs(self.general.get_warriors()) def proc_stop_procs(self, ws): rep = True while rep: rep = False self.get_pids() for w in ws: procs, ch = w.get_procs_info() for p in procs: if p["proc"].is_alive(): self.kill_pbyname(p["name"]) rep = True sleep(0.5) def kill_pbyname(self, pname): if pname in self.msgs: os.kill(int(self.msgs[pname]), signal.SIGKILL) print(colored("Terminated: ", 'green', attrs=['bold']) + pname + "("+str(self.msgs[pname])+")") else: print(colored("Not found: ", 'red', attrs=['bold']) + pname) def update_executed(self): for w in self.ws: self.priv_values["executed"].append(w.get_executed()) if self.general != "": for w in self.general.get_warriors(): self.priv_values["executed"].append(w.get_executed())