'Força bruta' automaticamente alguns bytes para recuperar um arquivo corrompido


35

Alguém aí sabe como encontrar valores de força bruta em um deslocamento específico de um arquivo? São 4 bytes consecutivos que precisam ser brutais. Eu sei o SHA-1 correto do arquivo corrompido. Então, o que eu gostaria de fazer é comparar o arquivo completo SHA-1, sempre que ele altera o valor do byte.

Conheço exatamente os 4 bytes que foram alterados, porque o arquivo me foi fornecido por um especialista em recuperação de dados como um desafio de recuperação. Para aqueles que estão interessados ​​em saber, o arquivo rar possui 4 bytes que foram intencionalmente alterados. Foi-me dito os deslocamentos dos 4 bytes alterados e do SHA-1 original. A pessoa disse que é IMPOSSÍVEL recuperar o arquivo exato no arquivo morto depois que os 4 bytes foram alterados. Mesmo que fosse apenas alguns bytes e você sabia exatamente onde a corrupção estava localizada. Como não possui um registro de recuperação. Estou tentando ver se existe uma maneira de preencher esses 4 bytes corretamente corretamente, para que o arquivo seja descompactado sem erros. O tamanho do arquivo é de cerca de 5 MB.

Exemplo :

Fiz upload de fotos para que fique mais claramente definido exatamente o que estou procurando fazer. Acredito que alguém possa publicá-las aqui para mim com mais rep.

Screenshot One

Captura de tela dois

O exemplo de deslocamento no 0x78qual estou focando é onde a primeira foto mostra o valor que CA eu quero que o script aumente o valor em 1, para que ele se torne CBcomo mostrado na segunda foto. Eu quero que ele continue aumentando o valor 1e compare o arquivo SHA-1 todo a cada vez. Apenas fazendo alterações nesses 4 bytes no deslocamento especificado.

Ele tentará CAC5C58Acomparar o SHA-1. Se não corresponder, ele tentará. CBC5C58ADepois que o primeiro valor atingir, FFele irá para 00C6C58Ae assim por diante. Basicamente, eu gostaria de poder ir, 00000000-FFFFFFFFmas também ter a opção de escolher onde você quer que comece e termine. Eu sei que isso pode levar algum tempo, mas eu ainda gostaria de tentar. Tenha em mente que eu sei o deslocamento exato dos bytes que estão corrompidos. Eu só preciso dos valores corretos.

Se você pesquisar no Google: "Como corrigir um arquivo corrompido por força bruta" Há uma pessoa que escreveu um programa Linux. No entanto, ele funciona apenas nos arquivos incluídos no programa. Estou procurando uma maneira de usar o mesmo processo com o meu arquivo.


3
Bem-vindo ao Super Usuário! Editei sua pergunta para remover a solicitação de um programa, que seria fora de tópico. Você pode editar a sua pergunta para incluir (algumas das) os exemplos que você viu? Bom é que você tem feito pesquisa, mas nos mostrando exatamente o que a pesquisa que é seria útil :)
bertieb

20
eu poderia perguntar como você acabou com este arquivo e como você pode ter certeza de que esses são os únicos 4 bytes corrompidos?
Edoardo

11
Você conhece o formato do arquivo? Se você conseguir, poderá calcular os valores corretos ou limitar os intervalos, em vez de tentar forçá-los com força bruta. No entanto, em geral, sugiro que qualquer arquivo corrompido seja despejado por razões de segurança.
StephenG

11
@eddyce Estou realmente interessado na segunda parte da sua pergunta - por que esses 4 bytes?
Craig Otis

2
Por curiosidade, como o arquivo foi corrompido? E como você sabe que eram esses quatro bytes?
JohnEye

Respostas:


27

Aqui está um pequeno programa Python que faz o que você parece estar descrevendo.

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

UnApenas brevemente testado; por favor, envie-me um ping se encontrar erros de digitação.

Os baseespecifica onde tentam aplicar os quatro bytes, e a cadeia longa '996873... é a representação hexadecimal do SHA1 esperado. A linha for seq in... define os bytes para tentar; e, é claro, substitua 'binaryfile'pelo caminho do arquivo que você deseja tentar recuperar.

Você pode substituir a lista literal [[0xCA, 0xC5,... ]]por algo que realmente repasse todos os valores possíveis, mas é basicamente apenas um espaço reservado para algo mais útil, porque não tenho certeza do que exatamente você deseja.

Algo como for seq in itertools.product(range(256), repeat=4)):passará por todos os valores possíveis de 0 a 2 32 -1. (Você precisará adicionar import itertoolspróximo ao topo.) Ou talvez você possa simplesmente adicionar um deslocamento; atualize o script para substituir o atual for seq inpelo seguinte (onde novamente é importnecessário ir antes do programa principal);

import struct

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

