def cmd_parent(self, *args): parser = argparse.ArgumentParser(prog='tags', description="Set the Parent for this file.") parser.add_argument('-a', '--add', metavar='SHA256', help="Add parent file by sha256") parser.add_argument('-d', '--delete', action='store_true', help="Delete Parent") parser.add_argument('-o', '--open', action='store_true', help="Open The Parent") try: args = parser.parse_args(args) except: return # This command requires a session to be opened. if not __sessions__.is_set(): self.log('error', "No open session") parser.print_usage() return # If no arguments are specified, there's not much to do. if args.add is None and args.delete is None and args.open is None: parser.print_usage() return db = Database() if not db.find(key='sha256', value=__sessions__.current.file.sha256): self.log('error', "The opened file is not stored in the database. " "If you want to add it use the `store` command.") return if args.add: if not db.find(key='sha256', value=args.add): self.log('error', "the parent file is not found in the database. ") return db.add_parent(__sessions__.current.file.sha256, args.add) self.log('info', "parent added to the currently opened file") self.log('info', "Refreshing session to update attributes...") __sessions__.new(__sessions__.current.file.path) if args.delete: db.delete_parent(__sessions__.current.file.sha256) self.log('info', "parent removed from the currently opened file") self.log('info', "Refreshing session to update attributes...") __sessions__.new(__sessions__.current.file.path) if args.open: # Open a session on the parent if __sessions__.current.file.parent: __sessions__.new(get_sample_path(__sessions__.current.file.parent[-64:])) else: self.log('info', "No parent set for this sample")
def run(self, *args): try: args = self.parser.parse_args(args) except SystemExit: return # This command requires a session to be opened. if not __sessions__.is_set(): self.log('error', "No open session. This command expects a file to be open.") self.parser.print_usage() return # If no arguments are specified, there's not much to do. if args.add is None and args.delete is None and args.open is None: self.parser.print_usage() return db = Database() if not db.find(key='sha256', value=__sessions__.current.file.sha256): self.log('error', "The opened file is not stored in the database. " "If you want to add it use the `store` command.") return if args.add: if not db.find(key='sha256', value=args.add): self.log('error', "the parent file is not found in the database. ") return db.add_parent(__sessions__.current.file.sha256, args.add) self.log('info', "parent added to the currently opened file") self.log('info', "Refreshing session to update attributes...") __sessions__.new(__sessions__.current.file.path) if args.delete: db.delete_parent(__sessions__.current.file.sha256) self.log('info', "parent removed from the currently opened file") self.log('info', "Refreshing session to update attributes...") __sessions__.new(__sessions__.current.file.path) if args.open: # Open a session on the parent if __sessions__.current.file.parent: __sessions__.new(get_sample_path(__sessions__.current.file.parent[-64:])) else: self.log('info', "No parent set for this sample")
def decompress(self, dump_dir): # Check if the file type is right. # TODO: this might be a bit hacky, need to verify whether malformed # Flash exploit would get a different file type. if 'Flash' not in __sessions__.current.file.type: self.log( 'error', "The opened file doesn't appear to be a valid SWF object") return # Retrieve key information from the opened SWF file. header, version, size, data = self.parse_swf() # Decompressed data. decompressed = None compressed = True # Check if the file is already a decompressed Flash object. if header == b'FWS': self.log('info', "The opened file doesn't appear to be compressed") decompressed = data compressed = False # Check if the file is compressed with zlib. elif header == b'CWS': self.log('info', "The opened file appears to be compressed with Zlib") # Open an handle on the compressed data. compressed = BytesIO(data) # Skip the header. compressed.read(3) # Decompress and reconstruct the Flash object. decompressed = b'FWS' + compressed.read(5) + zlib.decompress( compressed.read()) # Check if the file is compressed with lzma. elif header == b'ZWS': self.log('info', "The opened file appears to be compressed with Lzma") # We need an third party library to decompress this. if not HAVE_PYLZMA: self.log( 'error', "Missing dependency, please install pylzma (`pip install pylzma`)" ) return # Open and handle on the compressed data. compressed = BytesIO(data) # Skip the header. compressed.read(3) # Decompress with pylzma and reconstruct the Flash object. # # ZWS(LZMA) # # | 4 bytes | 4 bytes | 4 bytes | 5 bytes | n bytes | 6 bytes | # # | 'ZWS'+version | scriptLen | compressedLen | LZMA props | LZMA data | LZMA end marker | decompressed = b'FWS' + compressed.read(5) compressed.read(4) # skip compressedLen decompressed += pylzma.decompress(compressed.read()) # If we obtained some decompressed data, we print it and eventually # dump it to file. if decompressed: # Print the decompressed data # TODO: this prints too much, need to find a better wayto display # this. Paginate? self.log('', cyan(hexdump(decompressed))) if compressed and dump_dir: # Dump the decompressed SWF file to the specified directory # or to the default temporary one. dump_path = os.path.join( dump_dir, '{0}.swf'.format(get_md5(decompressed))) with open(dump_path, 'wb') as handle: handle.write(decompressed) self.log('info', "Flash object dumped at {0}".format(dump_path)) # Set the parent-child relation between CWS-FWS this_parent = __sessions__.current.file.sha256 # Directly open a session on the dumped Flash object. __sessions__.new(dump_path) db = Database() # Make sure parents is in database if not db.find(key='sha256', value=this_parent): self.log('error', "the parent file is not found in the database. ") else: db.add_parent(__sessions__.current.file.sha256, this_parent)
def decompress(self, dump_dir): # Check if the file type is right. # TODO: this might be a bit hacky, need to verify whether malformed # Flash exploit would get a different file type. if 'Flash' not in __sessions__.current.file.type: self.log('error', "The opened file doesn't appear to be a valid SWF object") return # Retrieve key information from the opened SWF file. header, version, size, data = self.parse_swf() # Decompressed data. decompressed = None compressed = True # Check if the file is already a decompressed Flash object. if header == b'FWS': self.log('info', "The opened file doesn't appear to be compressed") decompressed = data compressed = False # Check if the file is compressed with zlib. elif header == b'CWS': self.log('info', "The opened file appears to be compressed with Zlib") # Open an handle on the compressed data. compressed = BytesIO(data) # Skip the header. compressed.read(3) # Decompress and reconstruct the Flash object. decompressed = b'FWS' + compressed.read(5) + zlib.decompress(compressed.read()) # Check if the file is compressed with lzma. elif header == b'ZWS': self.log('info', "The opened file appears to be compressed with Lzma") # We need an third party library to decompress this. if not HAVE_PYLZMA: self.log('error', "Missing dependency, please install pylzma (`pip install pylzma`)") return # Open and handle on the compressed data. compressed = BytesIO(data) # Skip the header. compressed.read(3) # Decompress with pylzma and reconstruct the Flash object. # # ZWS(LZMA) # # | 4 bytes | 4 bytes | 4 bytes | 5 bytes | n bytes | 6 bytes | # # | 'ZWS'+version | scriptLen | compressedLen | LZMA props | LZMA data | LZMA end marker | decompressed = b'FWS' + compressed.read(5) compressed.read(4) # skip compressedLen decompressed += pylzma.decompress(compressed.read()) # If we obtained some decompressed data, we print it and eventually # dump it to file. if decompressed: # Print the decompressed data # TODO: this prints too much, need to find a better wayto display # this. Paginate? self.log('', cyan(hexdump(decompressed))) if compressed and dump_dir: # Dump the decompressed SWF file to the specified directory # or to the default temporary one. dump_path = os.path.join(dump_dir, '{0}.swf'.format(get_md5(decompressed))) with open(dump_path, 'wb') as handle: handle.write(decompressed) self.log('info', "Flash object dumped at {0}".format(dump_path)) # Set the parent-child relation between CWS-FWS this_parent = __sessions__.current.file.sha256 # Directly open a session on the dumped Flash object. __sessions__.new(dump_path) db = Database() # Make sure parents is in database if not db.find(key='sha256', value=this_parent): self.log('error', "the parent file is not found in the database. ") else: db.add_parent(__sessions__.current.file.sha256, this_parent)