Last active
September 26, 2019 03:59
-
-
Save extremecoders-re/1241a0d46ddb2cf9cc4cdb6265587840 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
from z3 import * | |
# Eight byte nonce conactenated with 8 null bytes | |
# Obtained from sector 54 | |
nonce = [0xB0, 0x99, 0x9B, 0x9E, 0xE4, 0xEE, 0x74, 0xC2, 0, 0, 0, 0, 0, 0, 0, 0] | |
# Verification bytes xored with 0x37 | |
# Obtained from sector 55 | |
# Expanding the key must produce this keystream | |
targetkeystream = [ | |
0xC9, 0xF0, 0x00, 0x00, 0x3E, 0xD0, 0x00, 0x00, 0x58, 0xC5, 0x00, 0x00, 0x54, 0x03, 0x00, 0x00, | |
0x88, 0xC0, 0x00, 0x00, 0xDC, 0xC8, 0x00, 0x00, 0xE0, 0x71, 0x00, 0x00, 0xC8, 0x85, 0x00, 0x00, | |
0x00, 0x04, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x65, 0x5A, 0x00, 0x00, 0xCA, 0xAD, 0x00, 0x00, | |
0x36, 0xC6, 0x00, 0x00, 0x8E, 0x33, 0x00, 0x00, 0x56, 0x85, 0x00, 0x00, 0xE8, 0xCA, 0x00, 0x00 ] | |
def rotl(value, shift): | |
return (value << shift) | LShR(value, 32-shift) | |
def quarterround(y0, y1, y2, y3): | |
y1 = y1 ^ rotl(y0 + y3, 7); | |
y2 = y2 ^ rotl(y1 + y0, 9); | |
y3 = y3 ^ rotl(y2 + y1, 13); | |
y0 = y0 ^ rotl(y3 + y2, 18); | |
return y0, y1, y2, y3 | |
def rowround(y): | |
y[0], y[1], y[2], y[3] = quarterround(y[0], y[1], y[2], y[3]) | |
y[5], y[6], y[7], y[4] = quarterround(y[5], y[6], y[7], y[4]) | |
y[10], y[11], y[8], y[9] = quarterround(y[10], y[11], y[8], y[9]) | |
y[15], y[12], y[13], y[14] = quarterround(y[15], y[12], y[13], y[14]) | |
return y | |
def columnround(x): | |
x[0], x[4], x[8], x[12] = quarterround(x[0], x[4], x[8], x[12]) | |
x[5], x[9], x[13], x[1] = quarterround(x[5], x[9], x[13], x[1]) | |
x[10], x[14], x[2], x[6] = quarterround(x[10], x[14], x[2], x[6]) | |
x[15], x[3], x[7], x[11] = quarterround(x[15], x[3], x[7], x[11]) | |
return x | |
def doubleround(x): | |
x = columnround(x) | |
x = rowround(x) | |
return x | |
def littleendian(b0, b1): | |
return b1, b0 | |
def rev_littleendian(b, w, i): | |
b[i + 0] = Extract(7, 0, w) | |
b[i + 1] = Extract(15, 8, w) | |
b[i + 2] = BitVecVal(0, 8) | |
b[i + 3] = BitVecVal(0, 8) | |
return b | |
def hash(seq): | |
x = [BitVec('x_%d' %i, 16) for i in range(16)] | |
z = [BitVec('z_%d' %i, 16) for i in range(16)] | |
for i in range(16): | |
b0, b1 = littleendian(seq[4*i], seq[4*i + 1]) | |
x[i] = z[i] = Concat(BitVecVal(0, 8), b1) + Concat(b0, BitVecVal(0, 8)) | |
for i in range(10): | |
z = doubleround(z) | |
for i in range(16): | |
z[i] += x[i] | |
seq = rev_littleendian(seq, z[i], 4*i) | |
return seq | |
def expand32(k, n, keystream): | |
o = [ | |
[ 'e', 'x', 'p', 'a' ], | |
[ 'n', 'd', ' ', '3' ], | |
[ '2', '-', 'b', 'y' ], | |
[ 't', 'e', ' ', 'k' ] | |
] | |
for i in range(0, 64, 20): | |
for j in range(4): | |
keystream[i+j] = BitVecVal(ord(o[i / 20][j]), 8) | |
for i in range(16): | |
keystream[4+i] = k[i] | |
keystream[44+i] = k[i+16] | |
keystream[24+i] = n[i] | |
keystream = hash(keystream) | |
return k, n, keystream | |
def main(): | |
global nonce, targetkeystream | |
n = [BitVecVal(i, 8) for i in nonce] | |
keystream = [0] * 64 | |
key, bvlist = [], [] | |
for i in range(16): | |
bv = BitVec('k_%d' %i, 8) | |
bvlist.append(bv) | |
key.append(bv+122) | |
key.append(bv*2) | |
key, n, keystream = expand32(key, n, keystream) | |
s = Solver() | |
for i in range(len(targetkeystream)): | |
s.add(keystream[i] == targetkeystream[i]) | |
if s.check() == sat: | |
print 'Key Found:', | |
m = s.model() | |
keystring = reduce(lambda acc, x: acc + '1' if m[x] == None else acc + chr(m[x].as_long()), bvlist, '') | |
print keystring | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment