We can add some color via the following Python code.
import matplotlib.pyplot as plt import numpy as np import sys def main(): data = open(sys.argv[1], 'rb').read()[:512] dlist = bytearray(data) print len(dlist) plotters = np.array(dlist) plotters.shape = (32,16) #plt.bone() plt.flag() plt.axis([0,16,0, 32]) plt.pcolormesh(plotters) plt.show() plt.savefig('test.png') plt.close() if __name__ == '__main__': main()
The code reads the first 512 bytes of a file, puts each byte into a bytearray and then plots the color in the same structure as the hex dump. If we were to pass an executable file to this script we would get the following pretty picture.
The bottom left hand corner byte is 0x4d 'M' the second is 0x5a 'Z' and so on. If we were to XOR the executable with 0x88 we would get the following image.
XOR 0x88 Key |
import sys import struct # read file into a bytearray byte = bytearray(open(sys.argv[1], 'rb').read()) # for each byte in the file stream, excluding the last 256 bytes for i in range(0, len(byte) - 256): # KEY ^ VALUE ^ KEY = VALUE; Simple way to get the key key = byte[i] ^ ord('M') # verify the two bytes contain 'M' & 'Z' if chr(byte[i] ^ key) == 'M' and chr(byte[i+1] ^ key) == 'Z': # skip non-XOR encoded MZ if key == 0: continue # read four bytes into temp, offset to PE aka lfanew temp = byte[(i + 0x3c) : (i + 0x3c + 4)] # decode values with key lfanew = [] for x in temp: lfanew.append( x ^ key) # convert from bytearray to int value, probably a better way to do this pe_offset = struct.unpack( '<i', str(bytearray(lfanew)))[0] # verify results are not negative or read is bigger than file if pe_offset < 0 or pe_offset > len(byte): continue # verify the two decoded bytes are 'P' & 'E' if byte[pe_offset + i ] ^ key == ord('P') and byte[pe_offset + i + 1] ^ key == ord('E'): print "Encoded PE Found, Key %x, Offset %x" % (key, i) ~
Speed, false postives testing, etc are all probably areas of improvement for the code.
If we were to run this on the executable XORed with 0x88 we would be present with the following output Encoded PE Found, Key 88, Offset 0. Here is a script that will automatically find a XOR encoded executable and carve it out using the above code and Pefile.
Kind of a cool technique to use the Portable Executable structure to find XOR exes. It only works on single byte executables. Could be modified for 2 or 4 bytes. Not sure about anything higher. A brute force approach would probably be better for key byte size of anything higher than 4. The skeleton is prevalent when an executable is XORed with a key of five bytes in size. Using gray tones can help show the skeleton because the contrast is dulled.
Useful Links
http://tomchop.me/2012/12/yo-dawg-i-heard-you-like-xoring/
http://hiddenillusion.blogspot.com/2013/01/nomorexor.html
http://playingwithothers.com/2012/12/20/decoding-xor-shellcode-without-a-key/
http://www.cloudshield.com/blog/advanced-malware/how-to-efficiently-detect-xor-encoded-content-part-1-of-2/
http://digital-forensics.sans.org/blog/2013/05/14/tools-for-examining-xor-obfuscation-for-malware-analysis
Side Note:
I have to admit I'm a huge fan of using ByteArrays now. I wish I could have of learned of them sooner. They are very useful for writing decoders. It remove a lot of the four play of checking the computed size ( value & 0xFF), using ord() and using chr().
No comments:
Post a Comment