Автоматически «перебор» нескольких байт для восстановления поврежденного файла

35

Кто-нибудь знает способ подбора значений силы при определенном смещении в файле? Это 4 последовательных байта, которые должны быть грубо форсированы. Я знаю правильный SHA-1 поврежденного файла. Итак, я хотел бы сравнить полный файл SHA-1, каждый раз, когда он меняет значение байта.

Я знаю точные 4 байта, которые были изменены, потому что файл был предоставлен мне экспертом по восстановлению данных, как задача восстановления. Для тех, кто интересуется знанием, файл rar имеет 4 байта, которые были намеренно изменены. Мне сказали смещения измененных 4 байтов и оригинального SHA-1. Человек сказал, что невозможно восстановить точный файл в архиве после того, как 4 байта были изменены. Даже если бы было всего несколько байтов, и вы точно знали, где была обнаружена коррупция. Так как у него нет записи восстановления. Я пытаюсь увидеть, есть ли способ для правильного заполнения этих 4 байтов, чтобы файл распаковывался без ошибок. Размер файла составляет около 5 МБ.

Пример :

Я загрузил фотографии, чтобы они более четко определяли, что именно я хочу сделать. Я считаю, что кто-то может опубликовать их здесь для меня с большим количеством представителей.

Скриншот первый

Скриншот два

Пример смещения, на котором я сосредоточился, - это то, 0x78где на первом рисунке показано значение, так как CA я хочу, чтобы скрипт принял значение на 1, чтобы оно стало таким, CBкак показано на втором рисунке. Я хочу, чтобы он продолжал увеличивать значение, 1а затем сравнивать весь файл SHA-1 каждый раз. Вносить изменения только в эти 4 байта с указанным смещением.

Он попробует CAC5C58Aсравнить SHA-1. Если не совпадает, то он будет пытаться. CBC5C58AЗатем, как только первое значение достигнет FFего, затем перейдет к 00C6C58Aи так далее. В принципе, я бы хотел, чтобы он мог идти, 00000000-FFFFFFFFно также имел возможность выбрать, где вы хотите, чтобы он начинался и заканчивался. Я знаю, что это может занять некоторое время, но я все еще хотел бы попробовать это. Имейте в виду, я знаю точное смещение байтов, которые повреждены. Мне просто нужны правильные значения.

Если вы ищете в Google: «Как исправить поврежденный файл с помощью грубой силы», то есть человек, который написал программу для Linux. Тем не менее, он работает только против файлов, включенных в программу. Я ищу способ использовать тот же процесс с моим файлом.

Sbt19
источник
3
Добро пожаловать в Супер пользователя! Я отредактировал ваш вопрос, чтобы удалить запрос на программу, которая была бы не по теме. Можете ли вы отредактировать свой вопрос, чтобы включить (некоторые из) примеров, которые вы видели? Это хорошо, что вы провели исследование, но показали нам, какое именно исследование было бы полезно :)
bertieb
20
Могу ли я спросить, как вы получили этот файл и как вы можете быть уверены, что это только 4 поврежденных байта?
Эдоардо
1
Знаете ли вы формат файла? Если вы это сделаете, вы сможете выработать правильные значения или ограничить диапазоны, вместо того, чтобы пытаться их перебором. В целом, однако, я бы посоветовал сбросить любой поврежденный файл по соображениям безопасности.
StephenG
11
@eddyce Мне действительно интересна вторая часть вашего вопроса - почему эти 4 байта?
Крейг Отис,
2
Из любопытства, как файл был поврежден? И откуда ты знаешь, что это были те четыре байта?
JohnEye

Ответы:

27

Вот небольшая программа на Python, которая делает то, что вы, кажется, описываете.

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

ООНТолько кратко проверено; пожалуйста, пингуйте меня, если найдете опечатки.

В baseуказует , где , чтобы попытаться применить четыре байта, и длинная строку '996873... шестнадцатеричное представление ожидаемого SHA1. Строка for seq in... определяет байты, которые нужно попробовать; и, конечно, замените 'binaryfile'путь к файлу, который вы хотите попытаться спасти.

Вы можете заменить буквальный список [[0xCA, 0xC5,... ]]чем-то, что фактически зацикливает все возможные значения, но в основном это просто заполнитель для чего-то более полезного, потому что я не совсем уверен, чего именно вы там хотите.

Нечто подобное for seq in itertools.product(range(256), repeat=4)):зациклит все возможные значения от 0 до 2 32 -1. (Вам нужно будет добавить import itertoolsоколо вершины.) Или, возможно, вы могли бы просто добавить смещение; обновите скрипт, чтобы заменить текущий for seq inна следующий (где снова importнужно идти перед основной программой);

import struct

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

Я изменил порядок байтов , так что он , естественно , с шагом от 0x8AC5C5CA к 0x8AC5C5CB , но тогда следующий прирост будет 0x8AC5C5CC и т.д. structмагия преобразовать это последовательность байтов (пришлось искать его с https: // StackOverflow. com / a / 26920983/874188 ). Это начнется с 0x8AC5C5CA и перейдет к 0xFFFFFFFF, затем развернется к 0x00000000 и поднимется до 0x8AC5C5C9.

Если у вас есть несколько диапазонов кандидатов, которые вы хотели бы изучить в определенном порядке, может быть что-то вроде

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

но тогда вам нужно убедиться, что пары (начало, конец)rge покрывают все пространство между 0x00000000 и 0xFFFFFFFF, если вы действительно хотите проверить все это. (И снова обратите внимание, что диапазон увеличивает последний байт и seqприменяет байты значения в обратном порядке, в соответствии с вашими заявленными требованиями.)

Если вы хотите использовать два разных baseадреса, вы быстро столкнетесь с ограничениями того, что можно сделать в своей жизни с помощью грубой силы; но вы могли бы, например, разделить 4-байтовое число на две 2-байтовые части и применить их с разными смещениями.

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:]
tripleee
источник
Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Подмастерье Компьютерщик
4

Нет, нет, нет и снова НЕТ!

Редкий ответ, который вы получаете, не тот, который вы ожидаете.

Несколько вопросов для вас:

  • Возможно ли, что эксперт не знает, что можно грубо форсировать строку байтов и повторять попытку SHA-1, пока она не сойдет? нет
  • Возможно ли, что он забыл это? нет
  • Возможно ли, что вы не можете сделать это на RAR-файл? нет
  • Есть другой ответ не так? абсолютно НЕТ

Ну и что? ... время

Дело в том, что вы должны изменить так мало байтов ... только 4!

Что это значит? 256 4, то есть 256x256x256x256 возможностей, действительно очень большое число.
Если ваш компьютер мог обрабатывать 1 операцию в секунду (подстановка в файле + sha1) ...
вам следует подождать более 136 лет или, если вы предпочитаете, более 49710 дней.

Вам повезло, предварительно кэшированный файл объемом 5 МБ (уже загруженный в оперативную память и в кэш) запрашивает всего около 0,03 секунды (минимум 0,025 с) на старом компьютере. Это сокращает ваше ожидаемое время до 1242-1492 дней (что превышает 3 года).

Это правда, кстати, что по статистике у вас должен быть положительный ответ в половине случаев . Тем не менее, вам следует подождать, пока вы не попробуете все возможности, чтобы быть уверенным, что есть только одна замена, которая даст вам такую ​​же контрольную сумму SHA-1 ...

Теперь это НЕВОЗМОЖНО звучит как «невозможно в ДОСТОЙНОЕ количество времени».


Как продолжить

Более правильный ответ на ваш технический вопрос: когда вы говорите о грубой силе, необязательно использовать слепую грубую силу.

  • В другом ответе просто говорится, что вам не нужно вычислять контрольную сумму sha1 для детали до повреждения. Вы делаете 1-й раз и экономите время для каждой последующей итерации (может быть, фактор 2 зависит от позиции).

  • То, что может изменить бесполезные усилия, - это написать параллельный код, который будет работать на GPU. Если у вас хорошая графическая карта, у вас может быть около 1000 ядер, которые могут вычислять для вас параллельно (даже больше, но их частота ниже, чем у процессора, но все же их много). Если вы можете сократить время с 1400 до 1,4 дня, может быть, вы даже можете сделать это.

  • Другой подход может привести вас к более быстрому решению.
    Вы сказали, что это RAR файл. Структура файла rar разделена на блоки. Если вы примете это во внимание, вы увидите, куда падает коррупция. Если это на части данных, на части заголовков или на обоих. Тогда вы можете действовать соответственно. Для простоты давайте предположим, что это по данным:
    вы можете сделать грубую силу своего смещения, проверить для каждого положительного CRC этого блока, если это даже положительный SHA1 для всего файла. Снова вы можете сделать параллельный код.

Конечная нота

Если бы они были 6 байтов вместо 4, вы вышли из игры с существующей технологией.

Hastur
источник
Отличный ответ - не обязательно нужно исчерпывать все пространство, хотя сам rar в этом примере не будет распаковываться из-за внутренних проверок, даже если sha1 работает с дублирующим хешем. Попадание 4 байтов, которые ошибочно решили sha1 И внутреннюю CRC, было бы очень маловероятным.
rrauenza
@rrauenza Спасибо. Кстати не только (двойная проверка). Действительно, блок должен быть короче всей части от поврежденных байтов до конца файла, а CRC должен быть легче для вычисления, чем алгоритм sha1 ...
Hastur
@rrauenza Знаете ли вы, как я мог бы заставить фактический параллельный код работать на GPU? У меня хороший графический процессор. Спасибо.
Sbt19
Нет, я не. Вы можете использовать несколько процессоров, разделив пространство поиска.
rrauenza
@ Sbt19 Что бы они ни говорили вам об этом, Google не так страшно использовать ;-). Ищите (если nvidia), Cuda, brute force, sha1и у вас будет много подсказок, например, исходный код . КСТАТИ держать свое высокое внимание , потому что просмотр с этого пути Google, о мой мальчик, может привести вас на одной из темных сторон сети ... :-). (Не на github ... на другом сайте, где вы можете встретиться с такого рода исследованиями). PS> Есть много научных работ по смежным темам, например, эта ...
Hastur