import struct def processinput(iblock, blocksize): return (bytes.fromhex('%0*x' % (2 * blocksize, iblock)), None) def processoutput(output, blocksize): return int.from_bytes(output, byteorder='big', signed=False) #engine=deadpool_dfa.Acquisition(targetbin='./main64', targetdata='./libnative-lib.so', goldendata='./libnative-lib.so.gold', # dfa=phoenixAES, processinput=processinput, processoutput=processoutput, verbose=2, minleaf=1, minleafnail=1) # Limited address range to .rodata section for faster results: engine = deadpool_dfa.Acquisition(targetbin='./main64', targetdata='./libnative-lib.so', goldendata='./libnative-lib.so.gold', dfa=phoenixAES, processinput=processinput, processoutput=processoutput, verbose=2, minleaf=1, minleafnail=1, addresses=[0x6350, 0x2b490]) tracefiles_sets = engine.run() for tracefile in tracefiles_sets[0]: if phoenixAES.crack(tracefile): break
import sys, os import deadpool_dfa import phoenixAES def processinput(iblock, blocksize): return (bytes.fromhex('%0*x' % (2 * blocksize, iblock)), ["--stdin"]) def processoutput(output, blocksize): i = int(b''.join([x for x in output.split()]), 16) return i # Initial attack attempt: engine = deadpool_dfa.Acquisition( targetbin='./wb_patched', targetdata='./wb_data', goldendata='./mem.dump', dfa=phoenixAES, processinput=processinput, processoutput=processoutput, maxleaf=0x100, minleaf=0x1, minleafnail=0x1, ) tracefiles_sets = engine.run() for tracefile in tracefiles_sets[0]: if phoenixAES.crack(tracefile, verbose=1): break
def AesGetAllRoundKeys(targetbin, targetdata, goldendata, iblock=0x74657374746573747465737474657374, processinput=deadpool_dfa.processinput, processoutput=deadpool_dfa.processoutput, verbose=1, maxleaf=256 * 256, minleaf=64, minleafnail=8, addresses=None, start_from_left=True, depth_first_traversal=False, faults=4, minfaultspercol=4, timeoutfactor=2, savetraces_format='default', logfile=None, tolerate_error=False, lastroundkeys=[], encrypt=None, outputbeforelastrounds=False, shell=False, debug=False): engine = deadpool_dfa.Acquisition( targetbin, targetdata, goldendata, phoenixAES, iblock, processinput, processoutput, verbose, maxleaf, minleaf, minleafnail, addresses, start_from_left, depth_first_traversal, faults, minfaultspercol, timeoutfactor, savetraces_format, logfile, tolerate_error, encrypt, outputbeforelastrounds, shell, debug) foundkey = True while foundkey: foundkey = False tracefiles_sets = engine.run(lastroundkeys, encrypt) if encrypt is not None: tracefiles = tracefiles_sets[not encrypt] else: assert len(tracefiles_sets[0]) > 0 or len(tracefiles_sets[1]) > 0 if len(tracefiles_sets[0]) > 0: encrypt = True tracefiles = tracefiles_sets[0] elif len(tracefiles_sets[1]) > 0: encrypt = False tracefiles = tracefiles_sets[1] else: tracefiles = [] for tracefile in tracefiles: k = phoenixAES.crack( tracefile, lastroundkeys, encrypt, outputbeforelastrounds and len(lastroundkeys) > 0, verbose) if k: foundkey = True lastroundkeys.append(k) open('lastroundkeys.log', 'w').write('\n'.join(lastroundkeys)) break # Fuzzing directly the input: # This was only tested on encryption! foundkey = False tracefiles_sets = engine.runoninput(lastroundkeys) if encrypt is not None: tracefiles = tracefiles_sets[not encrypt] else: assert len(tracefiles_sets[0]) > 0 or len(tracefiles_sets[1]) > 0 if len(tracefiles_sets[0]) > 0: encrypt = True tracefiles = tracefiles_sets[0] elif len(tracefiles_sets[1]) > 0: encrypt = False tracefiles = tracefiles_sets[1] else: tracefiles = [] for tracefile in tracefiles: k = phoenixAES.crack(tracefile, lastroundkeys, encrypt, outputbeforelastrounds and len(lastroundkeys) > 0, verbose) if k: foundkey = True lastroundkeys.append(k) open('lastroundkeys.log', 'w').write('\n'.join(lastroundkeys)) break if foundkey: p = 0 # null plaintext cint, _, _ = engine.doit(engine.goldendata, processinput(p, 16), lastroundkeys=[]) c = [(cint >> (i << 3) & 0xff) for i in range(16)][::-1] kr0 = phoenixAES.rewind(cint, lastroundkeys, encrypt=encrypt, mimiclastround=False) # Be cautious, round key could be wrong if there is some external encoding... print("First round key found?:\n%032X" % kr0) lastroundkeys.append('%032X' % kr0) return lastroundkeys
#!/usr/bin/env python3 import subprocess import struct import sys sys.path.insert(0, '../../../JeanGrey/') import phoenixAES TRACES = 20 CHALLENGE = './nosuchcon_2013_whitebox_allenc' BLOCKSIZE = 16 TRACEFILE = 'dfa.txt' pairs = [] plain = 0x000102030405060708090a0b0c0d0e0f with open(TRACEFILE, 'wb') as tracefile: for i in range(TRACES): output = subprocess.check_output( [CHALLENGE, '%0*x' % (2 * BLOCKSIZE, plain)]) cipher = int( output[output.find(b'Output:') + 10:].rstrip().replace(b' ', b''), 16) print('%05i %0*X -> %0*X' % (i, 2 * BLOCKSIZE, plain, 2 * BLOCKSIZE, cipher)) tracefile.write( ('%0*X %0*X\n' % (2 * BLOCKSIZE, plain, 2 * BLOCKSIZE, cipher)).encode('utf8')) if i == 0: CHALLENGE = CHALLENGE + "_DFA" phoenixAES.crack(TRACEFILE)
import array import phoenixAES def ary(x): return array.array('B', x) import sys traces = open(sys.argv[1]).read() def fmt(x): return b''.join(b'%02X' % a for a in x) with open('tracefile', 'wb') as f: for line in traces.strip().splitlines(): a, b = [[int(y) for y in x.split(',')] for x in line.split()] f.write(b'%s %s\n' % (fmt(a), fmt(b))) phoenixAES.crack('tracefile')
#!/usr/bin/env python3 import subprocess import struct import sys sys.path.insert(0, '../../../JeanGrey/') import phoenixAES TRACES=20 CHALLENGE='./nosuchcon_2013_whitebox_allenc' BLOCKSIZE=16 TRACEFILE='dfa.txt' pairs=[] plain=0x000102030405060708090a0b0c0d0e0f with open(TRACEFILE, 'wb') as tracefile: for i in range(TRACES): output=subprocess.check_output([CHALLENGE, '%0*x' % (2*BLOCKSIZE, plain)]) cipher=int(output[output.find(b'Output:')+10:].rstrip().replace(b' ', b''), 16) print ('%05i %0*X -> %0*X' % (i, 2*BLOCKSIZE, plain, 2*BLOCKSIZE, cipher)) tracefile.write(('%0*X %0*X\n' % (2*BLOCKSIZE, plain, 2*BLOCKSIZE, cipher)).encode('utf8')) if i==0: CHALLENGE=CHALLENGE+"_DFA" phoenixAES.crack(TRACEFILE)
#!/usr/bin/env python3 import sys import deadpool_dfa import phoenixAES def processinput(iblock, blocksize): # hardcoded in spawn_drmless.py return [''] def processoutput(output, blocksize): # Typical output (Frida mem dump): #- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF #0x00000000 34 1a fa 02 f2 95 e6 fc 0b 08 9e 41 c6 30 27 4b 4..........A.0'K return int(output[output.find(b'0x00000000')+12:output.find(b'0x00000000')+59].replace(b' ', b''), 16) # Key found in 1m50s when addresses are restricted to the sweet spot: engine=deadpool_dfa.Acquisition(targetbin='./spawn_drmless.py', targetdata='./drmless', goldendata='drmless.gold', dfa=phoenixAES, processinput=processinput, processoutput=processoutput, maxleaf=2048, faults=[('nop', lambda x: 0x90)], addresses=(0x1c0000, 0x1d0000), verbose=2) # Key found in 12m40s when addresses are not specified: #engine=deadpool_dfa.Acquisition(targetbin='./spawn_drmless.py', targetdata='./drmless', goldendata='drmless.gold', # dfa=phoenixAES, processinput=processinput, processoutput=processoutput, maxleaf=2048, faults=[('nop', lambda x: 0x90)], verbose=2) tracefiles=engine.run() for trace in tracefiles: if phoenixAES.crack(trace, encrypt=False): break
#!/usr/bin/env python3 import sys import deadpool_dfa import phoenixAES def processinput(iblock, blocksize): return ["--load-tables tables_karroumi_extenc.tbl --extEnc=1 --input-files <(echo %0*x|xxd -r -p) --out-file >(xxd -p)" % (2*blocksize, iblock)] def processoutput(output, blocksize): return int(''.join([x for x in output.decode().split('\n') if len(x)==32][0]), 16) engine=deadpool_dfa.Acquisition(targetbin='./main', targetdata='tables_karroumi_extenc.tbl', goldendata='tables_karroumi_extenc.tbl.gold', maxleaf=64, minleaf=4, minleafnail=1, addresses=(0x57000, 0x5A000), dfa=phoenixAES, processinput=processinput, processoutput=processoutput, shell=True, verbose=2) tracefiles=engine.run() for tracefile in tracefiles: if phoenixAES.crack(tracefile): break