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')
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')
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')
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')
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}')
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
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 '''
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