Automáticamente 'fuerza bruta' unos pocos bytes para recuperar un archivo corrupto

35

¿Alguien sabe por ahí una forma de valores de fuerza bruta en un desplazamiento particular en un archivo? Son 4 bytes consecutivos que tendrían que ser forzados por fuerza bruta. Sé el SHA-1 correcto del archivo corrupto. Entonces, lo que me gustaría hacer es comparar el archivo completo SHA-1, cada vez que cambia el valor del byte.

Sé exactamente los 4 bytes que se cambiaron, porque un experto en recuperación de datos me dio el archivo como un desafío de recuperación. Para aquellos que estén interesados ​​en saber, el archivo rar tiene 4 bytes que fueron cambiados intencionalmente. Me dijeron las compensaciones de los 4 bytes modificados y el SHA-1 original. La persona dijo que es IMPOSIBLE recuperar el archivo exacto en el archivo una vez que se cambiaron los 4 bytes. Incluso si solo eran unos pocos bytes y usted sabía exactamente dónde se encontraba la corrupción. Dado que no tiene un registro de recuperación. Estoy tratando de ver si hay una manera de que esos 4 bytes en particular se llenen correctamente para que el archivo se descomprima sin error. El tamaño del archivo es de alrededor de 5 mb.

Ejemplo :

Subí fotos para que esté más claramente definido de exactamente lo que estoy buscando hacer. Creo que alguien puede publicarlos aquí para mí con más representante.

Captura de pantalla uno

Captura de pantalla dos

El desplazamiento de ejemplo en el que me estoy centrando es 0x78donde la primera imagen muestra el valor, ya CA que quiero que el script tome el valor en 1 para que se vuelva CBcomo se muestra en la segunda imagen. Quiero que siga aumentando el valor 1y luego compare todo el archivo SHA-1 cada vez. Solo haciendo cambios a esos 4 bytes en el desplazamiento especificado.

Intentará CAC5C58Acomparar el SHA-1. Si no coincide, entonces lo intentará. CBC5C58ALuego, una vez que llegue el primer valor FF, irá a 00C6C58Ay así sucesivamente. Básicamente, me gustaría poder ir, 00000000-FFFFFFFFpero también tener la opción de elegir dónde quieres que comience y termine. Sé que podría llevar algo de tiempo, pero todavía me gustaría probarlo. Tenga en cuenta que sé el desplazamiento exacto de los bytes que están corruptos. Solo necesito los valores correctos.

Si busca en Google: "Cómo reparar un archivo dañado por la fuerza bruta" Hay una persona que escribió un programa de Linux. Sin embargo, solo funciona contra los archivos incluidos con el programa. Estoy buscando alguna forma de usar el mismo proceso con mi archivo.

Sbt19
fuente
3
¡Bienvenido a Super User! He editado su pregunta para eliminar la solicitud de un programa, que estaría fuera de tema. ¿Puedes editar tu pregunta para incluir (algunos de) los ejemplos que viste? Es bueno que hayas investigado, pero que nos
muestres
20
¿podría preguntar cómo terminó con este archivo y cómo puede estar seguro de que esos son los únicos 4 bytes corruptos?
Edoardo
1
¿Conoces el formato del archivo? Si lo hace, podría calcular los valores correctos o limitar los rangos, en lugar de tratar de forzarlos por fuerza bruta. En general, sin embargo, sugeriría que cualquier archivo dañado se descarte por razones de seguridad.
StephenG
11
@eddyce Estoy realmente interesado en la segunda parte de tu pregunta: ¿por qué esos 4 bytes?
Craig Otis
2
Por curiosidad, ¿cómo se corrompió el archivo? ¿Y cómo sabes que eran esos cuatro bytes?
JohnEye

Respuestas:

27

Aquí hay un pequeño programa de Python que hace lo que parece estar describiendo.

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

Naciones UnidasSolo brevemente probado; por favor envíame un ping si encuentras errores tipográficos.

Las baseespecifica dónde tratan de aplicar los cuatro bytes, y la larga cadena '996873... es la representación hexadecimal de la SHA1 esperado. La línea for seq in... define los bytes a intentar; y, por supuesto, reemplácelo 'binaryfile'con la ruta al archivo que desea intentar salvar.

Puede reemplazar la lista literal [[0xCA, 0xC5,... ]]con algo para recorrer todos los valores posibles, pero básicamente es solo un marcador de posición para algo más útil porque no estoy realmente seguro de qué es exactamente lo que quiere allí.

