Exemple #1
0
    def __init__(self, ctx):
        be.log('in rekall constructor')
        be.set_name('rekall')
        self.felist = {}
        self.rekall_cmds = [
            '/opt/rekall/bin/rekal -p /opt/kernels/rekall/win7ie11.rekall.json -f /home/furnace pslist',
            '/opt/rekall/bin/rekal -p /opt/kernels/rekall/win7ie11.rekall.json -f /home/furnace netscan',
            '/opt/rekall/bin/rekal -p /opt/kernels/rekall/win7ie11.rekall.json -f /home/furnace netstat',
            '/opt/rekall/bin/rekal -p /opt/kernels/rekall/win7ie11.rekall.json -f /home/furnace pstree',
            '/opt/rekall/bin/rekal -p /opt/kernels/rekall/win7ie11.rekall.json -f /home/furnace modscan',
            '/opt/rekall/bin/rekal -p /opt/kernels/rekall/win7ie11.rekall.json -f /home/furnace psxview',
        ]

        self.cycle_count = 1

        integration = True  # if True, starts up subscriber for external commands
        if integration:
            rekall_unix = 'ipc:///tmp/rekall'
            self.sub = be.bei.context.socket(zmq.SUB)
            self.sub.setsockopt(zmq.SUBSCRIBE, b'')
            self.sub.connect(rekall_unix)

            e = {
                'event_type': be.TIMER,
                'time_value': 1.0,
                'callback': self.timer_callback
            }
            be.event_register(e)

        e = {'event_type': be.FE, 'callback': self.fe_callback}
        be.event_register(e)

        be.log('leaving rekall constructor')
Exemple #2
0
    def __init__(self, ctx):
        be.log('in memdump constructor')
        be.set_name('memdump')
        self.felist = {}
        self.cycle_count = 1
        self.stime = 0.0
        self.zdo = zlib.decompressobj()
        self.decompressed_data = b''
        self.total_recv_bytes = 0
        self.ix_recv = {}

        be.event_register({'event_type': be.FE, 'callback': self.fe_callback})
        '''
        e = {'event_type': be.TIMER, 'time_value': 2.0,  # seconds
             'callback': self.timer_callback}
        be.event_register(e)
'''

        be.log('leaving memdump constructor')
Exemple #3
0
    def __init__(self, ctx):
        """
        Tenant's backend constructor
        :param ctx: Currently unused, passed as an empty dict.
        """
        be.log('in example constructor')
        be.set_name('example_backend')
        self.felist = {}

        e = {'event_type': be.FE, 'callback': self.fe_callback}
        be.event_register(e)

        e = {
            'event_type': be.TIMER,
            'time_value': 2.0,  # seconds
            'callback': self.timer_callback
        }
        be.event_register(e)

        be.log('leaving example constructor')
Exemple #4
0
 def timer_callback(self, ctx):
     be.log('BE TIMER')
     try:
         cmd = self.sub.recv(flags=zmq.NOBLOCK)
         be.log(f'got command: {cmd}')
     except zmq.ZMQError:
         be.log('no msgs')
Exemple #5
0
 def timer_callback(self, ctx):
     """
     Called on timer timeouts
     :param ctx: Presently unused, passes as a static "timer triggered" string
     :returns: Nothing.
     """
     be.log('BE TIMER')
     be.log(f'FEs I have seen: {self.felist}')
     for key, last_seen in self.felist.items():
         if key[-1] == 'd':
             be.log(f'notifying {key}')
             be.notify(key, f'hi {key}')
Exemple #6
0
 def fe_callback(self, ctx):
     """
     Called when messages arrive from apps
     :param ctx: a ctx named tuple collections.namedtuple('ctx', 'ident sync message')
          ident (string): ID of sending app.
          sync (bool): if True, the app is blocking on a response.
          message (string): Contents of message.
     :returns: a string reply to send to the app
     """
     be.log('BE CALLBACK')
     be.log(f'in: {ctx}')
     self.felist[ctx.ident] = time.time()
     if ctx.sync == be.SYNC:  # the FE is blocking on our reply
         msg = f'ok: {id(ctx)}'
         be.log('returning: {msg}')
         return msg
