web-dev-qa-db-fra.com

Automatiquement 'force brute' quelques octets pour récupérer un fichier corrompu

Est-ce que quelqu'un connaît un moyen de forcer les valeurs de force à un décalage particulier dans un fichier? C'est 4 octets consécutifs qu'il faudrait forcer brutalement. Je connais le bon SHA-1 du fichier corrompu. Donc, ce que je voudrais faire, c'est comparer le fichier complet SHA-1, chaque fois qu'il change la valeur d'octet.

Je connais les 4 octets exacts qui ont été modifiés, car le fichier m'a été transmis par un expert en récupération de données, à titre de défi de récupération. Pour ceux que cela intéresse, le fichier rar contient 4 octets qui ont été intentionnellement modifiés. On m'a dit les décalages des 4 octets modifiés et du SHA-1 d'origine. La personne a déclaré qu'il était IMPOSSIBLE de récupérer le fichier exact dans l'archive une fois les 4 octets modifiés. Même s'il ne s'agissait que de quelques octets et que vous saviez exactement où se trouvait la corruption. Puisqu'il n'a pas d'enregistrement de récupération. J'essaie de voir s'il est possible de remplir correctement ces 4 octets afin que le fichier soit décompressé sans erreur. La taille du fichier est d'environ 5Mo.

Exemple :

J'ai mis des photos en ligne afin de définir plus clairement ce que je cherche à faire. Je crois que quelqu'un peut les poster ici pour moi avec plus de représentant.

 Screenshot One

 Screenshot Two

L'exemple par défaut sur lequel je me concentre est 0x78, où la première image montre la valeur sous la forme CA. Je souhaite que le script prenne la valeur 1 de manière à ce qu'il devienne CB, comme indiqué dans la deuxième image. Je veux qu'il continue à augmenter la valeur de 1 et ensuite compare le fichier entier SHA-1 à chaque fois. N'apporter que des modifications à ces 4 octets à l'offset spécifié.

Il va essayer CAC5C58A et comparer le SHA-1. Si ne correspond pas, il essaiera CBC5C58A. Ensuite, une fois que la première valeur atteindra FF, il passera à 00C6C58A et ainsi de suite. En gros, je voudrais qu’il puisse passer de 00000000-FFFFFFFF mais aussi avoir la possibilité de choisir où vous voulez commencer et se terminer. Je sais que cela pourrait prendre du temps, mais j'aimerais quand même l'essayer. N'oubliez pas que je connais le décalage exact des octets corrompus. J'ai juste besoin des bonnes valeurs.

Si vous recherchez sur Google: "Comment réparer un fichier corrompu par la force brutale" Il y a une personne qui a écrit un programme Linux. Cependant, cela ne fonctionne que sur les fichiers inclus avec le programme. Je cherche un moyen d'utiliser le même processus avec mon dossier.

34
Sbt19

Voici un petit programme Python qui fait ce que vous semblez décrire.

#!/usr/bin/env python3
from hashlib import sha1

with open('binaryfile', 'rb') as bin:
    binary = bin.read()

base = 0x0078
# ... is not valid Python; add more sequences, or take it out (or see below)
for seq in [[0xCA, 0xC5, 0xC5, 0x8A], [0xCB, 0xC5, 0xC5, 0x8A], ...]:
    copy = binary[0:base]
    copy += bytes(seq)
    copy += binary[base+len(seq):]
    if sha1(copy).hexdigest() == '9968733ce3ff0893bbb0a19e75faaf2fb0000e19':
        print('success with bytes {0}'.format(seq))
        break
else:
    print('no success')

ONU Seulement brièvement testé; S'il vous plaît me cingler si vous trouvez des fautes de frappe.

basespécifie où essayer d'appliquer les quatre octets, et la chaîne longue '996873... est la représentation hexadécimale de la valeur SHA1 attendue. La ligne for seq in... définit les octets à essayer; et bien sûr, remplacez 'binaryfile' par le chemin du fichier que vous voulez tenter de récupérer.

Vous pouvez remplacer la liste littérale [[0xCA, 0xC5,...]] par quelque chose à lire en boucle sur toutes les valeurs possibles, mais il s'agit simplement d'un espace réservé pour quelque chose de plus utile, car je ne suis pas vraiment sûr de ce que vous voulez exactement.

Quelque chose comme for seq in itertools.product(range(256), repeat=4)): fera une boucle sur toutes les valeurs possibles de 0 à 232-1. (Vous devrez alors ajouter import itertools près du sommet.) Ou peut-être pourriez-vous simplement ajouter un décalage; mettre à jour le script pour remplacer le for seq in actuel par le suivant (où encore une fois le importdoit précéder le programme principal);

import struct

for n in range(2**32):
    val=(n+0x8AC5C5CA) % 2**32  # notice reverse order
    seq=list(reversed(struct.pack(">I", val)))
    copy = ...

