''' Author: Alexander Hanel Name: pe_brute_xor.py Purpose: - POC that searches for n-grams and uses them as the XOR key. - Portable executables can contain a lot of padding because of section alignment. - When the padding is XORed it will imprint the XOR key. - For example the following hex shows some padding (not caused by section alignment).00000000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 |MZ..............|00000010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |........@.......|00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|00000030 00 00 00 00 00 00 00 00 00 00 00 00 f8 00 00 00 |................|00000040 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 |........!..L.!Th| - The data was XORed with a key of J7QkcaYItXEsuDzUfhfmpUHx3k3Y0aHL. - Remnants of the XOR key can be seen in the padding starting at 0x30.00000000 07 6d c1 6b 60 61 59 49 70 58 45 73 8a bb 7a 55 |.m.k`aYIpXEs..zU|00000010 de 68 66 6d 70 55 48 78 73 6b 33 59 30 61 48 4c |.hfmpUHxsk3Y0aHL|00000020 4a 37 51 6b 63 61 59 49 74 58 45 73 75 44 7a 55 |J7QkcaYItXEsuDzU|00000030 66 68 66 6d 70 55 48 78 33 6b 33 59 c8 61 48 4c |fhfmpUHx3k3Y.aHL|00000040 44 28 eb 65 63 d5 50 84 55 e0 44 3f b8 65 2e 3d |D(.ec.P.U.D?.e.=| - By searching the most common occuring n-grams the XOR key can be predicited. - 9u8jreve is an encoded Locky payload. word@up:~/Downloads$ python pe_brute_xor.py 9u8jreve Length: 32, Count: 253 Key: J7QkcaYItXEsuDzUfhfmpUHx3k3Y0aHL File Name: 0.bin'''importsysimportpefileimportrefromcollectionsimportCounterfromitertoolsimportcycledefxor_mb(message,key):'''Multi-byte XOR of a string message and string key'''return''.join(chr(ord(m_byte)^ord(k_byte))form_byte,k_byteinzip(message,cycle(key)))defpe_carv(data):'''carve out executable using pefile's trim'''c=1foroffsetin[temp.start()fortempinre.finditer('\x4d\x5a',data)]:# slice out executable temp_buff=data[offset:]try:pe=pefile.PE(data=temp_buff)except:continuereturnpe.trim()returnNonedefrun():data=open(sys.argv[1],'rb').read()c=0used_key=""# source http://stackoverflow.com/a/25071991# most common XOR key sizesfornin[2,4,8,16,32,64,128,256,512]:substr_counter=Counter(data[i:i+n]foriinrange(len(data)-n))# get top 32 most commonsub_count=substr_counter.most_common(32)fortempinsub_count:key,count=tempifcount==1:breaktemp=xor_mb(data,key)pe_c=pe_carv(temp)ifpe_c:print"Length: %s, Count: %s Key: %s File Name: %s.bin"%(len(key),count,key,str(c))f=open(str(c)+".bin","wb")fk=open("key-"+str(c)+".bin","wb")f.write(temp)fk.write(key)f.close()fk.close()c+=1# comment out if you want to see all the keys. # It will match the same key but of different sizes. returnrun()
Comments (0)
HTTPSSSH
You can clone a snippet to your computer for local editing.
Learn more.