Automatycznie „brutalną siłą” kilka bajtów, aby odzyskać uszkodzony plik

35

Czy ktoś tam zna sposób na brutalne wartości siły przy określonym przesunięciu w pliku? To 4 kolejne bajty, które trzeba by brutalnie wymusić. Znam prawidłowy SHA-1 uszkodzonego pliku. Chciałbym więc porównać cały plik SHA-1 za każdym razem, gdy zmienia on wartość bajtu.

Znam dokładnie 4 bajty, które zostały zmienione, ponieważ plik został mi przekazany przez eksperta od odzyskiwania danych jako wyzwanie odzyskiwania. Dla tych, którzy są zainteresowani wiedzą, plik rar ma 4 bajty, które zostały celowo zmienione. Powiedziano mi przesunięcia zmienionych 4 bajtów i oryginalnego SHA-1. Osoba powiedziała, że ​​niemożliwe jest odzyskanie dokładnego pliku w archiwum po zmianie 4 bajtów. Nawet jeśli było to tylko kilka bajtów i dokładnie wiedziałeś, gdzie znajduje się uszkodzenie. Ponieważ nie ma rekordu odzyskiwania. Próbuję sprawdzić, czy istnieje sposób na prawidłowe wypełnienie tych 4 bajtów, aby plik rozpakował się bez błędów. Rozmiar pliku to około 5 MB.

Przykład :

Przesłałem zdjęcia, aby było wyraźniej określone, co dokładnie chcę zrobić. Wierzę, że ktoś może opublikować je tutaj dla mnie z większym przedstawicielem.

Zrzut ekranu Jeden

Zrzut ekranu Dwa

Przykładowe przesunięcie, na 0x78którym się skupiam, to miejsce, w którym pierwsze zdjęcie pokazuje wartość, ponieważ CA chcę, aby skrypt podniósł wartość o 1, aby stała się CBjak pokazano na drugim zdjęciu. Chcę, aby ciągle zwiększał wartość, 1a następnie porównywał cały plik SHA-1 za każdym razem. Wprowadzanie zmian tylko w tych 4 bajtach z określonym przesunięciem.

Spróbuje CAC5C58Aporównać SHA-1. Jeśli nie pasuje, to spróbuje. CBC5C58ANastępnie, gdy pierwsza wartość osiągnie FF, przejdzie do 00C6C58Ai tak dalej. Zasadniczo chciałbym, aby można było z niego przejść, 00000000-FFFFFFFFale także mieć możliwość wyboru, gdzie chcesz, aby zaczął i skończył. Wiem, że może to zająć trochę czasu, ale nadal chciałbym spróbować. Pamiętaj, że znam dokładne przesunięcie bajtów, które są uszkodzone. Potrzebuję tylko poprawnych wartości.

Jeśli wyszukujesz w Google: „Jak naprawić uszkodzony plik brutalną siłą”, istnieje osoba, która napisała program dla systemu Linux. Działa to jednak tylko z plikami dołączonymi do programu. Szukam sposobu na użycie tego samego procesu z moim plikiem.

Sbt19
źródło
3
Witamy w Super User! Zredagowałem twoje pytanie, aby usunąć prośbę o program, co byłoby nie na temat. Czy możesz edytować swoje pytanie, aby uwzględnić (niektóre) przykłady, które widziałeś? Dobrze, że przeprowadziłeś badania, ale pokazanie nam dokładnie, jakie badania byłyby pomocne :)
bertieb
20
czy mogę zapytać, jak skończyłeś z tym plikiem i skąd masz pewność, że są to tylko 4 uszkodzone bajty?
Edoardo,
1
Czy znasz format pliku? Jeśli to zrobisz, być może będziesz w stanie wypracować prawidłowe wartości lub ograniczyć zakresy, zamiast próbować je brutalnie wymusić. Ogólnie jednak sugeruję, aby każdy uszkodzony plik został zrzucony ze względów bezpieczeństwa.
StephenG,
11
@eddyce Naprawdę interesuje mnie druga część twojego pytania - dlaczego te 4 bajty?
Craig Otis,
2
Z ciekawości, w jaki sposób plik został uszkodzony? A skąd wiesz, że to były te cztery bajty?
JohnEye,

Odpowiedzi:

27

Oto mały program w języku Python, który robi to, co wydajesz się opisywać.

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

UnTylko krótko przetestowane; proszę ping mnie, jeśli znajdziesz literówki.

W baseOkreśla gdzie spróbuj zastosować cztery bajty, a długi ciąg '996873... jest reprezentacją hex oczekiwanego SHA1. Linia for seq in... określa bajty do wypróbowania; i oczywiście zastąp 'binaryfile'ścieżką do pliku, który chcesz spróbować odzyskać.

Możesz zastąpić dosłowną listę [[0xCA, 0xC5,... ]]czymś, co faktycznie zapętla wszystkie możliwe wartości, ale jest to po prostu symbol zastępczy dla czegoś bardziej przydatnego, ponieważ nie jestem pewien, co dokładnie tam chcesz.

Coś takiego for seq in itertools.product(range(256), repeat=4)):zapętli wszystkie możliwe wartości od 0 do 2 32 -1. (Musisz wtedy dodać import itertoolsu góry.) A może po prostu możesz dodać przesunięcie; zaktualizuj skrypt, aby zastąpił bieżący for seq innastępującym (tam, gdzie ponownie importmusi przejść przed programem głównym);

import struct

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

Odwróciłem kolejność bajtów, aby naturalnie zwiększała się z 0x8AC5C5CA do 0x8AC5C5CB, ale następnie następnym przyrostem będzie 0x8AC5C5CC itp. structMagią jest przekonwertowanie tego na sekwencję bajtów (musiałem to sprawdzić z https: // stackoverflow. com / a / 26920983/874188 ). Rozpocznie się to od 0x8AC5C5CA i przejdzie do 0xFFFFFFFF, następnie zawinie do 0x00000000 i wróci do 0x8AC5C5C9.

Jeśli masz wiele zakresów kandydatów, które chciałbyś sprawdzić w określonej kolejności, być może coś w tym rodzaju

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

ale musisz się upewnić, że pary (początek, koniec)rge obejmują całą przestrzeń między 0x00000000 a 0xFFFFFFFF, jeśli naprawdę chcesz to wszystko zbadać. (I znowu zauważ, że zakres zwiększa ostatni bajt i że seqstosuje bajty wartości w odwrotnej kolejności, zgodnie z podanymi wymaganiami).

Jeśli chciałbyś użyć dwóch różnych baseadresów, szybko przekraczasz granice tego, co jest możliwe w życiu z brutalną siłą; ale możesz na przykład podzielić 4-bajtową liczbę na dwie 2-bajtowe części i zastosować je przy różnych przesunięciach.

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:]
potrójny
źródło
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Journeyman Geek
4

Nie, nie, nie i jeszcze raz NIE!

Rzadko pojawia się odpowiedź, której się nie spodziewasz.

Kilka pytań do ciebie:

  • Czy to możliwe, że ekspert nie wie, że można brutalnie wymusić ciąg bajtów i iteracyjnie wypróbować SHA-1, aż się zbiegnie? Nie
  • Czy to możliwe, żeby o tym zapomniał? Nie
  • Czy to możliwe, że nie możesz tego zrobić na pliku RAR? Nie
  • Czy druga odpowiedź jest zła? absolutnie NIE

Więc co? ... czas.

Chodzi o to, że musisz zmienić tak mało bajtów ... tylko 4!

Co to znaczy? 256 4 czyli 256x256x256x256 możliwości, to naprawdę bardzo duża liczba.
Jeśli twój komputer był w stanie przetworzyć 1 operację na sekundę (podstawienie w pliku + sha1) ...
powinieneś poczekać ponad 136 lat , lub jeśli wolisz dłużej niż 49710 dni.

Masz szczęście, 5 MB wstępnie buforowany plik (już załadowany do pamięci RAM i pamięci podręcznej) prosi tylko o około 0,03 sekundy (min. 0,025 s) na starym komputerze. To skraca czas oczekiwania do 1242-1492 dni (coś więcej niż 3 lata).

