손상된 파일을 복구하기 위해 몇 바이트를 자동으로 '부동'


35

누군가 파일의 특정 오프셋에서 힘 값을 무차별시키는 방법을 알고 있습니까? 무차별 강제 실행이 필요한 4 개의 연속 바이트입니다. 손상된 파일의 올바른 SHA-1을 알고 있습니다. 그래서 내가하고 싶은 것은 바이트 값을 변경할 때마다 완전한 파일 SHA-1을 비교하는 것입니다.

데이터 복구 전문가가 파일을 복구 문제로 제공했기 때문에 변경된 정확한 4 바이트를 알고 있습니다. 알고 싶은 사람들을 위해 rar 파일에는 의도적으로 변경된 4 바이트가 있습니다. 변경된 4 바이트와 원래 SHA-1의 오프셋을 들었습니다. 4 바이트가 변경되면 아카이브에서 정확한 파일을 복구하는 것이 불가능하다고 말했다. 비록 그것이 단지 몇 바이트이고 손상이 어디 있는지 정확히 알고 있었다고해도. 복구 기록이 없기 때문입니다. 특정 4 바이트를 올바르게 채워 넣을 수있는 방법이 있는지 확인하려고하므로 파일이 오류없이 압축 해제됩니다. 파일 크기는 약 5MB입니다.

:

내가 원하는 것을 정확하게 정의하기 위해 사진을 올렸습니다. 더 많은 담당자와 함께 누군가 나를 위해 여기에 게시 할 수 있다고 생각합니다.

스크린 샷

스크린 샷 2

내가 집중하고있는 예제 오프셋 0x78은 첫 번째 그림 CA 이 스크립트가 값을 1만큼 가져 오기를 원할 때 첫 번째 그림이 값을 표시하는 위치 이므로 CB두 번째 그림과 같이됩니다. 값을 계속 늘리고 1매번 전체 파일 SHA-1을 비교하고 싶습니다 . 지정된 오프셋에서 4 바이트 만 변경합니다.

CAC5C58ASHA-1 을 시도 하고 비교합니다. 일치하지 않으면을 시도한 다음 CBC5C58A첫 번째 값에 도달 FF하면 계속 진행합니다 00C6C58A. 기본적으로, 나는 00000000-FFFFFFFF그것을 시작할 수 있기를 원하지만 시작하고 끝나는 곳을 선택할 수있는 옵션을 갖기를 원합니다. 시간이 걸릴 수 있지만 여전히 시도하고 싶습니다. 손상 된 바이트의 정확한 오프셋을 알고 있습니다. 올바른 값만 있으면됩니다.

Google에서 검색하는 경우 : "무차별적인 방법으로 손상된 파일을 수정하는 방법"Linux 프로그램을 작성한 사람이 있습니다. 그러나 프로그램에 포함 된 파일에 대해서만 작동합니다. 내 파일과 동일한 프로세스를 사용하는 방법을 찾고 있습니다.


3
슈퍼 유저에 오신 것을 환영합니다! 주제에 맞지 않는 프로그램 요청을 삭제하기 위해 귀하의 질문을 편집했습니다. 본 예제를 포함하도록 질문편집 할 수 있습니까 ? 연구를 해왔지만 도움이 될만한 연구를 정확하게 보여주십시오 :)
bertieb

20
이 파일로 어떻게 끝났는지, 어떻게 4 바이트가 손상되었는지 어떻게 알 수 있습니까?
Edoardo

1
파일 형식을 알고 있습니까? 그렇게하면 정확한 값을 계산하거나 범위를 제한하여 무차별 대입하려고하지 않을 수 있습니다. 그러나 일반적으로 보안상의 이유로 손상된 파일을 덤프해야합니다.
StephenG

11
@eddyce 나는 정말로 당신의 질문의 두 번째 부분에 관심이 있습니다- 왜 그 4 바이트입니까?
크레이그 오티스

2
호기심으로 파일이 어떻게 손상 되었습니까? 그리고 그것이 4 바이트라는 것을 어떻게 알 수 있습니까?
JohnEye

답변:


27

여기 당신이 묘사하는 것처럼 보이는 작은 파이썬 프로그램이 있습니다.

#!/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 = ...

그러나 실제로 모든 것을 검사 하려면 (시작, 끝) 쌍이 rge0x00000000과 0xFFFFFFFF 사이의 모든 공간을 포함하는지 확인해야합니다. (다시 말해 범위는 마지막 바이트를 증가시키고 지정된 seq요구 사항에 따라 값의 바이트를 반대로 적용합니다.)

서로 다른 두 개의 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:]

의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Journeyman Geek

4

아냐 아냐 아냐 아냐 아냐

당신이 얻는 대답은 거의 기대하지 않습니다.

