破損したファイルを回復するために数バイトを自動的に「ブルートフォース」


35

ファイルの特定のオフセットで値をブルートフォースする方法を知っている人はいますか?ブルートフォースが必要な4つの連続したバイトです。破損したファイルの正しいSHA-1を知っています。そのため、バイト値を変更するたびに、完全なファイルSHA-1を比較します。

変更された正確な4バイトを知っているのは、ファイルがデータリカバリの専門家からリカバリの課題として与えられたためです。知りたい人のために、rarファイルには意図的に変更された4バイトがあります。変更された4バイトと元のSHA-1のオフセットが通知されました。その人は、4バイトが変更されたら、アーカイブ内の正確なファイルを回復することは不可能だと言いました。それがほんの数バイトであり、破損がどこにあるかを正確に知っていたとしても。リカバリレコードがないため。これらの特定の4バイトを正しく入力して、ファイルがエラーなしで解凍されるようにする方法があるかどうかを確認しようとしています。ファイルサイズは約5MBです。

写真をアップロードしたので、私がやろうとしていることを正確に定義できます。誰かが私のためにもっと多くの担当者と一緒にここに投稿できると信じています。

スクリーンショット1

スクリーンショット2

私が注目しているオフセットの例は0x78、最初の写真が値を表示する場所CA です。スクリプトで値を1 CBずつ増やして、2番目の写真のようになります。値を増やし続け、1毎回ファイル全体SHA-1を比較してほしい。指定されたオフセットでこれらの4バイトのみを変更します。

CAC5C58ASHA-1を比較しようとします。一致しない場合はCBC5C58A、最初の値に達するFFと、などに進み00C6C58Aます。基本的に、そこから移動できるようにし00000000-FFFFFFFFたいのですが、開始と終了の場所を選択するオプションも持っています。時間がかかるかもしれませんが、試してみたいと思います。破損したバイトの正確なオフセットを知っていることに注意してください。正しい値が必要です。

Googleで検索する場合:「ブルートフォースによって破損したファイルを修正する方法」Linuxプログラムを書いた人がいます。ただし、プログラムに含まれているファイルに対してのみ機能します。ファイルで同じプロセスを使用する方法を探しています。


3
スーパーユーザーへようこそ!私はあなたの質問を編集して、プログラムのリクエストを削除しました。質問編集して、見た例(の一部)を含めることはできますか?あなたはそれを研究まさに研究を行ったが、私たちを示していることがそれの良い:)は参考になるである
bertieb

20
このファイルにどのようになったのか、それらが唯一の4つの破損バイトであることをどのように確認することができますか?
エドアルド

1
ファイル形式を知っていますか?そうした場合、ブルートフォースを試みるのではなく、正しい値を算出したり、範囲を制限したりできる場合があります。ただし、一般的に、セキュリティ上の理由から、破損したファイルはダンプすることをお勧めします。
-StephenG

11
@eddyceあなたの質問の2番目の部分に本当に興味があります- なぜそれらの4バイトなのですか?
クレイグオーティス

2
好奇心から、ファイルはどのように破損しましたか?そして、それがこれらの4バイトだったことをどうやって知るのですか?
ジョンアイ

回答:


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')

国連簡単なテストのみ。タイプミスを見つけたら私にpingを送ってください。

base4つのバイトを適用しようとする指定し、長い文字列'996873...期待SHA1の16進数表現です。行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魔法からそれをルックアップするために持っていたバイトのシーケンス(にこれを変換することです// stackoverflowの:httpsを。 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された要件に従って、値のバイトを逆に適用することに注意してください。)

2つの異なるbaseアドレスを使用したい場合、ブルートフォースを使用して一生の間に実行可能な制限にすぐに立ち向かいます。しかし、たとえば、4バイトの数値を2つの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:]

コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
ジャーニーマンオタク

4

いやいやいや

あなたが得る答えがあなたが期待するものではないことはめったにありません。