Eu inverti a ordem dos bytes para que naturalmente aumentasse de 0x8AC5C5CA para 0x8AC5C5CB, mas o próximo incremento será 0x8AC5C5CC etc. A structmágica é converter isso em uma sequência de bytes (tive que procurar em https: // stackoverflow. com / a / 26920983/874188 ). Isso começará em 0x8AC5C5CA e irá para 0xFFFFFFFF, depois envolverá para 0x00000000 e voltará para 0x8AC5C5C9.

Se você tem vários intervalos de candidatos que gostaria de examinar em uma ordem específica, talvez algo como

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

mas você precisará garantir que os pares (início, fim)rge abranjam todo o espaço entre 0x00000000 e 0xFFFFFFFF, se você realmente quiser examinar tudo. (E, novamente, observe que o intervalo incrementa o último byte e que seqaplica os bytes do valor ao contrário, de acordo com os requisitos estabelecidos.)

Se você quiser usar dois baseendereços diferentes , rapidamente se depara com os limites do que é possível fazer em sua vida com força bruta; mas você pode, por exemplo, dividir o número de 4 bytes em duas partes de 2 bytes e aplicá-las em diferentes compensações.

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

Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Journeyman Geek

4

Não, não, não e novamente NÃO!

Raramente a resposta que você recebe não é o que você espera.

Algumas perguntas para você:

  • É possível que um especialista não saiba que é possível fazer força bruta em uma sequência de bytes e experimentar iterativamente o SHA-1 até que ele converja? Não
  • É possível que ele esqueça? Não
  • É possível que você não possa fazer isso em um arquivo rar? Não
  • A outra resposta está errada? absolutamente NÃO

E daí? ... Tempo.

O ponto é que você precisa alterar tão poucos bytes ... apenas 4!

O que isso significa? 256 4, ou seja, 256x256x256x256 possibilidades, um número realmente grande.
Se o seu computador conseguiu processar 1 operação por segundo (substituição no arquivo + sha1) ...
você deve esperar mais de 136 anos ou, se preferir, mais de 49710 dias.

Você tem sorte: um arquivo pré-armazenado em cache de 5 MB (já carregado no RAM e no cache) pede apenas cerca de 0,03 segundos (mín 0,025s), em um computador antigo. Isso reduz o tempo de espera para 1242-1492 dias (algo mais que 3 anos).

É verdade que, estatisticamente, você deve ter uma resposta positiva na metade do tempo . No entanto, você deve esperar até ter tentado todas as possibilidades para ter certeza de que há apenas 1 substituição que fornecerá a mesma soma de verificação SHA-1 ...

Agora que IMPOSSÍVEL soa como "não é possível em um período de tempo INTEIRO ".


Como proceder

Uma resposta mais adequada à sua pergunta técnica: quando você fala sobre força bruta, não precisa ser necessária a força bruta cega.

  • É apenas afirmado em um comentário na outra resposta que você não precisa calcular a soma de verificação sha1 da parte antes da corrupção. Você faz a primeira vez e economiza tempo para cada iteração sucessiva (talvez um fator 2 dependa da posição).

  • Algo que pode mudar o esforço inútil é escrever um código paralelo que será executado na GPU. Se você possui uma boa placa gráfica, pode ter cerca de 1000 núcleos que podem ser computados em paralelo (ainda mais, mas eles têm uma frequência mais baixa que a CPU, mas ainda são muitos). Se você é capaz de diminuir o tempo de 1400 para 1,4 dias, talvez possa fazê-lo.

  • Uma abordagem diferente pode levar você a uma solução mais rápida.
    Você disse que é um arquivo rar. A estrutura do arquivo rar é dividida em blocos. Se você contar isso, poderá ver onde a corrupção cai. Se estiver na parte dos dados, na parte dos cabeçalhos ou em ambos. Então você pode agir consequentemente. Por uma questão de simplicidade, vamos supor que esteja acima dos dados:
    você pode fazer a força bruta de seu deslocamento, verificar cada CRC positivo desse bloco se é mesmo positivo o SHA1 em todo o arquivo. Novamente, você pode fazer um código paralelo.

Nota final

Se fossem 6 bytes em vez de 4, você estava fora do jogo com a tecnologia atual.


Ótima resposta - não seria necessário esgotar todo o espaço, porque o rar neste exemplo não seria descompactado devido a verificações internas, mesmo que o sha1 funcionasse com um hash duplicado. Atingir 4 bytes que resolveram o sha1 falsamente E um CRC interno falsamente seria muito, muito improvável.
Rruenza

@rrauenza Obrigado. Aliás, não apenas (a verificação dupla). Na verdade, o bloco deve ser mais curto, em seguida, toda a parte dos bytes corrompidos para o final do arquivo, eo CRC deve ser mais leve para calcular então o algoritmo SHA1 ...
Hastur

@ruuenza Você sabe como eu faria para obter o código paralelo real para rodar na GPU? Eu tenho uma boa GPU. Obrigado.
Sbt19

Não, eu não. Você pode usar vários cpus particionando o espaço de pesquisa.
Rruenza

@ Sbt19 O que eles disseram sobre o Google não é tão assustador de usar ;-). Procure (se nvidia) Cuda, brute force, sha1e você terá muitas dicas, por exemplo, código fonte . BTW manter sua alta atenção porque navegando desse caminho google, oh meu filho, pode levá-lo em um dos lados obscuros da rede ... :-). (Não no github ... em outro site que você pode encontrar com esse tipo de pesquisa). PS> Há muitos artigos científicos sobre tópicos relacionados, por exemplo , este ...
Hastur
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.