예제 #1
0
class Session:
    def __init__(self, services, log):
        self.log = log
        self.services = services
        self.sessions = []
        self.console = Console()

    async def accept(self, reader, writer):
        connection = writer.get_extra_info('socket')
        paw = await self._gen_paw_print(connection)
        self.sessions.append(
            dict(id=len(self.sessions) + 1, paw=paw, connection=connection))
        self.console.line('New session: %s' % paw)

    async def refresh(self):
        for index, session in enumerate(self.sessions):
            try:
                session.get('connection').send(str.encode(' '))
            except socket.error:
                del self.sessions[index]

    async def has_agent(self, paw):
        agents = await self.services.get('data_svc').locate('agents')
        return next((i for i in agents if i['paw'] == paw), False)

    @staticmethod
    async def _gen_paw_print(connection):
        paw = ''
        while True:
            try:
                data = str(connection.recv(1), 'utf-8')
                paw += data
            except BlockingIOError:
                break
        return paw
예제 #2
0
class Zero:
    def __init__(self, conn):
        self.conn = conn
        self.console = Console()

    async def enter(self):
        self.console.hint('You can enter "help" here as well')
        while True:
            cmd = await ainput(colored('zero> ', 'magenta'))
            if cmd == 'help':
                await self._help()
            elif cmd == 'bg':
                break
            elif len(str.encode(cmd)) > 0:
                await self._execute(cmd)

    """ PRIVATE """

    @staticmethod
    async def _help():
        print('ZERO SHELL HELP:')
        print('-> bg: send this shell to the background')
        print('-> download [filename]: drop any file from the API')
        print('-> upload [filename]: exfil any file or archive to the API')

    async def _execute(self, cmd):
        self.conn.send(str.encode('%s\n' % cmd))
        client_response = str(self.conn.recv(4096), 'utf-8')
        print(client_response, end='')
예제 #3
0
 def __init__(self, services):
     self.data_svc = services.get('data_svc')
     self.planning_svc = services.get('planning_svc')
     self.plugin_svc = services.get('plugin_svc')
     self.agent_svc = services.get('agent_svc')
     self.session = Session(services, self.plugin_svc.log)
     self.prompt = 'caldera> '
     self.console = Console()
예제 #4
0
async def initialize(app, services):
    data_svc = services.get('data_svc')
    await data_svc.load_data(directory='plugins/terminal/data')
    logging.getLogger().setLevel(logging.FATAL)
    loop = asyncio.get_event_loop()
    show_welcome_msg()
    terminal = start_terminal(loop, services)
    start_socket_listener(loop, terminal)
    Console().hint('Enter "help" at any point')
예제 #5
0
 def __init__(self, services, log):
     self.log = log
     self.services = services
     self.sessions = []
     self.console = Console()
예제 #6
0
class Shell:

    def __init__(self, services):
        self.data_svc = services.get('data_svc')
        self.planning_svc = services.get('planning_svc')
        self.plugin_svc = services.get('plugin_svc')
        self.agent_svc = services.get('agent_svc')
        self.session = Session(services, self.plugin_svc.log)
        self.prompt = 'caldera> '
        self.console = Console()

    async def start(self):
        await asyncio.sleep(1)
        while True:
            try:
                cmd = await ainput(self.prompt)
                if cmd:
                    self.plugin_svc.log.debug(cmd)
                    await self.session.refresh()
                    commands = {
                        'help': lambda _: self._help(),
                        'hosts': lambda _: self._show_hosts(),
                        'join': lambda c: self._connect_session(cmd),
                        'new': lambda c: self._new_session(cmd)
                    }
                    command = [c for c in commands.keys() if cmd.startswith(c)]
                    await commands[command[0]](cmd)
            except Exception:
                self.console.line('Bad command', 'red')

    """ PRIVATE """

    @staticmethod
    async def _help():
        print('HELP MENU:')
        print('-> hosts: show all connected computers')
        print('-> new [n]: start a new session on an agent ID')
        print('-> join [n]: connect to a session by ID')

    async def _show_hosts(self):
        agents = await self.data_svc.locate('agents')
        sessions = self.session.sessions
        hosts = []
        for paw in set([x['paw'] for x in agents + sessions]):
            temp_sessions = [s['id'] for s in sessions if s['paw'] == paw]
            temp_agents = [a['id'] for a in agents if a['paw'] == paw]
            hosts.append(dict(paw=paw, agents=temp_agents, sessions=temp_sessions))
        if not hosts:
            self.console.hint('Deploy 54ndc47 agents to add new hosts')
        await self.console.table(hosts)

    async def _connect_session(self, cmd):
        session = int(cmd.split(' ')[1])
        try:
            conn = next(i['connection'] for i in self.session.sessions if i['id'] == int(session))
            conn.setblocking(True)
            conn.send(str.encode(' '))
            await Zero(conn).enter()
        except StopIteration:
            self.console.line('Session cannot be established with %s' % session, 'red')

    async def _new_session(self, command):
        agent_id = command.split(' ')[1]
        agent = await self.data_svc.locate('agents', match=dict(id=agent_id))
        if agent:
            abilities = await self.data_svc.explode('ability',
                                                    criteria=dict(ability_id='356d1722-7784-40c4-822b-0cf864b0b36d',
                                                                  platform=agent[0]['platform'])
                                                    )
            abilities = await self.agent_svc.capable_agent_abilities(abilities, agent[0])
            command = await self.planning_svc.decode(abilities[0]['test'], agent[0], group='')
            cleanup = self.planning_svc.decode(abilities[0].get('cleanup', ''), agent[0], group='')

            link = dict(op_id=None, paw=agent[0]['paw'], ability=abilities[0]['id'], jitter=0, score=0,
                        decide=datetime.now(), command=self.plugin_svc.encode_string(command),
                        cleanup=self.plugin_svc.encode_string(cleanup), executor=abilities[0]['executor'])
            await self.data_svc.save('link', link)
            self.console.line('Queued. Waiting for agent to beacon...', 'green')
        else:
            self.console.line('No agent with an ID = %s' % agent_id, 'red')
예제 #7
0
 def __init__(self, conn):
     self.conn = conn
     self.console = Console()