Algo así se for seq in itertools.product(range(256), repeat=4)):repetirá sobre todos los valores posibles de 0 a 2 32 -1. (Necesitará agregar import itertoolscerca de la parte superior entonces). O tal vez podría simplemente agregar un desplazamiento; actualice el script para reemplazar el actual for seq incon lo siguiente (donde nuevamente importdebe ir antes del 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 = ...

Invertí el orden de los bytes para que aumente naturalmente de 0x8AC5C5CA a 0x8AC5C5CB, pero luego el siguiente incremento será 0x8AC5C5CC, etc. La structmagia es convertir esto en una secuencia de bytes (tenía que buscarlo desde https: // stackoverflow. com / a / 26920983/874188 ). Esto comenzará en 0x8AC5C5CA e irá a 0xFFFFFFFF, luego pasará a 0x00000000 y volverá a subir hasta 0x8AC5C5C9.

Si tiene varios rangos de candidatos que le gustaría examinar en un orden particular, tal vez algo así 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 = ...

pero luego deberá asegurarse de que los pares (inicio, fin)rge cubran todo el espacio entre 0x00000000 y 0xFFFFFFFF si realmente desea examinarlo todo. (Y de nuevo, observe que el rango incrementa el último byte y que seqaplica los bytes del valor a la inversa, de acuerdo con los requisitos establecidos).

Si desea utilizar dos basedirecciones diferentes , rápidamente se encuentra con los límites de lo que es posible hacer en su vida con fuerza bruta; pero podría, por ejemplo, dividir el número de 4 bytes en dos partes de 2 bytes y aplicarlas en diferentes desplazamientos.

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
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Journeyman Geek
4

No, no, no y otra vez NO!

Rara vez la respuesta que obtienes no es lo que esperas.

Algunas preguntas para ti:

  • ¿Es posible que un experto no sepa que es posible forzar la fuerza bruta de una cadena de bytes y probar iterativamente el SHA-1 hasta que converja? No
  • ¿Es posible que lo olvide? No
  • ¿Es posible que no pueda hacerlo en un archivo rar? No
  • ¿ La otra respuesta es incorrecta? absolutamente NO

¿Y qué? ... Hora.

El punto es que tienes que cambiar tan pocos bytes ... ¡solo 4!

¿Qué significa? 256 4 es decir 256x256x256x256 posibilidades, un número realmente muy grande.
Si su computadora pudo procesar 1 operación por segundo (sustitución en el archivo + sha1) ...
debe esperar más de 136 años , o si prefiere más de 49710 días.

Eres lo suficientemente afortunado, un archivo pre-almacenado en caché de 5MB (ya cargado en la memoria RAM y en el caché) solo pide aproximadamente 0.03 segundos (mínimo 0.025s), en una computadora vieja. Eso reduce su tiempo de espera a 1242-1492 días (algo más de 3 años).

Es cierto, por cierto, que estadísticamente debería tener una respuesta positiva en la mitad del tiempo . No obstante, debe esperar hasta que haya probado todas las posibilidades para asegurarse de que solo haya una sustitución que le otorgue la misma suma de control SHA-1 ...

Ahora que IMPOSIBLE suena como "no es posible en un MUCHO MOMENTO de tiempo".


Cómo proceder

Una respuesta más adecuada a su pregunta técnica: cuando habla de fuerza bruta, no tiene que ser necesaria la fuerza bruta ciega.

  • Solo se indica en un comentario en la otra respuesta que no es necesario calcular la suma de comprobación sha1 de la parte anterior a la corrupción. Realiza la primera vez y ahorra tiempo para cada iteración sucesiva (tal vez un factor 2 depende de la posición).

  • Algo que puede cambiar el esfuerzo inútil es escribir un código paralelo que se ejecutará en la GPU. Si tiene una buena tarjeta gráfica, puede tener alrededor de 1000 núcleos que pueden calcular en paralelo (incluso más, pero tienen una frecuencia más baja que la CPU, pero aún así son muchos). Si puede disminuir el tiempo de 1400 a 1.4 días, tal vez incluso pueda hacerlo.

  • Un enfoque diferente puede llevarlo a una solución más rápida.
    Dijiste que es un archivo rar. La estructura del archivo rar se divide en bloques. Si lo cuentas, puedes ver dónde cae la corrupción. Si es de parte de los datos, de parte de los encabezados o de ambos. Entonces puedes actuar en consecuencia. En aras de la simplicidad, supongamos que está sobre los datos:
    puede hacer la fuerza bruta de su desplazamiento, verifique cada CRC positivo de ese bloque si incluso es positivo el SHA1 en todo el archivo. De nuevo puedes hacer un código paralelo.

Nota final

Si fueran 6 bytes en lugar de 4, estarías fuera del juego con la tecnología actual.

Hastur
fuente
Gran respuesta: sin embargo, uno no necesariamente necesitaría agotar todo el espacio porque el rar en este ejemplo no se descomprimiría debido a las comprobaciones internas, incluso si el sha1 funcionara con un hash duplicado. Golpear 4 bytes que resolvieron falsamente el sha1 Y un crc interno falsamente sería muy poco probable.
rrauenza
@rrauenza Gracias. Por cierto no solo (la doble verificación). De hecho, el bloque debería ser más corto que toda la parte desde los bytes corruptos hasta el final del archivo, y el CRC debería ser más ligero para calcular que el algoritmo sha1 ...
Hastur
@rrauenza ¿Sabes cómo haría para que el código paralelo real se ejecute en la GPU? Tengo una buena GPU. Gracias.
Sbt19
No, yo no. Sin embargo, podría usar múltiples cpus al particionar el espacio de búsqueda.
rrauenza
@ Sbt19 Lo que sea que te hayan dicho al respecto google no es tan aterrador de usar ;-). Busque (si es nvidia) Cuda, brute force, sha1y tendrá muchas sugerencias, por ejemplo, código fuente . Por cierto a mantener su alta atención porque la navegación de ese camino Google, oh hijo mío, puede llevarle a uno de los lados oscuros de la red ... :-). (No en github ... en otro sitio que pueda encontrar con este tipo de investigaciones). PD> Hay muchos artículos científicos sobre temas relacionados, por ejemplo , este ...
Hastur