Exemple #7
0
    def fe_callback(self, ctx):
        be.log('FE CALLBACK')
        if ctx.sync == be.SYNC:  # the FE is blocking on our reply
            msg = f'ok: {id(ctx)}'
            be.log('returning: {msg}')
            return msg

        # msg format: {'cmd': 'foo', 'data': 'bar'}
        # ALL ASYNC
        # FE: hi, waiting, memdump_running, memdump_done, error
        # BE: memdump_cmd: go, stop
        feid = ctx.ident
        msg = json.loads(ctx.message)
        record = self.felist.get(feid, {
            'last_contact': time.time(),
            'state': None,
            'bytes': b''
        })
        record['state'] = msg['cmd']

        if msg['cmd'] in ['hi', 'waiting']:
            if self.cycle_count > 0:
                self.cycle_count -= 1
                be.notify(feid, json.dumps({
                    'cmd': 'memdump_cmd',
                    'data': 'go'
                }))
                self.stime = time.time()
            else:
                be.log('cycle_count < 1')

        elif msg['cmd'] in ['memdump_running']:
            be.log(f'{feid} memdump_running')

        elif msg['cmd'] in ['memdump']:

            res = ''
            compressed_size = 0

            for chunk in msg['data']:
                compressed_size += len(chunk)
                cres = self.zdo.decompress(binascii.a2b_base64(chunk.encode()))
                self.total_recv_bytes += len(cres)
                #res += cres

            #shahash = hashlib.sha256(res).hexdigest()
            #orighash = msg['hash']
            ix = msg['ix']
            try:
                self.ix_recv[feid].append(ix)
            except KeyError:
                self.ix_recv[feid] = [ix]

            be.log(
                f'{feid} got memdump ix={ix}:{compressed_size} -> {self.total_recv_bytes} B'
            )
            #be.log(f'{feid} theirs={orighash}')
            #be.log(f'{feid} mine  ={shahash}')

            # TODO: for benchmarking, we dump the bytes right on the ground
            # instead, they could be saved to disk
            #record['bytes'] += res  # need to eventually bytes() this

            #recsize = len(record['bytes'])
            #be.log(f'{feid} current memdump: recordsize={recsize} B')

        elif msg['cmd'] in ['memdump_done']:
            rt = round(time.time() - self.stime, 2)
            #rate = round((len(record['bytes'])/rt) / 1000000, 2)
            rate = round((self.total_recv_bytes / rt) / 1000000, 2)
            be.log(f'{feid} memdump finished')
            be.log(
                f'{feid} total_recv_bytes={self.total_recv_bytes}, runtime={rt}, rate={rate} MBps'
            )
            be.log(f'{self.ix_recv}')
            be.log('exiting...')
            for feid in self.felist:
                be.log(f'telling {feid} to exit')
                be.notify(feid,
                          json.dumps({
                              'cmd': 'memdump_cmd',
                              'data': 'exit'
                          }))
            be.exit()

        elif msg['cmd'] in ['error']:
            be.log(f'{feid} error: {msg["data"]}')

        if feid not in self.felist:
            self.felist[feid] = record
            '''
Exemple #8
0
    def fe_callback(self, ctx):
        be.log('FE CALLBACK')
        be.log(f'in: {ctx}')
        if ctx.sync == be.SYNC:  # the FE is blocking on our reply
            msg = f'ok: {id(ctx)}'
            be.log('returning: {msg}')
            return msg

        # msg format: {'cmd': 'foo', 'data': 'bar'}
        # ALL ASYNC
        # FE: hi, waiting, rekall_running, rekall_done
        # BE: rekall_cmd
        feid = ctx.ident
        msg = json.loads(ctx.message)
        record = self.felist.get(feid, {
            'last_contact': time.time(),
            'state': None,
            'cmd_index': 0
        })
        record['state'] = msg['cmd']

        if msg['cmd'] in ['hi', 'waiting']:
            if self.cycle_count > 0:
                self.cycle_count -= 1
                ix = (record['cmd_index'] + 1) % len(self.rekall_cmds)
                record['cmd_index'] = ix
                be.notify(
                    feid,
                    json.dumps({
                        'cmd': 'rekall_cmd',
                        'data': self.rekall_cmds[ix]
                    }))
            else:
                be.log('cycle_count < 1')

        elif msg['cmd'] in ['rekall_running']:
            be.log(f'{feid} rekall_running')

        elif msg['cmd'] in ['rekall_done']:
            results = msg['data']
            be.log(f'{feid} rekall_done: {results}')
            print(results)

        if feid not in self.felist:
            self.felist[feid] = record