def trouver_dernier_octet(login, IV, r, Y_n_before, Y_n): """ Fonction permettant de trouver le dernier octet de X_n, en fonction des blocs Y_n-1 et Y_n. Renverra l'octet trouvé, ainsi que son état intermédiaire (dans un tuple) login : login de l'utilisateur IV : vecteur d'initialisation, donné par le serveur lors de la demande avec SEED r : l'objet Block aléatoire permettant l'attaque Y_n_before : bloc Y_n-1 Y_n : bloc Y_n """ #Création de l'oracle oracle = Oracle(BASE_URL, ORACLE_URL, login, SEED) i = 0 while True: h = "0x{:02x}".format(i) r[15] = int(h, 16) if debug: print("i : {0} ; r : {1}".format(h, r.hex() + Y_n.hex())) reponse = oracle.demande_informations(r.hex() + Y_n.hex(), IV.hex()) if reponse['status'] != 'invalid padding': print("VALIDE : " + reponse['status'] + " - " + str(i)) break i = i+1 #L'octet intermédiaire est i ^ 01 byte_IS = i ^ 1 #Le dernier octet de X_n est donc byte_IS ^ Y_n[len(Y_n)-1] last_byte = byte_IS ^ Y_n_before[15] last_byte = hex(last_byte) #Récupération des deux derniers hexa -> un octet last_byte = last_byte[2:] #Vérification - si la longueur vaut 1, dans ce cas on concatène 0 avec le dernier octet if len(last_byte) == 1: last_byte = "0"+last_byte #Destruction de l'oracle del oracle return (byte_IS, last_byte)
def trouver_bloc(login, bytes_IS_block, IV, r, Y_n_before, Y_n, last_byte, nb_block): """ Fonction permettant de trouver le dernier bloc X_n du message à déchiffrer. Renverra le bloc contenant tous les octets trouvés. login : login de l'utilisateur bytes_IS_block : objet Block qui contenant absolument tous les états intermédiaires calculés (pour évaluation padding) IV : vecteur d'initialisation, donné par le serveur lors de la demande avec SEED r : l'objet Block aléatoire permettant l'attaque Y_n_before : bloc Y_n-1 Y_n : bloc Y_n last_byte : dernier octet trouvé du bloc sur lequel on effectue l'attaque """ #Création de l'oracle oracle = Oracle(BASE_URL, ORACLE_URL, login, SEED) #Bloc d'octets - initialisé à last_byte bloc = last_byte #i sert à chercher l'octet en question i = 0 #j sert à changer de position dans le block (on décrémente) j = 14 #Boucle permettant de calculer le bloc entier concerné while True: #Calcul de h en hexadécimal h = "0x{:02x}".format(i) #Transformation de r[j] via h entier (hexa) r[j] = int(h, 16) if debug: print("i : {0} ; r : {1}".format(h, r.hex() + Y_n.hex())) reponse = oracle.demande_informations(r.hex() + Y_n.hex(), IV.hex()) #Si la réponse renvoyée par le serveur n'est pas invalide, le padding est bon! if reponse['status'] == 'invalid padding': i = i+1 else: if debug: print("VALIDE : {0} - i={1}".format(reponse['status'],str(i))) #L'octet de l'état intermédiaire est calculé bytes_IS_block[j] = i ^ (16 - j) #On le xor avec le bloc précédent à l'état j+1 byte = bytes_IS_block[j] ^ Y_n_before[j] byte = hex(byte) byte = byte[2:] if len(byte) == 1: byte = "0"+byte print("L'octet {0} de X_n est {1}".format(j, byte)) #envoie_octet_intermediaire(login, (nb_block * 16 + (16 - j)), byte) bloc = "{0}{1}".format(byte, bloc) #L'état intermédiaire est modifié de façon à calculer le nouvel octet à la position donnée for k in range (j, 16): r[k] = bytes_IS_block[k] ^ (16 - (j - 1)) #On décrémente j -> passage vers une position moindre j = j-1 #Réinitialisation de i, permettant de commencer l'attaque à 0 i=0 #Si la position de l'octet est inférieure à 0, on stoppe! if j<0: break #Destruction de l'oracle del oracle return bloc