Cryptopals zestaw 4 ćwiczenie 26

przez | 26 listopada 2020

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 .

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *