'Forza bruta' automaticamente alcuni byte per recuperare un file corrotto


35

Qualcuno là fuori conosce un modo per forzare i valori della forza a un determinato offset in un file? Sono 4 byte consecutivi che dovrebbero essere forzati brutalmente. Conosco lo SHA-1 corretto del file corrotto. Quindi, quello che vorrei fare è confrontare il file completo SHA-1, ogni volta che cambia il valore del byte.

Conosco i 4 byte esatti che sono stati modificati, perché il file mi è stato dato da un esperto di recupero dati, come una sfida di recupero. Per coloro che sono interessati a saperlo, il file rar ha 4 byte che sono stati intenzionalmente modificati. Mi è stato detto degli offset dei 4 byte modificati e dello SHA-1 originale. La persona ha detto che è IMPOSSIBILE recuperare il file esatto nell'archivio dopo aver cambiato i 4 byte. Anche se c'erano solo pochi byte e sapevi esattamente dove si trovava la corruzione. Dal momento che non ha un record di recupero. Sto cercando di vedere se esiste un modo per riempire correttamente quei 4 byte in modo che il file si decomprima senza errori. La dimensione del file è di circa 5 MB.

Esempio :

Ho caricato foto in modo che sia più chiaramente definito esattamente quello che sto cercando di fare. Credo che qualcuno possa pubblicarli qui per me con più rappresentanti.

Screenshot One

Schermata due

L'offset di esempio su 0x78cui mi sto concentrando è dove la prima immagine mostra il valore mentre CA voglio che lo script prenda il valore di 1 in modo che diventi CBcome mostrato nella seconda immagine. Voglio che continui ad aumentare il valore di 1e quindi confrontare ogni volta l'intero file SHA-1. Apportando modifiche solo a quei 4 byte all'offset specificato.

Proverà a CAC5C58Aconfrontare SHA-1. Se non corrisponde, allora proverà. Quindi, CBC5C58Auna volta raggiunto il primo valore FF, andrà a 00C6C58Ae così via. Fondamentalmente, vorrei che potesse andare da, 00000000-FFFFFFFFma anche avere la possibilità di scegliere dove iniziare e finire. So che potrebbe volerci del tempo, ma vorrei ancora provarlo. Tieni presente che conosco l'esatto offset dei byte che sono corrotti. Ho solo bisogno dei valori corretti.

Se cerchi su Google: "Come riparare un file danneggiato con la forza bruta" C'è una persona che ha scritto un programma Linux. Tuttavia, funziona solo con i file inclusi con il programma. Sto cercando un modo per utilizzare lo stesso processo con il mio file.


3
Benvenuto in Super User! Ho modificato la tua domanda per rimuovere la richiesta di un programma, che sarebbe fuori tema. Puoi modificare la tua domanda per includere (alcuni) degli esempi che hai visto? È positivo che tu abbia fatto delle ricerche, ma mostrandoci esattamente quale ricerca sarebbe utile :)
bertieb,

20
potrei chiederti come hai finito con questo file e come puoi essere sicuro che questi sono gli unici 4 byte corrotti?
Edoardo,

1
Conosci il formato del file? Se lo fai potresti essere in grado di elaborare i valori corretti o limitare gli intervalli, invece di provare a forzarli. In generale, tuttavia, suggerirei di scaricare eventuali file danneggiati per motivi di sicurezza.
StephenG

11
@eddyce Sono davvero interessato alla seconda parte della tua domanda - perché quei 4 byte?
Craig Otis,

2
Per curiosità, come è stato corrotto il file? E come fai a sapere che erano quei quattro byte?
JohnEye,

Risposte:


27

Ecco un piccolo programma Python che fa ciò che sembra stia descrivendo.

#!/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')

unSolo brevemente testato; per favore, chiamami se trovi errori di battitura.

I basespecifica dove tentano di applicare i quattro byte, e la stringa lunga '996873... è la rappresentazione esadecimale del SHA1 previsto. La linea for seq in... definisce i byte da provare; e ovviamente sostituisci 'binaryfile'con il percorso del file che vuoi tentare di salvare.

Puoi sostituire la lista letterale [[0xCA, 0xC5,... ]]con qualcosa per passare in rassegna tutti i possibili valori, ma fondamentalmente è solo un segnaposto per qualcosa di più utile perché non sono davvero sicuro di cosa esattamente vuoi lì.

Qualcosa di simile for seq in itertools.product(range(256), repeat=4)):scorrerà su tutti i valori possibili da 0 a 2 32 -1. (Dovrai aggiungere import itertoolsvicino all'inizio in alto.) O forse potresti semplicemente aggiungere un offset; aggiorna lo script per sostituire quello attuale for seq incon il seguente (dove di nuovo importbisogna andare prima del programma principale);

import struct

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

Ho invertito l'ordine dei byte in modo che passi naturalmente da 0x8AC5C5CA a 0x8AC5C5CB, ma l'incremento successivo sarà 0x8AC5C5CC ecc. La structmagia è di convertirlo in una sequenza di byte (ho dovuto cercarlo da https: // stackoverflow. com / a / 26920983/874188 ). Questo inizierà a 0x8AC5C5CA e passerà a 0xFFFFFFFF, quindi tornerà a 0x00000000 e risalirà fino a 0x8AC5C5C9.

Se hai più intervalli candidati che desideri esaminare in un ordine particolare, forse qualcosa del genere

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

ma poi dovrai assicurarti che le coppie (inizio, fine)rge coprano tutto lo spazio tra 0x00000000 e 0xFFFFFFFF se vuoi davvero esaminarlo tutto. (E ancora, si noti che l'intervallo incrementa l' ultimo byte e che seqapplica i byte del valore al contrario, in conformità con i requisiti dichiarati.)

Se volevi usare due baseindirizzi diversi , ti imbatti rapidamente nei limiti di ciò che è possibile fare nella tua vita con forza bruta; ma potresti, ad esempio, dividere il numero di 4 byte in due parti di 2 byte e applicarle a offset diversi.

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:]

I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Journeyman Geek

4

No, no, no e ancora NO!

Di rado la risposta che ottieni non è quella che ti aspetti.

Alcune domande per te:

  • È possibile che un esperto non sappia che è possibile forzare una stringa di for byte e provare iterativamente lo SHA-1 fino a quando non converge? No
  • È possibile che lo dimentichi? No
  • È possibile che non sia possibile farlo su un file rar? No
  • È l'altra risposta sbagliata? assolutamente NO

E allora? ... Tempo.

Il punto è che devi cambiare così pochi byte ... solo 4!

Cosa significa? 256 4 che è 256x256x256x256 possibilità, un numero davvero grande.
Se il tuo computer è stato in grado di elaborare 1 operazione al secondo (sostituzione nel file + sha1) ...
dovresti attendere più di 136 anni o se preferisci più di 49710 giorni.

Sei abbastanza fortunato, un file pre-memorizzato nella cache da 5 MB (già caricato in RAM e nella cache) richiede solo circa 0,03 secondi (minimo 0,025 secondi), su un vecchio computer. Ciò riduce il tempo previsto a 1242-1492 giorni (qualcosa in più di 3 anni).

È vero, a proposito, statisticamente dovresti avere una risposta positiva nella metà del tempo . Tuttavia dovresti aspettare fino a quando avrai provato tutte le possibilità per essere sicuro che ci sia solo 1 sostituzione che ti darà lo stesso checksum SHA-1 ...

Ora che IMPOSSIBILE suona come "impossibile in un lasso di tempo WORTHWHILE ".


Come procedere

Una risposta più adeguata alla tua domanda tecnica: quando parli di forza bruta non deve essere necessaria la forza bruta cieca.

  • È appena stato dichiarato in un commento nell'altra risposta che non è necessario calcolare il checksum sha1 sulla parte prima della corruzione. Fai la prima volta e risparmi tempo per ogni iterazione successiva (forse un fattore 2 dipende dalla posizione).

  • Qualcosa che può cambiare l'inutile sforzo è scrivere un codice parallelo che verrà eseguito sulla GPU. Se hai una buona scheda grafica potresti avere circa 1000 core che possono essere calcolati per te in parallelo (anche di più ma hanno una frequenza inferiore alla CPU, ma sono ancora molti). Se sei in grado di ridurre il tempo da 1400 a 1,4 giorni, forse puoi anche farlo.

  • Un approccio diverso può portare a una soluzione più rapida.
    Hai detto che è un file rar. La struttura dei file rar è divisa in blocchi. Se ne prendi conto, puoi vedere dove cade la corruzione. Se è da parte dei dati, da parte delle intestazioni o da entrambi. Quindi puoi agire di conseguenza. Per semplicità supponiamo che sia sui dati:
    puoi fare la forza bruta del tuo offset, controllare per ogni CRC positivo di quel blocco se è anche positivo lo SHA1 sull'intero file. Ancora una volta puoi fare un codice parallelo.

Nota finale

Se fossero 6 byte anziché 4, eri fuori gioco con la tecnologia attuale.


Ottima risposta: non sarebbe necessariamente necessario esaurire l'intero spazio, perché la rar stessa in questo esempio non si decomprimerebbe a causa di controlli interni anche se sha1 funzionava con un hash duplicato. Colpire 4 byte che hanno risolto falsamente sha1 E un crc interno in modo errato sarebbe molto improbabile.
rrauenza,

@rrauenza Grazie. A proposito non solo (il doppio controllo). In effetti il ​​blocco dovrebbe essere più corto dell'intera parte dai byte corrotti alla fine del file, e il CRC dovrebbe essere più leggero per calcolare l'algoritmo sha1 ...
Hastur

@rrauenza Sai come farei per ottenere il codice parallelo effettivo da eseguire sulla GPU? Ho una buona GPU. Grazie.
Sbt19,

No, io no. Tuttavia, è possibile utilizzare più cpus partizionando lo spazio di ricerca.
rrauenza,

@ Sbt19 Qualunque cosa ti abbiano detto su di esso, google non è così spaventoso da usare ;-). Cerca (se nvidia) Cuda, brute force, sha1e avrai molti suggerimenti, ad esempio il codice sorgente . Mantenere BTW vostra attenzione alta perché la navigazione da quel percorso google, oh mio ragazzo, può portare su uno dei lati oscuri della rete ... :-). (Non su github ... in altri siti che puoi incontrare con questo tipo di ricerche). PS> Ci sono molti articoli scientifici su argomenti correlati, ad esempio questo ...
Hastur,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.