あなたへのいくつかの質問:

  • それは可能性があり、専門家は、バイトのための文字列をブルートフォースと繰り返しSHA-1、それが収束するまでをしようとすることが可能であることを知らないのですか?いや
  • 彼はそれを忘れることは可能ですか?いや
  • rarファイルで実行できない可能性はありますか?いや
  • ある他の回答間違いましたか?絶対にNO

だから何?...時間。

ポイントは、数バイトだけ変更する必要があるということです...たった4バイトです!

どういう意味ですか?256 4は256x256x256x256の可能性で、本当に大きな数字です。
コンピューターが1秒あたり1つの操作を処理できる場合(ファイル内の置換+ sha1)...
136年以上待つか、49710日以上待つ場合。

幸運なことに、5MBの事前キャッシュファイル(RAMおよびキャッシュに既にロードされている)は、古いコンピューターで約0.03秒(最小0.025秒)しか要求しません。これにより、予想時間は1242〜1492日(3年以上)に短縮されます。

これは、こと、ところで、真で統計的にあなたが時間の半分に肯定的な答えを持っている必要があります。それでも、すべての可能性を試して、同じSHA-1チェックサムを提供する置換が1つしかないことを確認するまで待つ必要があります...

今ではIMPOSSIBLE「のことはできないような音価値がある時間の長さ」。


どうやって進める

技術的な質問に対するより適切な答え:総当たり攻撃について話すときは、盲目的な総当たり攻撃である必要はありません。

  • 他の回答のコメントに、破損前の部分でsha1チェックサムを計算する必要がないことが明記されています。1回目を実行し、連続する反復ごとに時間を節約します(おそらく、位置に依存する係数2)。

  • 努力の価値を変えることができる何かは、GPUで実行される並列コードを書くことです。優れたグラフィックカードをお持ちの場合は、並列で計算できるコアが約1000個ある場合があります(さらに多くの場合、CPUよりも低い周波数ですが、それでも多くのコアがあります)。時間を1400日から1.4日に短縮できる場合は、それを行うこともできます。

  • 別のアプローチは、より高速なソリューションにあなたを導くことができます。
    あなたはそれがrarファイルだと言った。RARファイルの構造は、ブロックに分割されます。あなたがそれを数えるなら、腐敗がどこに落ちるかを見ることができます。データの一部、ヘッダーの一部、または両方にある場合。その後、結果的に行動することができます。簡単にするために、それがデータを超えていると仮定しましょう:
    オフセットのブルートフォースを行うことができ、そのブロックの各正のCRCがファイル全体の正のSHA1であってもチェックします。ここでも、並列コードを実行できます。

最後のメモ

4バイトではなく6バイトだった場合、現在の技術ではゲームから除外されていました。


素晴らしい答え-この例のrar自体は、sha1が重複ハッシュで機能しても、内部チェックのために解凍しないため、必ずしもスペース全体を使い果たす必要はありません。sha1を誤って解決し、内部crcを誤って解決した4バイトをヒットすることはほとんどありません。
ラウエンツァ

@rrauenzaありがとう。ところで(ダブルチェック)だけではありません。実際、ブロックは破損したバイトからファイルの最後までの全体よりも短く、CRCはsha1アルゴリズムを計算するために軽くする必要があります...
Hastur

@rrauenza GPUで実際の並列コードを実行する方法を知っていますか?優れたGPUがあります。ありがとう。
Sbt19

いいえ、私はしません。ただし、検索スペースを分割することで複数のCPUを使用できます。
ラウエンツァ

@ Sbt19彼らがそれについてあなたに言ったことは何でもグーグルは使うのがそんなに怖くない;-)。(nvidiaの場合)Cuda, brute force, sha1を検索すると、ソースコードなど、多くのヒントが得られます。ところでので、あなたの注意を高く保つこと、Googleのパスから閲覧、私の少年ああ、ネットの暗い側のいずれかにあなたを導くことが ... :-)。(githubではありません...この種の研究に出会える他のサイト)。PS>関連トピックに関する科学論文が多数あります。たとえば、これは ...
Hastur
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.