def discover_mac(message): guess_mac = b'\x00' * 20 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 9000)) for i in range(20): nextbyte = guess_byte(sock, message, i, guess_mac) guess_mac = setByte(guess_mac, i, nextbyte) print(rawToHex(guess_mac)) return guess_mac
def discover_mac(message): guess_mac = b'\x00' * 20; sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM); sock.connect(('127.0.0.1', 9000)) for i in range(20): nextbyte = guess_byte(sock, message, i, guess_mac); guess_mac = setByte(guess_mac, i, nextbyte); print (rawToHex(guess_mac)); return guess_mac;
def guess_byte(sock, message, index, guess_mac, numtrials=5): timings = [0]*256; # try each byte at the index for i in range(256): this_guess = setByte(guess_mac, index, i); url = b'test?file=' + message + b'&signature=' + rawToHex(this_guess) + b'\n'; start = time.perf_counter() for j in range(numtrials): sock.send(url); data = sock.recv(1024) stop = time.perf_counter() timings[i] = stop - start; # assume the largest timing is the right one value = timings.index(max(timings)); print("index: " + str(index) + " : value: " + hex(value)); return value;
def guess_byte(sock, message, index, guess_mac, numtrials=50): timings = [0]*256; # try each byte at the index for i in range(256): this_guess = setByte(guess_mac, index, i); url = b'test?file=' + message + b'&signature=' + rawToHex(this_guess) + b'\n'; start = time.perf_counter() for j in range(numtrials): sock.send(url); data = sock.recv(1024) stop = time.perf_counter() timings[i] = stop - start; # assume the largest timing is the right one value = timings.index(max(timings)); print("index: " + str(index) + " : value: " + hex(value)); return value;
def solve19(): # initial guess: Assume every plaintext char is a space. Guess the key that creates the most spaces guess = b"" for i in range(longestPlaintextLength): myDict = {} for j in range(256): myDict[chr(j)] = 0 for p in rawCiphers: try: myDict[chr(p[i] ^ 0x20)] += 1 except Exception: # out of range... pass guess += ord(max(myDict, key=lambda k: myDict[k])).to_bytes(1, byteorder="big") printSolution(guess, rawCiphers) # Notice that the first plain says "(ehav*o)". Guess that this should be "Behavior". guess = setByte(guess, 0, rawCiphers[0][0] ^ ord("B")) guess = setByte(guess, 1, rawCiphers[0][1] ^ ord("e")) guess = setByte(guess, 5, rawCiphers[0][5] ^ ord("i")) guess = setByte(guess, 7, rawCiphers[0][7] ^ ord("r")) printSolution(guess, rawCiphers) # Notice that the last plain starts with "Jeter~&}l- bea0ty" -- guess this should be "beauty" guess = setByte(guess, 13, rawCiphers[39][13] ^ ord("a")) guess = setByte(guess, 14, rawCiphers[39][14] ^ ord("u")) printSolution(guess, rawCiphers) # Plain (21) has "beau1i#ul" -- guess this should be beautiful guess = setByte(guess, 19, rawCiphers[21][19] ^ ord("t")) guess = setByte(guess, 21, rawCiphers[21][21] ^ ord("f")) guess = setByte(guess, 23, rawCiphers[21][23] ^ ord("l")) printSolution(guess, rawCiphers) # Plain 24 : b"J+d rc+z 'ur winged hors6." -- probably supposed to end in horse. guess = setByte(guess, 24, rawCiphers[24][24] ^ ord("e")) printSolution(guess, rawCiphers) # Plain 7 : b'[*litiore)ningless words,' -- should be " meaningless"? guess = setByte(guess, 9, rawCiphers[7][9] ^ ord("a")) guess = setByte(guess, 7, rawCiphers[7][7] ^ ord("m")) guess = setByte(guess, 6, rawCiphers[7][6] ^ 0x20) printSolution(guess, rawCiphers) # Plain 3 : b'N,ghtienth-century houses.' -- should start 'Eighteenth'? guess = setByte(guess, 0, rawCiphers[3][0] ^ ord("E")) guess = setByte(guess, 1, rawCiphers[3][1] ^ ord("i")) guess = setByte(guess, 5, rawCiphers[3][5] ^ ord("e")) printSolution(guess, rawCiphers) # a Google for "from counter or desk" took me to http://www.poetryfoundation.org/poem/172061 to fill in the rest: # (heh -- just noticed that my first guess ("Behavior") was completely wrong...) # Plain 37 : b'He, too, has been changed &ne 07 x46 ' shoudl be: He, too, has been changed in his turn, guess = setByte(guess, 8, rawCiphers[37][8] ^ ord(" ")) guess = setByte(guess, 26, rawCiphers[37][26] ^ ord("i")) guess = setByte(guess, 28, rawCiphers[37][28] ^ ord(" ")) guess = setByte(guess, 29, rawCiphers[37][29] ^ ord("h")) guess = setByte(guess, 30, rawCiphers[37][30] ^ ord("i")) guess = setByte(guess, 31, rawCiphers[37][31] ^ ord("s")) guess = setByte(guess, 32, rawCiphers[37][32] ^ ord(" ")) guess = setByte(guess, 33, rawCiphers[37][33] ^ ord("t")) guess = setByte(guess, 34, rawCiphers[37][34] ^ ord("u")) guess = setByte(guess, 35, rawCiphers[37][35] ^ ord("r")) guess = setByte(guess, 36, rawCiphers[37][36] ^ ord("n")) guess = setByte(guess, 37, rawCiphers[37][37] ^ ord(",")) printSolution(guess, rawCiphers)
def solve19(): # initial guess: Assume every plaintext char is a space. Guess the key that creates the most spaces guess = b'' for i in range(longestPlaintextLength): myDict = {} for j in range(256): myDict[chr(j)] = 0 for p in rawCiphers: try: myDict[chr(p[i] ^ 0x20)] += 1 except Exception: # out of range... pass guess += ord(max(myDict, key=lambda k: myDict[k])).to_bytes(1, byteorder='big') #printSolution(guess, rawCiphers); # Notice that the first plain says "(ehav*o)". Guess that this should be "Behavior". guess = setByte(guess, 0, rawCiphers[0][0] ^ ord('B')) guess = setByte(guess, 1, rawCiphers[0][1] ^ ord('e')) guess = setByte(guess, 5, rawCiphers[0][5] ^ ord('i')) guess = setByte(guess, 7, rawCiphers[0][7] ^ ord('r')) #printSolution(guess, rawCiphers); # Notice that the last plain starts with "Jeter~&}l- bea0ty" -- guess this should be "beauty" guess = setByte(guess, 13, rawCiphers[39][13] ^ ord('a')) guess = setByte(guess, 14, rawCiphers[39][14] ^ ord('u')) #printSolution(guess, rawCiphers); # Plain (21) has "beau1i#ul" -- guess this should be beautiful guess = setByte(guess, 19, rawCiphers[21][19] ^ ord('t')) guess = setByte(guess, 21, rawCiphers[21][21] ^ ord('f')) guess = setByte(guess, 23, rawCiphers[21][23] ^ ord('l')) #printSolution(guess, rawCiphers); # Plain 24 : b"J+d rc+z 'ur winged hors6." -- probably supposed to end in horse. guess = setByte(guess, 24, rawCiphers[24][24] ^ ord('e')) #printSolution(guess, rawCiphers); # Plain 7 : b'[*litiore)ningless words,' -- should be " meaningless"? guess = setByte(guess, 9, rawCiphers[7][9] ^ ord('a')) guess = setByte(guess, 7, rawCiphers[7][7] ^ ord('m')) guess = setByte(guess, 6, rawCiphers[7][6] ^ 0x20) #printSolution(guess, rawCiphers); # Plain 3 : b'N,ghtienth-century houses.' -- should start 'Eighteenth'? guess = setByte(guess, 0, rawCiphers[3][0] ^ ord('E')) guess = setByte(guess, 1, rawCiphers[3][1] ^ ord('i')) guess = setByte(guess, 5, rawCiphers[3][5] ^ ord('e')) #printSolution(guess, rawCiphers); # a Google for "from counter or desk" took me to http://www.poetryfoundation.org/poem/172061 to fill in the rest: # (heh -- just noticed that my first guess ("Behavior") was completely wrong...) # Plain 37 : b'He, too, has been changed &ne 07 x46 ' shoudl be: He, too, has been changed in his turn, guess = setByte(guess, 8, rawCiphers[37][8] ^ ord(' ')) guess = setByte(guess, 26, rawCiphers[37][26] ^ ord('i')) guess = setByte(guess, 28, rawCiphers[37][28] ^ ord(' ')) guess = setByte(guess, 29, rawCiphers[37][29] ^ ord('h')) guess = setByte(guess, 30, rawCiphers[37][30] ^ ord('i')) guess = setByte(guess, 31, rawCiphers[37][31] ^ ord('s')) guess = setByte(guess, 32, rawCiphers[37][32] ^ ord(' ')) guess = setByte(guess, 33, rawCiphers[37][33] ^ ord('t')) guess = setByte(guess, 34, rawCiphers[37][34] ^ ord('u')) guess = setByte(guess, 35, rawCiphers[37][35] ^ ord('r')) guess = setByte(guess, 36, rawCiphers[37][36] ^ ord('n')) guess = setByte(guess, 37, rawCiphers[37][37] ^ ord(',')) printSolution(guess, rawCiphers)