/
oracle.py
97 lines (78 loc) · 2.82 KB
/
oracle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import urllib2
import sys
def query(q):
target = 'http://crypto-class.appspot.com/po?er=' + urllib2.quote(q) # Create query URL
req = urllib2.Request(target) # Send HTTP request to server
try:
f = urllib2.urlopen(req) # Wait for response
except urllib2.HTTPError, e:
if e.code == 404:
return True # good padding
return False # bad padding
ct = 'f20bdba6ff29eed7b046d1df9fb7000058b1ffb4210a580f748b4ac714c001bd4a61044426fb515dad3f21f18aa577c0bdf302936266926ff37dbf7035d5eeb4'
def int2hex(i):
return hex(i)[2:] if len(hex(i)[2:]) == 2 else '0' + hex(i)[2:]
def exor_pad(i):
assert(i > 0)
assert(i<=16)
return '00' * (16 -i) + int2hex(i) * i
def exor_g(g,pos):
assert(pos>=0)
assert(pos<16)
return '00' * (15-pos) + int2hex(g) + '00' * pos
def rellenar_zero(s):
return '0' * (32 - len(s)) + s
def strxor(a, b): # xor two strings of different lengths
if len(a) > len(b):
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
else:
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])
def hexexor(s1,s2):
return strxor(s1.decode("hex"),s2.decode("hex")).encode("hex")
blocks = ()
while ct:
blocks = blocks + (ct[:32],)
ct = ct[32:]
mensaje = ()
probable_range = [ord(' '),] + range(ord('a'),ord('z')) + range(ord('A'),ord('Z')) + range(17)
for b in range(1,len(blocks)):
iv = blocks[b-1]
block = blocks[b]
msg = ""
for pos in range(1,17):
pad = exor_pad(pos)
lastmsg = rellenar_zero(msg.encode("hex"))
getletter = 0
for g in probable_range:
gpad = exor_g(g,pos-1)
print "probando " + int2hex(g)
if query("".join(blocks[:(b-1)]) + hexexor(lastmsg,hexexor(iv,hexexor(gpad,pad))) + block):
getletter = 1
break
if getletter:
msg = int2hex(g).decode("hex") + msg
else:
msg = '?' + msg
print "mensaje='" + msg + "'"
mensaje = mensaje + (msg,)
print "Mensaje bloque " + str(b) + ":" + mensaje[b-1]
iv = blocks[2]
block = blocks[3]
msg = '09'.decode("hex") * 9
for pos in range(10,17):
pad = exor_pad(pos)
lastmsg = rellenar_zero(msg.encode("hex"))
getletter = 0
for g in probable_range:
gpad = exor_g(g,pos-1)
print "probando " + int2hex(g)
if query("".join(blocks[:(b-1)]) + hexexor(lastmsg,hexexor(iv,hexexor(gpad,pad))) + block):
getletter = 1
break
if getletter:
msg = int2hex(g).decode("hex") + msg
else:
msg = '?' + msg
print "mensaje='" + msg + "'"
mensaje = mensaje + (msg,)
print "Mensaje bloque " + str(b) + ":" + mensaje[b-1]