Advertisement
aaSSfxxx

Citadel/Ice IX config extractor

Dec 16th, 2012
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.22 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. # ZBot (Citadel/Ice IX) config extractor, written in python2
  4. # Wrote by aaSSfxxx
  5.  
  6. # WARNING: this code is unstable (dirty finding of "call" opcodes), and could
  7. # make the extractor crash or find nothing. If it's the case, reverse manually the bot.
  8.  
  9. import pefile
  10. import sys
  11. import struct
  12.  
  13. def find_str(str):
  14.     tmp = ""
  15.     for i in str:
  16.         if ord(i) != 0:
  17.             tmp += i
  18.         else:
  19.             break
  20.     return tmp
  21.  
  22. #Gets the first far call relative address of a function (really dirty function)
  23. def get_first_far_call_rel(str):
  24.     calloff = str.find("\xe8")
  25.     return struct.unpack("l", str[calloff+1:calloff+5])[0] + 5 + calloff
  26.  
  27. # Finds the "real" entry point of a Zbot (bacause citadel does a "jmp start_0" at the EP)
  28. def find_real_ep(ep):
  29.     global mem
  30.     # Compare if opcode of EP is a long jump
  31.     if(ord(mem[ep]) == 0xe9):
  32.         # If it is the case, get reljump & do a recursive finding (to avoid inception-like
  33.         # jmp)
  34.         realep = struct.unpack("l", mem[ep+1:ep+5])[0]
  35.         return find_real_ep(ep + realep + 5)
  36.     else:
  37.         # If no jmp found, just return the right address.
  38.         return ep
  39.  
  40. #Parses the bot's PE header
  41. malw = pefile.PE(sys.argv[1])
  42.  
  43. #Get the botkey address and virtual memory
  44. botkey = malw.sections[2].VirtualAddress
  45. mem = malw.get_memory_mapped_image()
  46.  
  47. #Get the malware EP
  48. ep = malw.OPTIONAL_HEADER.AddressOfEntryPoint
  49. ep = find_real_ep(ep)
  50.  
  51. #Grab address of bot init function
  52. initfunc = get_first_far_call_rel (mem[ep:ep+50]) + ep
  53. #Grab the address of the config extractor function (should grab both Ice IX & citadel)
  54. grabconffunc = get_first_far_call_rel(mem[initfunc+0x2d0:initfunc+0x300]) + initfunc + 0x2d0
  55. #Grab length of config
  56. len = struct.unpack("L", mem[grabconffunc+2: grabconffunc+6])[0]
  57. #Grab address of structure
  58. confaddr = struct.unpack("L", mem[grabconffunc+8:grabconffunc+12])[0] - malw.OPTIONAL_HEADER.ImageBase
  59.  
  60. #Grab config
  61. config = mem[confaddr: confaddr+len]
  62. #Decrypt the config
  63. i=0
  64. safe = ""
  65. for c in config:
  66.     safe += chr((ord(c) ^ ord(mem[botkey+i])))
  67.     i += 1
  68.  
  69. #Find all URL's inside config \o/
  70. offset = safe.find("http")
  71. while offset != -1:
  72.     print find_str(safe[offset:offset+100])
  73.     safe = safe[offset+5:]
  74.     offset = safe.find("http")
  75.    
  76. # ACHIEVEMENT UNLOCKED FAGGOTS \o/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement