Guest User

Untitled

a guest
Jul 19th, 2018
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.19 KB | None | 0 0
  1. #!/usr/bin/env python
  2. """htl_extract.py, Extracts the embedded source code from Cisco Security Agent Management Console.
  3. Gerry Eisenhaur <gerry@hiredhacker.com>
  4. """
  5. import os
  6. import sys
  7. import struct
  8. import pefile
  9. from itertools import takewhile
  10.  
  11. _KEY = 'Copyright material protected by a technological protection measure!'
  12. _KEY_LEN = len(_KEY)
  13.  
  14. def get_section_by_name(pe, name):
  15. try:
  16. section = filter(lambda s: s.Name == name, pe.sections)[0]
  17. except IndexError, e:
  18. return None
  19. return section
  20.  
  21. def not_null(c):
  22. return c != '\0'
  23.  
  24. def decrypt_data(data):
  25. decrypted_data = []
  26. for idx, val in enumerate(data):
  27. decrypted_data.append(chr(ord(val) - ord(_KEY[idx % _KEY_LEN])))
  28. return ''.join(decrypted_data)
  29.  
  30. def main(output_path="./extracted", filename="webadmin.exe", section_name="htlconst"):
  31. pe = pefile.PE(filename, fast_load=True)
  32.  
  33. # Create the output path is needed, then chdir to it
  34. output_path = os.path.abspath(output_path)
  35. if not os.path.isdir(output_path):
  36. os.makedirs(output_path)
  37. os.chdir(output_path)
  38.  
  39. # Filename to search for when locating the file table
  40. search_string = "login.htl"
  41.  
  42. # The htlconst section contains all the data we need
  43. htlconst = get_section_by_name(pe, section_name)
  44. assert htlconst is not None, "Could not find section: %s" % section_name
  45.  
  46. image_base = pe.OPTIONAL_HEADER.ImageBase
  47.  
  48. try:
  49. # Get index of known filename in htlconst section data
  50. filename_offset = htlconst.data.index(search_string)
  51. except ValueError:
  52. sys.exit("Could not find search string: %s" % search_string)
  53.  
  54. # Get address of known filename in htlconst section
  55. filename_rva = filename_offset + htlconst.VirtualAddress + image_base
  56.  
  57. # Search for a pointer to the filename
  58. filename_ptr = struct.pack("I", filename_rva)
  59. assert filename_ptr in htlconst.data, "Could not find pointer to filename"
  60.  
  61. # Search back for 0x00000000 and add 4 to get the start of the struct
  62. table_offset = None
  63. filename_ptr_idx = htlconst.data.index(filename_ptr)
  64.  
  65. # Is there a better way todo this?
  66. for idx in reversed(xrange(0, filename_ptr_idx, 4)):
  67. if htlconst.data[idx:idx+4] == "\x00\x00\x00\x00":
  68. table_offset = idx + 4
  69. break
  70. assert table_offset is not None, "Could not find start of file table"
  71.  
  72. cur_offset = table_offset
  73. while True:
  74. # unpack pointers to the filename and its 'encrypted' contents
  75. (ptr_filename, ptr_data) = struct.unpack('II', htlconst.data[cur_offset:cur_offset + 8])
  76.  
  77. # Check for the end of the structure
  78. if not htlconst.contains_rva(ptr_data - image_base):
  79. break
  80.  
  81. filename = pe.get_string_at_rva(ptr_filename - image_base)
  82. print '[+] Extracting: %s' % filename
  83.  
  84. data_offset = (ptr_data - image_base - htlconst.VirtualAddress)
  85. encrypted_data = takewhile(not_null, htlconst.data[data_offset:])
  86. decrypted_data = decrypt_data(encrypted_data)
  87.  
  88. f = open(filename, 'w')
  89. f.write(decrypted_data)
  90. f.close()
  91. cur_offset += 8
  92. print "[+] Done extracting %d files." % ((cur_offset - table_offset)/8)
  93.  
  94. if __name__ == "__main__":
  95. main()
Add Comment
Please, Sign In to add comment