당신을위한 몇 가지 질문 :

  • 그것은 가능성이 전문가 는 바이트의 문자열을 무력하고 반복적으로 SHA-1이 수렴 될 때까지 시도하는 것이 가능하다는 것을 알고하지 않는 이유는 무엇입니까? 아니
  • 그는 그것을 잊을 수 있습니까? 아니
  • rar 파일에서 수행 할 수 없습니까? 아니
  • 다른 대답 잘못은? 절대 아니요

그래서 무엇? ... 시각.

요점은 몇 바이트 만 바꿔야한다는 것입니다.

무엇 않습니다 그 의미? 256 4 256x256x256x256 가능성, 정말 정말 큰 숫자입니다.
컴퓨터에서 초당 1 회 작업 (파일 대체 + sha1) 을 처리 할 수있는 경우
136 년 이상 기다려야 하거나 49710 일 이상을 선호해야합니다.

5MB의 미리 캐시 된 파일 (이미 ram 및 캐시에로드 됨)은 오래된 컴퓨터에서 약 0.03 초 (최소 0.025 초) 만 묻습니다. 이로 인해 예상 시간이 1242-1492 일 (3 년 이상)으로 줄어 듭니다.

통계적으로 절반의 시간 안에 긍정적 인 대답을해야한다는 것이 BTW 입니다. 그럼에도 불구하고 당신은 당신에게 동일한 SHA-1 체크섬을 줄 1 개의 치환 만이 있는지 확인하기 위해 모든 가능성을 시도 할 때까지 기다려야합니다 ...

이제 안되고 "하지 가능하면 같이 소리 보람있는 시간의 양."


진행하는 방법

기술적 인 질문에 대한보다 적절한 답변 : 무차별 대입에 대해 이야기 할 때 맹인 무차별 대입이 필요하지 않습니다.

  • 그것은 다른 답변의 주석에서 부패하기 전에 부분의 sha1 체크섬을 계산할 필요가 없다는 언급에 언급되어 있습니다. 첫 번째 작업을 수행하고 연속 된 각 반복에 대한 시간을 절약합니다 (위치에 따라 요소 2가 달라질 수 있음).

  • 많은 노력을 기울일 수있는 것은 GPU에서 실행될 병렬 코드작성 하는 것입니다. 좋은 그래픽 카드가 있다면 병렬로 계산할 수있는 약 1000 개의 코어가있을 수 있습니다 (심지어 CPU보다 주파수가 낮지 만 여전히 많이 있습니다). 시간을 1400에서 1.4 일로 줄일 수 있다면 아마 할 수도 있습니다.

  • 다른 접근 방식은 빠른 솔루션 당신을 이끌 수 있습니다.
    당신은 그것이 rar 파일이라고 말했습니다. RAR 파일 구조는 블록으로 분할된다. 당신이 그것을 계산하면 부패가 어디에서 떨어지는 지 볼 수 있습니다. 데이터 부분, 헤더 부분 또는 둘 다에있는 경우 그러면 결과적으로 행동 할 수 있습니다. 간단하게하기 위해 데이터가 있다고 가정 해 봅시다.
    오프셋의 무차별 대입을 수행 할 수 있으며 전체 파일에서 SHA1이 양수인 경우 해당 블록의 각 양의 CRC를 확인하십시오. 다시 병렬 코드를 수행 할 수 있습니다.

최종 메모

만약 그들이 4 바이트가 아닌 6 바이트라면 당신은 현재 기술로 게임에서 벗어난 것입니다.


큰 대답-sha1이 중복 해시로 작업 하더라도이 예제의 rar 자체는 내부 검사로 인해 압축을 풀지 않기 때문에 반드시 전체 공간을 다 쓸 필요는 없습니다. sha1을 잘못 해결하고 내부 crc를 잘못 해결 한 4 바이트를 치는 것은 매우 가능성이 낮습니다.
rrauenza

@rrauenza 감사합니다. BTW뿐만 아니라 (더블 체크). 실제로 블록은 손상된 바이트에서 파일의 끝까지 전체 부분보다 짧아야하고 sha1 알고리즘을 계산하기 위해 CRC는 더
작아야

@rrauenza GPU에서 실제 병렬 코드를 실행하는 방법을 알고 있습니까? 좋은 GPU가 있습니다. 감사.
Sbt19

아니, 난하지 않습니다. 검색 공간을 분할하여 여러 CPU를 사용할 수 있습니다.
rrauenza

@ Sbt19 그들이 당신에 대해 뭐라고 말하든 구글은 그렇게 무섭지 않다 ;-). (nvidia 인 경우)를 검색하면 소스 코드Cuda, brute force, sha1 와 같은 힌트가 많이 있습니다 . 때문에 BTW 관심을 높게 유지 하는 구글의 경로에서 검색, 오, 내 아들은 그물의 어두운 측면 중 하나에 당신을 이끌 수있다 ... :-). (github에는 없습니다 ... 이러한 종류의 연구를 만날 수있는 다른 사이트에서는). 추신> 관련 주제에 대한 과학 논문이 많이 있습니다. 예를 들면 다음같습니다 .
Hastur
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.