-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchallenge12.py
More file actions
91 lines (77 loc) · 2.96 KB
/
Copy pathchallenge12.py
File metadata and controls
91 lines (77 loc) · 2.96 KB
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
import challenge6
import challenge7
import challenge8
import challenge9
import challenge11
import base64
SECRET_KEY = challenge11.gen_key()
SECRET_MSG = base64.b64decode(b'''
Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg
aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq
dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg
YnkK''')
def encryption_oracle_12(s):
if type(s) == str:
s = s.encode('utf-8')
msg = challenge9.pad_pkcs7(s + SECRET_MSG)
return challenge7.aes_ecb_encrypt(msg, SECRET_KEY)
def find_blocksize(enc_fct):
i = 0
pt = 'a' * i
ct = enc_fct(pt)
last_len = len(ct)
while last_len == len(ct):
i += 1
pt = 'a' * i
ct = enc_fct(pt)
return len(ct) - last_len
def find_mode(enc_fct, blocksize):
# A minimum of 3 identical blocks is required to have 2 aligned identical blocks
#0123456789abcdef 0123456789abcdef 0123456789abcdef 0123456789abcdef
#xxxxxxxxxxxxxxx0 123456789abcdef0 123456789abcdef0 123456789abcdefx
#
#0123456789abcdef 0123456789abcdef 0123456789abcdef 0123456789abcdef
#x0123456789abcde f0123456789abcde f0123456789abcde fxxxxxxxxxxxxxxx
pt = b'a' * blocksize * 3
ct = enc_fct(pt)
if challenge8.is_probably_ecb(ct):
return 'ecb'
else:
return 'cbc'
# First block with 1 byte off
# 0123456789abcdef 0123456789abcdef
# aaaaaaaaaaaaaaa0 123456789abcdef0
# Then, try all possible last byte until one match the first block with 1 byte off
# Second block
# 0123456789abcdef 0123456789abcdef 0123456789abcdef
# known_completely unknown..........................
#
# Use 1st block to bruteforce a character followed a block with 1 byte off to slide the whole message one byte off
# 0123456789abcdef 0123456789abcdef 0123456789abcdef 0123456789abcdef
# nown_completelyX aaaaaaaaaaaaaaak nown_completelyX unknown
def find_ecb_byte(enc_fct, known, blocksize):
i_block_searching = len(known) // blocksize
size_oneoff = blocksize - len(known) % blocksize - 1
oneoff_block = b'a' * size_oneoff
brute_block = known[-(blocksize - 1):]
brute_block = b'a' * ((blocksize - 1) - len(brute_block)) + brute_block
for i in range(256):
pt = brute_block + bytes([i]) + oneoff_block
ct = enc_fct(pt)
ct_blocks = challenge6.get_blocks(ct, blocksize)
if ct_blocks[0] == ct_blocks[i_block_searching + 1]:
return bytes([i])
def decrypt_ecb_enc_oracle_no_prefix():
blocksize = find_blocksize(encryption_oracle_12)
mode = find_mode(encryption_oracle_12, blocksize)
if mode =='ecb':
known = b''
new_c = find_ecb_byte(encryption_oracle_12, known, blocksize)
while new_c:
known += new_c
new_c = find_ecb_byte(encryption_oracle_12, known, blocksize)
return known
if __name__ == '__main__':
pt = challenge9.unpad_pkcs7(decrypt_ecb_enc_oracle_no_prefix())
assert pt == SECRET_MSG
print('Success !')