#!/usr/bin/env python3 import sys import deadpool_dfa import phoenixAES def processinput(iblock, blocksize): p='%0*x' % (2*blocksize, iblock) return (None, [p[j*2:(j+1)*2] for j in range(len(p)//2)]) def processoutput(output, blocksize): return int(output, 16) engine=deadpool_dfa.Acquisition(targetbin='./DemoKey_table_encrypt', targetdata='DemoKey_table.bin', goldendata='DemoKey_table.bin.gold', dfa=phoenixAES, processinput=processinput, processoutput=processoutput, verbose=2, maxleaf=0x800, minleaf=0x100, outputbeforelastrounds=True) tracefiles_sets=engine.run() for tracefile in tracefiles_sets[0]: if phoenixAES.crack_file(tracefile): break
#!/usr/bin/env python3 import phoenixAES phoenixAES.convert_r8faults_file("r8faults", "r9faults") phoenixAES.crack_file("r9faults", verbose=2)
#!/usr/bin/env python3 import sys import deadpool_dfa import phoenixAES def processinput(iblock, blocksize): # hardcoded in spawn_drmless.py return (None, None) 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_file(trace, encrypt=False): break
import pathlib import phoenixAES CWD = pathlib.Path(__file__).parent trace_dir = CWD / ".." / "assets" / "wb-traces" for f in trace_dir.iterdir(): x = phoenixAES.crack_file(f) if x is not None: print(x, f.name)
import sys import deadpool_dfa import phoenixAES def processinput(iblock, blocksize): p = '%0*x' % (2 * blocksize, iblock) return (None, [p[j * 2:(j + 1) * 2] for j in range(len(p) // 2)]) def processoutput(output, blocksize): return int(output, 16) engine = deadpool_dfa.Acquisition(targetbin='./DemoKey_table_encrypt', targetdata='DemoKey_table.bin', goldendata='DemoKey_table.bin.gold', dfa=phoenixAES, processinput=processinput, processoutput=processoutput, verbose=2, maxleaf=0x800, minleaf=0x100, outputbeforelastrounds=True) tracefiles_sets = engine.run() for tracefile in tracefiles_sets[0]: if phoenixAES.crack_file(tracefile): break
def dfa(): subkey10 = phoenixAES.crack_file("testcases/tracefile.orig", verbose=1) base_key = reverse_key_schedule(unhexlify(subkey10), 10) print("Main key:") print(base_key.hex().upper())
def dfa(): subkey10 = phoenixAES.crack_file("testcases/aes_arm_thumb_tracefile", verbose=0) base_key = reverse_key_schedule(unhexlify(subkey10), 10) print("Main key:") print(base_key.hex().upper())
#!/usr/bin/env python3 import subprocess import struct import sys sys.path.insert(0, '../../../JeanGrey/phoenixAES/') 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_file(TRACEFILE)
import subprocess import struct import sys sys.path.insert(0, '../../../JeanGrey/phoenixAES/') import phoenixAES TRACES = 20 CHALLENGE = './nosuchcon_2013_whitebox_allenc' BLOCKSIZE = 16 TRACEFILE = 'dfa2.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 + "_DFA2" phoenixAES.crack_file(TRACEFILE)
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_file( tracefile, lastroundkeys, encrypt, outputbeforelastrounds and len(lastroundkeys) > 0, verbose) if k: foundkey = True lastroundkeys.append(bytes.fromhex(k)) open('lastroundkeys.log', 'w').write('\n'.join([l.hex() for l in 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_file( tracefile, lastroundkeys, encrypt, outputbeforelastrounds and len(lastroundkeys) > 0, verbose) if k: foundkey = True lastroundkeys.append(bytes.fromhex(k)) open('lastroundkeys.log', 'w').write('\n'.join([l.hex() for l in lastroundkeys])) break if foundkey: p = 0 # null plaintext cint, _, _ = engine.doit(engine.goldendata, processinput(p, 16), lastroundkeys=[]) kr0 = phoenixAES.rewind(phoenixAES.int2bytes(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%s" % kr0.hex()) lastroundkeys.append(kr0) return lastroundkeys
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_file(tracefile, lastroundkeys, encrypt, outputbeforelastrounds and len(lastroundkeys)>0, verbose) if k: foundkey=True lastroundkeys.append(bytes.fromhex(k)) open('lastroundkeys.log', 'w').write('\n'.join([l.hex() for l in 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_file(tracefile, lastroundkeys, encrypt, outputbeforelastrounds and len(lastroundkeys)>0, verbose) if k: foundkey=True lastroundkeys.append(bytes.fromhex(k)) open('lastroundkeys.log', 'w').write('\n'.join([l.hex() for l in lastroundkeys])) break if foundkey: p=0 # null plaintext cint,_,_=engine.doit(engine.goldendata, processinput(p, 16), lastroundkeys=[]) kr0=phoenixAES.rewind(phoenixAES.int2bytes(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%s" % kr0.hex()) lastroundkeys.append(kr0) return lastroundkeys
#!/usr/bin/env python3 import phoenixAES phoenixAES.convert_r8faults_file("r8faults", "r9faults", encrypt=False) phoenixAES.crack_file("r9faults", encrypt=False)