Prawdą jest, BTW, że statystycznie powinieneś mieć pozytywną odpowiedź w połowie czasu . Niemniej jednak powinieneś poczekać, aż wypróbujesz wszystkie możliwości, aby upewnić się, że istnieje tylko 1 podstawienie, które da ci tę samą sumę kontrolną SHA-1 ...

Teraz, gdy NIEMOŻLIWE dźwięki brzmią jak „niemożliwe w WSPÓŁCZESNYM czasie”.


Jak postępować

Bardziej właściwa odpowiedź na twoje pytanie techniczne: kiedy mówisz o brutalnej sile, nie musi być koniecznie ślepa, brutalna siła.

  • W komentarzu w drugiej odpowiedzi stwierdzono tylko, że nie trzeba obliczać sumy kontrolnej sha1 dla części przed uszkodzeniem. Robisz za pierwszym razem i oszczędzasz czas na każdą kolejną iterację (może współczynnik 2 zależy od pozycji).

  • Coś, co może zmienić bezwartościowy wysiłek, to napisanie równoległego kodu, który będzie działał na GPU. Jeśli masz dobrą kartę graficzną, możesz mieć około 1000 rdzeni, które mogą obliczyć dla ciebie równolegle (nawet więcej, ale mają częstotliwość niższą niż procesor, ale wciąż są dużo). Jeśli jesteś w stanie skrócić czas z 1400 do 1,4 dnia, być może możesz to zrobić.

  • Inne podejście może doprowadzić do szybszego rozwiązania.
    Powiedziałeś, że to plik rar. Struktura pliku rar jest podzielona na bloki. Jeśli weźmiesz to pod uwagę, zobaczysz, gdzie spada korupcja. Jeśli jest to część danych, część nagłówków lub obie. Następnie możesz działać konsekwentnie. Dla uproszczenia załóżmy, że dotyczy to danych:
    możesz wykonać brutalną siłę swojego przesunięcia, sprawdzić dla każdego dodatniego CRC tego bloku, czy jest to dodatni SHA1 na całym pliku. Ponownie możesz zrobić kod równoległy.

Ostatnia uwaga

Jeśli miałyby one 6 bajtów zamiast 4, to nie grałeś z obecną technologią.

Hastur
źródło
Świetna odpowiedź - niekoniecznie trzeba by wyczerpać całą przestrzeń, ponieważ sam rar w tym przykładzie nie rozpakowałby się z powodu wewnętrznych kontroli, nawet gdyby sha1 działał ze zduplikowanym hashem. Trafienie 4 bajtów, które fałszywie rozwiązały sha1 ORAZ wewnętrzny crc, byłoby bardzo mało prawdopodobne.
rrauenza
@rrauenza Dzięki. BTW nie tylko (podwójna kontrola). Rzeczywiście, blok powinien być krótszy niż cała część od zepsutych bajtów do końca pliku, a CRC powinien być lżejszy do obliczenia niż algorytm sha1 ...
Hastur
@rrauenza Czy wiesz, jak bym zrobił, aby uruchomić rzeczywisty kod równoległy do ​​uruchomienia na GPU? Mam dobry procesor graficzny. Dzięki.
Sbt19
Nie ja nie. Możesz jednak użyć wielu procesorów, dzieląc przestrzeń wyszukiwania.
rrauenza
@ Sbt19 Cokolwiek powiedzieli na ten temat, Google nie jest tak przerażające w użyciu ;-). Wyszukaj (jeśli nvidia), Cuda, brute force, sha1a będziesz miał wiele podpowiedzi, np . Kod źródłowy . BTW utrzymać szczególnej uwagi, ponieważ przeglądanie od tej ścieżki google, och mój chłopcze, może doprowadzić Cię na jednym z boków ciemności siatki ... :-). (Nie na github ... na innej stronie, na której możesz spotkać się z tego rodzaju badaniami). PS> Istnieje wiele prac naukowych na pokrewne tematy, np. Ten ...
Hastur