def read_file(query, body, module_data): # XXX: The query will be: # id=<encrypted computer name>&&mux=<encrypted total file size> # So we need to parse those out. Also, the response body should have 'I'm # Ready' in it. chop.tsprnt("Readfile (not implemented):\n%s\n%s" % (hexdump(query), hexdump(body)))
def read_file_chunk(query, body, module_data): # XXX: The query will be: # id=<encoded computer name>&&date=<file chunk data> # So we need to parse those out and store it. Also, the response body should # have 'OK' in it. chop.tsprnt("Readfile chunk (not implemented):\n%s\n%s" % (hexdump(query), hexdump(body)))
def handleStream(tcp): ((src, sport), (dst, dport)) = parse_addr(tcp) if tcp.client.count_new > 0: data = tcp.client.data[:tcp.client.count_new] count = tcp.client.count_new if tcp.stream_data['dump']: chop.tsprnt("%s:%s -> %s:%s %i bytes" % ( src, sport, dst, dport, count, )) chop.prnt(hexdump(data)) if data[:3] in [ '\x18\x03\x00', '\x18\x03\x01', '\x18\x03\x02', '\x18\x03\x03' ]: chop.tsprnt("%s:%s -> %s:%s %i bytes" % ( src, sport, dst, dport, count, )) chop.prnt(hexdump(data[8:])) tcp.stream_data['dump'] = True if tcp.client.server_new > 0: count = tcp.server.count_new tcp.discard(count)
def handleStream(tcp): ((src, sport), (dst, dport)) = parse_addr(tcp) if tcp.client.count_new > 0: data = tcp.client.data[: tcp.client.count_new] count = tcp.client.count_new if tcp.stream_data["dump"]: chop.tsprnt("%s:%s -> %s:%s %i bytes" % (src, sport, dst, dport, count)) chop.prnt(hexdump(data)) if data[:3] in ["\x18\x03\x00", "\x18\x03\x01", "\x18\x03\x02", "\x18\x03\x03"]: chop.tsprnt("%s:%s -> %s:%s %i bytes" % (src, sport, dst, dport, count)) chop.prnt(hexdump(data[8:])) tcp.stream_data["dump"] = True tcp.discard(count)
def handleStream(tcp): ((src, sport), (dst, dport)) = parse_addr(tcp) if tcp.client.count_new > 0: data = tcp.client.data[:tcp.client.count_new] count = tcp.client.count_new if tcp.stream_data['dump']: chop.tsprnt("%s:%s -> %s:%s %i bytes" % (src, sport, dst, dport, count,)) chop.prnt(hexdump(data)) if data[:3] in ['\x18\x03\x00', '\x18\x03\x01', '\x18\x03\x02', '\x18\x03\x03']: chop.tsprnt("%s:%s -> %s:%s %i bytes" % (src, sport, dst, dport, count,)) chop.prnt(hexdump(data[8:])) tcp.stream_data['dump'] = True if tcp.client.server_new > 0: count = tcp.server.count_new tcp.discard(count)
def alter_data(module_data, data): if 'xor_key' in module_data: data = multibyte_xor(data, module_data['xor_key']) if module_data['hexdump']: data = hexdump(data) if module_data['base64']: data = b64encode(data) return data
def alter_data(module_data, data): if "xor_key" in module_data: data = multibyte_xor(data, module_data["xor_key"]) if module_data["hexdump"]: data = hexdump(data) if module_data["base64"]: data = b64encode(data) return data
def handle_bytes(data, color, direction, module_data): if 'xor_key' in module_data: data = multibyte_xor(data, module_data['xor_key']) if module_data['hexdump']: data = hexdump(data) if module_data['base64']: data = b64encode(data) chop.prettyprnt(color, data) chop.json({'payload': data, 'direction': direction})
def handle_bytes(data, color, direction, module_data): if "xor_key" in module_data: data = multibyte_xor(data, module_data["xor_key"]) if module_data["hexdump"]: data = hexdump(data) if module_data["base64"]: data = b64encode(data) chop.prettyprnt(color, data) chop.json({"payload": data, "direction": direction})
def handleDatagram(udp): # collect time and IP metadata ((src, sport), (dst, dport)) = udp.addr # handle client system packets if udp.module_data['verbose']: chop.tsprettyprnt("RED", "%s:%s -> %s:%s 0x%04X bytes" % (src, sport, dst, dport, len(udp.data))) if 'xor_key' in udp.module_data: data = multibyte_xor(udp.data, udp.module_data['xor_key']) else: data = udp.data if udp.module_data['hexdump']: data = hexdump(data) chop.prettyprnt("RED", data)
def handle_results(tcp): """Print and save results.""" ((src, sport), (dst, dport)) = parse_addr(tcp) # print results for match in tcp.stream_data['server_processor'].results: if not module_data['quiet']: chop.tsprnt('Stream: Match found; %s:%s --> %s:%s' % (src, sport, dst, dport)) chop.prnt(match) # Save results if tcp.module_data['save']: output = 'Match found in server stream; src=%s; sport=%s; dst=%s; dport=%s\n' \ % (src, sport, dst, dport) output += str(match) + '\n\n' output += hexdump(tcp.stream_data['server_buffer']) + '\n' chop.appendfile(tcp.module_data['save'], output) chop.json(match) tcp.stream_data['server_processor'].clear_results() # print results for match in tcp.stream_data['client_processor'].results: if not module_data['quiet']: chop.tsprnt('Stream: Match found; %s:%s --> %s:%s' % (dst, dport, src, sport)) chop.tsprnt(match) # Save results if tcp.module_data['save']: output = 'Match found in client stream; src=%s; sport=%s; dst=%s; dport=%s\n' \ % (dst, dport, src, sport) output += str(match) + '\n\n' output += hexdump(tcp.stream_data['client_buffer']) + '\n' chop.appendfile(tcp.module_data['save'], output) chop.json(match) tcp.stream_data['client_processor'].clear_results()
def decode(msg, tcp): ((src, sport), (dst, dport)) = parse_addr(tcp) #chop.tsprnt("%s:%i->%s:%i" % (src, sport, dst, dport), None) # If this is a shell session, just dump the contents. if tcp.stream_data['shell'] == True: chop.prnt("\n%s" % msg) return # Grab the token and decode if possible. b = struct.unpack('c', msg[:1])[0] if b in tcp.module_data['tokens']: msg = msg[1:] tcp.module_data['tokens'][b](msg, tcp) else: chop.prnt("Unknown token: 0x%02x" % ord(b)) chop.prnt("%s" % hexdump(msg))
def decode(msg, tcp): ((src, sport), (dst, dport)) = parse_addr(tcp) # chop.tsprnt("%s:%i->%s:%i" % (src, sport, dst, dport), None) # If this is a shell session, just dump the contents. if tcp.stream_data["shell"] == True: chop.prnt("\n%s" % msg) return # Grab the token and decode if possible. b = struct.unpack("c", msg[:1])[0] if b in tcp.module_data["tokens"]: msg = msg[1:] tcp.module_data["tokens"][b](msg, tcp) else: chop.prnt("Unknown token: 0x%02x" % ord(b)) chop.prnt("%s" % hexdump(msg))
def decode_command(dest, command, payload, command_list): """ Print out the command info response from command_conversion. Args: dest: a string containing either 'server' or 'client' to dictate which direction the packet is going. command: hex string of the command byte payload: hex string of the packet payload data """ if (dest == 'server'): decoded_text, payload = command_conversion(command, payload, command_list) chop.tsprnt('server -> client') if decoded_text: chop.tsprnt('EvilGrab Command: %s => %s' % (binascii.hexlify(command), decoded_text)) if payload: chop.tsprnt('EvilGrab Command Payload:') if len(payload) > 32: chop.tsprnt(hexdump(payload[:16]).strip()) chop.tsprnt(hexdump(payload[16:32]).strip()) else: chop.tsprnt(hexdump(payload).strip()) else: #print the hexdump of non-commands chop.tsprnt("Unknown command: %x" % ord(command)) elif dest == 'client': decoded_text, payload = command_conversion(command, payload, command_list) chop.tsprnt('client -> server') chop.tsprnt('Exfil Type: %s => %s' % (binascii.hexlify(command), decoded_text)) ## lets check out the initial system data sent #chop.tsprnt("%s" % binascii.hexlify(command).lower()) if binascii.hexlify(command).lower() == "a0" and payload: # the data should be pipe delimited, # but its a string so lets split on NULL and write the data portion split_payload = payload.split("\x00") chop.tsprnt('%r' % split_payload[0]) elif payload: chop.tsprnt('EvilGrab Exfil Payload: ') if len(payload) > 32: chop.tsprnt(hexdump(payload[:16]).strip()) chop.tsprnt(hexdump(payload[16:32]).strip()) else: chop.tsprnt(hexdump(payload).strip()) else: chop.tsprnt('unk -> unk')
def handleStream(tcp): ((src, sport), (dst, dport)) = parse_addr(tcp) if tcp.server.count_new > 0: data = tcp.server.data[:tcp.server.count_new] count = tcp.server.count_new color = "RED" else: data = tcp.client.data[:tcp.client.count_new] count = tcp.client.count_new color = "GREEN" if tcp.module_data['verbose']: chop.tsprettyprnt(color, "%s:%s -> %s:%s %i bytes" % (src, sport, dst, dport, count)) if 'xor_key' in tcp.module_data: data = multibyte_xor(data, tcp.module_data['xor_key']) if tcp.module_data['hexdump']: data = hexdump(data) chop.prettyprnt(color, data) tcp.discard(count)
def handleStream(tcp): ((src, sport), (dst, dport)) = parse_addr(tcp) if tcp.server.count_new > 0: data = tcp.server.data[:tcp.server.count_new] count = tcp.server.count_new color = "RED" else: data = tcp.client.data[:tcp.client.count_new] count = tcp.client.count_new color = "GREEN" if tcp.module_data['verbose']: chop.tsprettyprnt( color, "%s:%s -> %s:%s %i bytes" % (src, sport, dst, dport, count)) if 'xor_key' in tcp.module_data: data = multibyte_xor(data, tcp.module_data['xor_key']) if tcp.module_data['hexdump']: data = hexdump(data) chop.prettyprnt(color, data) tcp.discard(count)
def handleStream(tcp): ((src, sport), (dst, dport)) = parse_addr(tcp) if tcp.server.count_new > 0: data = tcp.server.data[:tcp.server.count_new] count = tcp.server.count_new direction = 'to_server' color = "RED" else: data = tcp.client.data[:tcp.client.count_new] count = tcp.client.count_new direction = 'to_client' color = "GREEN" if tcp.module_data['verbose']: chop.tsprettyprnt( color, "%s:%s -> %s:%s %i bytes (H = %0.2f)" % (src, sport, dst, dport, count, entropy(data))) if tcp.module_data['oneshot']: tcp.stream_data['data'] += data if tcp.module_data['oneshot_split']: tcp.stream_data[direction] += data if tcp.module_data['oneshot'] or tcp.module_data['oneshot_split']: return if 'xor_key' in tcp.module_data: data = multibyte_xor(data, tcp.module_data['xor_key']) if tcp.module_data['hexdump']: data = hexdump(data) if module_data['base64']: data = b64encode(data) chop.prettyprnt(color, data) chop.json({'payload': data, 'direction': direction}) tcp.discard(count)
def decode_command( dest, command, payload, command_list): """ Print out the command info response from command_conversion. Args: dest: a string containing either 'server' or 'client' to dictate which direction the packet is going. command: hex string of the command byte payload: hex string of the packet payload data """ if (dest == 'server'): decoded_text, payload = command_conversion(command, payload, command_list) chop.tsprnt('server -> client') if decoded_text: chop.tsprnt('EvilGrab Command: %s => %s' % (binascii.hexlify(command), decoded_text)) if payload: chop.tsprnt('EvilGrab Command Payload:') if len(payload) > 32: chop.tsprnt(hexdump(payload[:16]).strip()) chop.tsprnt(hexdump(payload[16:32]).strip()) else: chop.tsprnt(hexdump(payload).strip()) else: #print the hexdump of non-commands chop.tsprnt("Unknown command: %x" % ord(command)) elif dest == 'client': decoded_text, payload = command_conversion(command, payload, command_list) chop.tsprnt('client -> server') chop.tsprnt('Exfil Type: %s => %s' % (binascii.hexlify(command), decoded_text)) ## lets check out the initial system data sent #chop.tsprnt("%s" % binascii.hexlify(command).lower()) if binascii.hexlify(command).lower() == "a0" and payload: # the data should be pipe delimited, # but its a string so lets split on NULL and write the data portion split_payload = payload.split("\x00") chop.tsprnt('%r' % split_payload[0]) elif payload: chop.tsprnt('EvilGrab Exfil Payload: ') if len(payload) > 32: chop.tsprnt(hexdump(payload[:16]).strip()) chop.tsprnt(hexdump(payload[16:32]).strip()) else: chop.tsprnt(hexdump(payload).strip()) else: chop.tsprnt('unk -> unk')
def handleDatagram(udp): ((src, sport), (dst, dport)) = udp.addr chop.tsprnt("UDP %s:%s - %s:%s (%dB)" % (src, sport, dst, dport, len(udp.data))) buffer = udp.data offset = udp.module_data['emu'].shellcode_getpc_test(buffer) if offset >= 0: udp.stop udp.module_data['emu'].prepare(buffer, offset) udp.module_data['emu'].test() chop.tsprnt("UDP %s:%s - %s:%s contains shellcode in [0:%d] @ offset %d" % (src, sport, dst, dport, len(udp.data), offset)) if udp.module_data['cliargs']['hexdump']: data = hexdump(buffer[offset:]) chop.prnt("\n" + data) if udp.module_data['cliargs']['shellprofile']: buffer_profile = udp.module_data['emu'].emu_profile_output chop.prnt("\n" + buffer_profile) udp.module_data['emu'].free()
def handleStream(tcp): ((src, sport), (dst, dport)) = parse_addr(tcp) if tcp.server.count_new > 0: data = tcp.server.data[:tcp.server.count_new] count = tcp.server.count_new direction = 'to_server' color = "RED" else: data = tcp.client.data[:tcp.client.count_new] count = tcp.client.count_new direction = 'to_client' color = "GREEN" if tcp.module_data['verbose']: chop.tsprettyprnt(color, "%s:%s -> %s:%s %i bytes (H = %0.2f)" % (src, sport, dst, dport, count, entropy(data))) if tcp.module_data['oneshot']: tcp.stream_data['data'] += data if tcp.module_data['oneshot_split']: tcp.stream_data[direction] += data if tcp.module_data['oneshot'] or tcp.module_data['oneshot_split']: return if 'xor_key' in tcp.module_data: data = multibyte_xor(data, tcp.module_data['xor_key']) if tcp.module_data['hexdump']: data = hexdump(data) if tcp.module_data['base64']: data = b64encode(data) chop.prettyprnt(color, data) chop.json({'payload': data, 'direction': direction}) tcp.discard(count)
def execution(path, body, module_data): key = module_data['key'] opcodes = module_data['opcodes'] verbose = module_data['verbose'] blob = b64decode(path, '_-') cryptobj = rc4(key=key) decrypted = cryptobj.crypt(blob) chop.tsprnt("Command request from %s" % decrypted) if body: data = b64decode(body, '_-') cryptobj = rc4(key=key) decrypted = cryptobj.crypt(data) if len(decrypted) < 4: chop.tsprnt("Command response length invalid.") return opcode = struct.unpack('<I', decrypted[:4])[0] if opcode in opcodes: opcodes[opcode](decrypted[4:]) else: chop.tsprnt("Unknown opcode (%i)" % opcode) if verbose: chop.tsprnt("Data:\n%s" % hexdump(decrypted))
def handleStream(tcp): ((src, sport), (dst, dport)) = tcp.addr direction = "NA" count = 0 if tcp.server.count_new > 0: buffer = tcp.server.data[:tcp.server.count_new] server_count = tcp.server.count_new chop.tsprnt("TCP %s:%s -> %s:%s (CTS: %dB)" % (src, sport, dst, dport, server_count)) tcp.discard(server_count) direction = "CTS" count = server_count else: buffer = tcp.client.data[:tcp.client.count_new] client_count = tcp.client.count_new chop.tsprnt("TCP %s:%s <- %s:%s (STC: %dB)" % (src, sport, dst, dport, client_count)) tcp.discard(client_count) direction = "STC" count = client_count offset = tcp.module_data['emu'].shellcode_getpc_test(buffer) if offset >= 0: tcp.stop() tcp.module_data['emu'].prepare(buffer, offset) tcp.module_data['emu'].test() chop.tsprnt("TCP %s:%s - %s:%s contains shellcode in %s[0:%d] @ offset %d" % (src, sport, dst, dport, direction, count, offset)) if tcp.module_data['cliargs']['hexdump']: data = hexdump(buffer[offset:]) chop.prnt("\n" + data) if tcp.module_data['cliargs']['shellprofile']: buffer_profile = tcp.module_data['emu'].emu_profile_output chop.prnt("\n" + buffer_profile) tcp.module_data['emu'].free()
def cmd_exec(data): chop.tsprnt("EXEC (not implemented)\n%s" % hexdump(data))
def cmd_putfile(data): chop.tsprnt("PUTFILE (not implemented)\n%s" % hexdump(data))
def token_exception(msg, tcp): chop.prnt("token_exception\n%s" % hexdump(msg))
def cmd_readfile(data): chop.tsprnt("READFILE (not implemented)\n%s" % hexdump(data))
def command_fail(data, module_data): # XXX: Pretty sure this will be base64 and rc4 like the rest, but I # don't have real data to test with yet. chop.tsprnt("Command failure (not implemented):\n%s" % hexdump(data))
def command_webcam_enablecompress(msg, tcp): chop.prnt("command_webcam_enablecompress\n%s" % hexdump(msg))
def cmd_sleep(data): chop.tsprnt("SLEEP (not implemented)\n%s" % hexdump(data))
def cmd_uninstall(data): chop.tsprnt("UNINSTALL (not implemented)\n%s" % hexdump(data))
def token_get_filedata(msg, tcp): chop.prnt("token_get_filedata\n%s" % hexdump(msg))
def token_auth(msg, tcp): chop.prnt("token_auth\n%s" % hexdump(msg))
def command_rename_remark(msg, tcp): chop.prnt("command_rename_remark\n%s" % hexdump(msg))
def token_heartbeat(msg, tcp): chop.prnt("token_heartbeat\n%s" % hexdump(msg))
def put_file(data, body, module_data): # XXX: The actual file contents should be in body, and are likely base64 # and rc4 like the rest. chop.tsprnt("Putfile (not implemented):\n%s" % hexdump(body))
uncomp_len = struct.unpack('<I', server_data[offset+9:offset+13])[0] if tcp.module_data["verbose"]: chop.tsprnt(("offset: %i - comp: %i - uncomp: %i - len: %i" % (offset,comp_len, uncomp_len, len(server_data[offset:offset+comp_len])))) # If have full zlib bundle decoded it, else buffer if comp_len <= len(server_data[offset:]): try: decoded = zlib.decompress(server_data[offset+13:offset+comp_len]) #hexdump(decoded) # The first byte of most commands is a command flag # List drives if decoded[0] == "\x67": chop.tsprnt("Drive info") chop.tsprnt(hexdump(decoded)) # This command returns some system info. This decode # is a little crude, we're going to replace strings of # '\x00' with a space and then remove individual '\x00' # from unicode strings. elif decoded[0] == "\x66": p = re.compile("\x00\x00+") chop.tsprnt("%s" % p.sub(" ", decoded[1:]).replace("\x00", "")) elif decoded[0] =="\x69": chop.tsprnt("%s" % decoded[1:].replace("\x00", "")) # Response to an 0x03 command to print a file elif decoded[0] == "\x6a": None
def command_replay_heartbeat(msg, tcp): chop.prnt("command_replay_heartbeat\n%s" % hexdump(msg))
def command_exception(msg, tcp): chop.prnt("command_exception\n%s" % hexdump(msg))
def command_webcam_resize(msg, tcp): chop.prnt("command_webcam_resize\n%s" % hexdump(msg))