J'ai inversé l'ordre des octets pour qu'il passe naturellement de 0x8AC5C5CA à 0x8AC5C5CB, mais l'incrément suivant sera 0x8AC5C5CC, etc. La magie structconsiste à convertir ceci en une suite d'octets (il fallait le rechercher à partir de https://stackoverflow.com/a/26920983/874188 ). Cela commencera à 0x8AC5C5CA et ira à 0xFFFFFFFF, puis enroulera autour de 0x00000000 et remontera à 0x8AC5C5C9.

Si vous souhaitez examiner plusieurs catégories de candidats dans un ordre particulier, par exemple:

for rge in [(0x8AC5C5CA, 0x8AFFFFFF), (0x00C6C58A, 0x00FFFFFF),
        (0x00000000, 0x00C6C589), (0x01000000, 0x8AC5C5C9)]:
    for val in range(*rge):
        seq=list(reversed(struct.pack(">I", val)))
        copy = ...

mais ensuite vous devrez vous assurer que les (début, fin) des paires dans rgecouvrent tout l'espace entre 0x00000000 et 0xFFFFFFFF si vous voulez vraiment les examiner. (Et encore une fois, notez que la plage incrémente le last octet et que seqapplique les octets de la valeur en sens inverse, conformément à vos exigences.)

Si vous souhaitez utiliser deux adresses basedifférentes, vous vous heurtez rapidement aux limites de ce que vous pouvez faire de votre vie avec la force brute; mais vous pouvez, par exemple, scinder le nombre de 4 octets en deux parties de 2 octets et les appliquer à différents décalages.

base1 = 0x1234
base2 = 0x2345

for seq in range(whatever):
    copy = binary[0:base1]
    copy += bytes(seq[0:1])
    copy += binary[base1+2:base1+base2]
    copy += bytes(seq[2:3])
    copy += binary[base2+2:]
27
tripleee

Non, non, encore et encore NON!

Rarement la réponse que vous obtenez n'est pas ce que vous attendez.

Quelques questions pour vous:

  • Est-il possible qu'un expertne sache pas qu'il est possible de forcer brutalement une chaîne de octets et d'essayer de manière itérative le SHA-1 jusqu'à ce qu'il converge? Non
  • Est-il possible qu'il l'oublie? Non
  • Est-il possible que vous ne puissiez pas le faire sur un fichier rar? Non
  • Est-ce que l'autre réponse mal? absolument NON

Alors quoi? ... Temps.

Le fait est que vous devez changer si peu d'octets ... seulement 4!

Qu'est-ce que ça veut dire? 2564 c’est 256x256x256x256 possibilités, un très grand nombre.
Si votre ordinateur était capable de traiter 1 opération par seconde (substitution dans le fichier + sha1) ...
vous devez attendre plus de 136 ans ou, si vous préférez, plus de 49 710 jours.

Vous avez assez de chance, un fichier pré-mis en cache de 5 Mo (déjà chargé dans le ram et dans le cache) ne demande qu'environ 0,03 seconde (min 0,025 s), sur un ancien ordinateur. Cela réduit votre temps d'attente à 1242-1492 jours (quelque chose de plus de 3 ans).

Il est vrai, BTW, que statistiquement, vous devriez avoir une réponse positive deux fois plus vite. Néanmoins, vous devriez attendre jusqu'à ce que vous ayez essayé toutes les possibilités pour être sûr qu'il n'y a qu'une seule substitution qui vous donnera la même somme de contrôle SHA-1 ...

Maintenant que IMPOSSIBLEsonne comme "pas possible dans un VALABLE VAUTquantité de temps".


La façon de procéder

Une réponse plus appropriée à votre question technique: lorsque vous parlez de force brute, il ne doit pas nécessairement s'agir d'une force aveugle.

  • Dans une autre réponse, il est simplement indiqué dans un commentaire que vous n'avez pas besoin de calculer la somme de contrôle sha1 de la partie avant la corruption. Vous faites la première fois et vous gagnez du temps pour chaque itération successive (peut-être un facteur 2, cela dépend de la position).

  • Une chose qui peut changer l’effort inutile est d’écrire un code parallèle qui fonctionnera sur le GPU. Si vous avez une bonne carte graphique, vous pouvez avoir environ 1 000 cœurs capables de calculer en parallèle pour vous (encore plus, mais leur fréquence est inférieure à celle du processeur, mais ils sont quand même beaucoup). Si vous êtes en mesure de réduire le temps passé de 1400 à 1,4 jours, vous pourrez peut-être même le faire.

  • Une approche différente peut vous conduire à une solution plus rapide.
    Vous avez dit que c'était un fichier rar. La structure de fichier rar est divisée en blocs. Si vous en tenez compte, vous pouvez voir où se situe la corruption. S'il s'agit de la partie des données, des en-têtes ou des deux. Ensuite, vous pouvez agir en conséquence. Par souci de simplicité, supposons que ce soit sur les données:
    vous pouvez faire la force brute de votre décalage, vérifiez pour chaque CRC positif de ce bloc s'il est même positif le SHA1 sur l'ensemble du fichier. Encore une fois, vous pouvez créer un code parallèle.

Note finale

S'ils étaient 6 octets au lieu de 4, vous étiez hors du jeu avec la technologie actuelle.

4
Hastur