Tym razem bardzo proste ćwiczenie, pokazujące jedną ze słabości trybu CTR – podatność na przestawiania wartości bitów zaszyfrowanej wiadomości. Brzmi to banalnie, bo przecież atakujący nie dowie się dzięki temu jaka była treść zaszyfrowanej wiadomości, ale jak już przekonaliśmy się w ćwiczeniu 16 (https://koltys.info/blog/2020/08/06/cryptopals-zestaw-2-cwiczenie-16/) nie zawsze chodzi o to, żeby odkryć zawartość, czasami wystarczy ją odpowiednio zmodyfikować.
Sam atak przebiega identycznie jak w opisie wymienionego powyżej ćwiczenia, zmienia się sposób w jaki dane są szyfrowane. Naszym zadaniem jest przekonać się, że dane zaszyfrowane przy pomocy AES w trybie CTR są podatne na ataki typu „bitflipping”.
Kod nowej „wyroczni”:
class OracleCtrBitFlipping(object):
M_ENCRYPTION_KEY = b''
M_NONCE = b''
def __init__(self):
self.M_ENCRYPTION_KEY = generateRandomData(16)
self.M_NONCE = c_uint64(abs(randint(0, 0xffffffffffffffff)))
def encryptData(self, user_data):
user_data = user_data.replace(';', '')
user_data = user_data.replace('=', '')
plain_data = ("comment1=cooking%20MCs;userdata="+
user_data+
";comment2=%20like%20a%20pound%20of%20bacon")
plain_data = addPaddingPKCS7(bytearray(plain_data, 'ascii'), 16)
cipher = CustomAES()
return cipher.encode(plain_data, self.M_ENCRYPTION_KEY,
CustomAES.Mode.CTR, self.M_NONCE)
def isAdmin(self, ciphered_data):
result = False
cipher = CustomAES()
plain_data = cipher.decode(ciphered_data, self.M_ENCRYPTION_KEY,
CustomAES.Mode.CTR, self.M_NONCE)
print(plain_data)
if b";admin=true;" in plain_data:
result = True
return result
Rozwiązanie ćwiczenia:
def s4challenge26():
print("Challenge 26")
oracle = OracleCtrBitFlipping()
user_data = "aaaaaaaaaaaaaaaa"
user_data += ":admin<true:aaaa"
secret_data = bytearray(oracle.encryptData(user_data))
secret_data[48] = secret_data[48] ^ 0x1
secret_data[54] = secret_data[54] ^ 0x1
secret_data[59] = secret_data[59] ^ 0x1
print("IsAdmin: ", oracle.isAdmin(secret_data))
Nie będę wchodził w szczegóły ponieważ zostało to już opisane we wcześniejszym ćwiczeniu. Różnica jest taka, że tym razem zmieniamy wartości bajtów bezpośrednio, a w przypadku trybu CBC, modyfikowane były bajty z bloku poprzedzającego blok który miał zostać zmieniony.
Cały kod znajduje się na gitlabie: https://gitlab.com/akoltys/cryptopals .