Last active
October 3, 2020 09:13
-
-
Save MrAdz350/78421f040631002660c4194f630abf7a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import binascii | |
from array import array | |
from unicorn import * | |
from unicorn.x86_const import * | |
import string | |
import itertools | |
import pexpect | |
# I started off bruting the whole ASCII keyspace, then narrowed it down to [A-Za-z\, \.]. | |
#perms = [list(itertools.permutations(string.printable,1)),list(itertools.permutations(string.printable,2)),list(itertools.permutations(string.printable,3))] | |
#keyspace = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz .," | |
# Then I figured out that the key was only a small subset of characters after watching the first few keys pop out. This tweak shaved literal hours off of the crack time. | |
#keyspace = "inds glw.eHthofA,urkybac" | |
# Then I spotted that only particular unique groups of 1,2 & 3 chars were being used. This drops the run time to < 2 minutes! | |
perms = [] | |
perms.append(['f', ' ','.','e','r', 'g']) | |
perms.append(['ow','ll','no',' H', 'ng ', 'e ','in','of', ' w','is', 'ur']) | |
perms.append(['lik', 'thi', 'ds ', 'Ah,','hot','ng ','ace','the',' in', ' bl',' yo']) | |
# Lazy way to insert a str in a str | |
def insert (source_str, insert_str, pos): | |
return source_str[:pos]+insert_str+source_str[pos:] | |
def readMagic(): | |
f = open("magic","r") | |
data = f.read() | |
f.close() | |
start = 0x5100 | |
params = [] | |
for i in range(33): | |
j = ((i << 3) + i) << 5 | |
jStart = start + j | |
mFunc = binascii.hexlify(data[jStart:jStart+8][::-1]) | |
mFuncSize = binascii.hexlify(data[jStart+8:jStart+12][::-1]) | |
mKeyOffset = binascii.hexlify(data[jStart+12:jStart+16][::-1]) | |
mLoopCount = binascii.hexlify(data[jStart+16:jStart+20][::-1]) | |
mOutOffset = binascii.hexlify(data[jStart+20:jStart+24][::-1]) | |
mFuncXOR = binascii.hexlify(data[jStart+24:jStart+32][::-1]) | |
mRefVars = binascii.hexlify(data[jStart+32:jStart+64]) | |
params.append([mFunc,mFuncSize,mKeyOffset,mLoopCount,mOutOffset,mFuncXOR,mRefVars]) | |
# Pull out all the magic functions | |
shellcodes = [] | |
for i in range(33): | |
# Extract and XOR decode magic func shellcode | |
a = array("B",data[int(params[i][0],16)-0x400000:(int(params[i][0],16)-0x400000) + int(params[i][1],16)]) | |
b = array("B",data[int(params[i][5],16)-0x600000:(int(params[i][5],16)-0x600000) + int(params[i][1],16)]) | |
c = None | |
c = bytearray() | |
for j in range(int(params[i][1],16)): | |
c.append(a[j] ^ b[j]) | |
shellcodes.append(c) | |
return params,shellcodes | |
def brutus(uKey,kOff,iNum,params,shellcodes): | |
ADDRESS = 0x400000 | |
STACK = 0x410000 | |
UKEYMEM = 0x420000 | |
ENCKEYMEM = 0x430000 | |
STACK_SIZE = 1024 * 1024 | |
dummyKey = insert("ABCDEFGHIJKLMNOPQRTSUOAHSHAOISVHAVHDAOSVHSDABCDEFGHIJKLMNOPQRTSUOAHSHAOISVHAVHDAOSVHSD1111111",uKey,kOff) | |
# Initialize emulator in X86-32bit mode | |
mu = Uc(UC_ARCH_X86, UC_MODE_64) | |
# map 2MB memory for this emulation | |
mu.mem_map(ADDRESS, 5 * 1024 * 1024) | |
# write machine code to be emulated to memory | |
mu.mem_write(ADDRESS, binascii.unhexlify(binascii.hexlify(shellcodes[iNum]))) | |
mu.mem_write(UKEYMEM, dummyKey) | |
mu.mem_write(ENCKEYMEM,binascii.unhexlify(params[iNum][6][0:16])) | |
mu.mem_write(ENCKEYMEM + 8,binascii.unhexlify(params[iNum][6][16:32])) | |
mu.mem_write(ENCKEYMEM + 16, binascii.unhexlify(params[iNum][6][32:48])) | |
# initialize machine registers | |
mu.reg_write(UC_X86_REG_ESI, int(params[iNum][3])) | |
mu.reg_write(UC_X86_REG_RAX, UKEYMEM) | |
mu.reg_write(UC_X86_REG_RDI, UKEYMEM + kOff) | |
mu.reg_write(UC_X86_REG_RDX, ENCKEYMEM) | |
mu.reg_write(UC_X86_REG_RSP, STACK + STACK_SIZE - 1) | |
mu.emu_start(ADDRESS, ADDRESS + (len(binascii.unhexlify(binascii.hexlify(shellcodes[iNum]))) -1)) | |
return mu.reg_read(UC_X86_REG_RAX) | |
def doDaBrute(params,codes): | |
keys = bytearray(69) | |
for i in range(0,33): | |
found = False | |
for p in perms[int(params[i][3]) -1]: | |
if brutus("".join(p),16,i,params,codes) != 0: | |
found = True | |
keys[int(params[i][2],16):int(params[i][2],16) + int(params[i][3],16)] = "".join(p) | |
break | |
if found is False: | |
print("Error no key found") | |
return keys.decode("UTF-8") | |
def doMain(): | |
masterKeys = [] | |
child = pexpect.spawn("./magic") | |
child.expect("Challenge.+") | |
print(child.before) | |
print(child.after) | |
for i in range(0,666): | |
magicParams,magicCodes = readMagic() | |
thisKey = doDaBrute(magicParams,magicCodes) | |
masterKeys.append(thisKey) | |
print("Key " + str(i) + ":" + thisKey) | |
child.sendline(thisKey) | |
child.expect("Challenge.+") | |
print(child.before) | |
print(child.after) | |
magicParams,magicCodes = readMagic() | |
thisKey = doDaBrute(magicParams,magicCodes) | |
masterKeys.append(thisKey) | |
print("Key " + str(i) + ":" + thisKey) | |
child.sendline(thisKey) | |
child.expect(".+") | |
print(child.before) | |
print(child.after) | |
return masterKeys |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment