Ofuscación de código basado en hash

0

El siguiente código

if(str1 == "abc") {}

se puede convertir a

if(hash(str1) == 0x8732e) {} // assume hash("abc") == 0x8732e

para ofuscar el código.

Pero no son equivalentes cuando ocurre una colisión de hash; por ejemplo, el valor hash de str1="xyz" es el mismo que "abc".

Eso es cierto teóricamente. ¿Pero es un problema en la vida real cuando el método anterior se utiliza para ofuscar el código? ¿Es un método de ofuscación bien aceptado?

    
pregunta Infinite 05.08.2016 - 17:20
fuente

2 respuestas

3

El ejemplo del resumen hash que has dado es demasiado corto (20 bits o alrededor de un millón de posibilidades), por lo que tendrías colisiones con demasiada frecuencia y, lo que es peor, cualquiera que haya descompilado tu programa podría producir las cadenas correctas (o , al menos, cadenas que son aceptables debido a las colisiones de hash) simplemente forzando bruscamente el posible espacio de entrada.

"Esa es una objeción tonta. Es solo un ejemplo ..." podría decir, pero realmente no lo es. He encontrado, y explotado, este tipo exacto de debilidad antes. Por ejemplo, había una aplicación móvil que usaba una función hash de 32 bits en las entradas del usuario para intentar ocultar qué entradas producirían qué salidas. Tardó menos de una hora en escribir y ejecutar un programa que forzó bruscamente el espacio de búsqueda y encontró entradas que se asignaban a cada resumen de hash que la aplicación estaba buscando.

En esencia, esto es muy parecido a tratar de almacenar contraseñas de forma segura. Definitivamente hay diferencias: las contraseñas rara vez son muy largas, mientras que las cadenas codificadas en un programa pueden serlo, y si realiza la prueba de igualdad de cadenas con frecuencia, no puede permitirse que sea tan lenta como una buena función de verificación de contraseña. ser - pero muchos de los mismos paralelos se mantienen. Utilice una función hash fuerte, no solo resistente a las colisiones y la reversión, sino también a una que no sea tan rápida como sea posible para forzar la fuerza bruta en todo el espacio de búsqueda. Para cadenas cortas, use sal para que las personas no puedan simplemente buscar el valor en una tabla de arco iris.

Ahora, en cuanto a la ofuscación real: esta técnica es una (de muchas) que la ofuscación puede usar. Por lo general, no es muy efectivo, especialmente cuando se implementa de manera débil (vea mi segundo párrafo), y tiene un impacto suficiente en el rendimiento que no se usa normalmente, excepto de manera selectiva en lugares donde la desaceleración no es un gran problema. La ofuscación en general es una no solución; en el mejor de los casos, ralentiza la ingeniería inversa lo suficiente para que, para cuando se complete el RE, la base de código sea lo suficientemente antigua, a nadie le importe, sin que se produzcan errores indebidos de rendimiento o lógica del programa. En la práctica, sin embargo, generalmente no es tan bueno.

    
respondido por el CBHacking 05.08.2016 - 22:04
fuente
1

No es útil

Eso realmente no hace un buen trabajo en ofuscar. Si verifica contra cadenas específicas, es probable que esas cadenas aparezcan en la RAM en algún momento (incluso durante el uso normal). Un atacante puede simplemente copiar las cadenas que encuentran en la memoria RAM de su programa, encontrar una colisión y reemplazar las partes correspondientes del código con la cadena que encontraron.

Es estúpido

Además, casi todas las razones para ofuscar el código son estúpidas, pero eso no es un punto.

No lo hagas

Lo que debería ver es que existe un riesgo de falla. Es decir, cuando se produce una colisión hash. Debido a la forma en que están diseñadas las funciones hash, para cálculos probabilísticos podemos asumir que la salida de la función hash es aleatoria para cada entrada que aún no hemos probado.

Si hay varios valores hash con los que se compara el hash de una cadena variable, puede calcular la tasa de error para esa comparación utilizando la fórmula aproximada de la paradoja de cumpleaños enlace donde enlace es el número de valores diferentes que tomará la cadena variable.

Una vez que tenga esa probabilidad para cada comparación de cadenas en su programa, multiplíquelas y llame al número que obtiene enlace . La probabilidad de que el programa falle es enlace . Si el programa se ejecutará enlace veces de esa manera, la probabilidad de que falle es enlace .

Si valora la pequeña cantidad de ofuscación más de lo que teme las consecuencias de que su programa falle, con la probabilidad de un , hazlo. De lo contrario no.

    
respondido por el UTF-8 05.08.2016 - 22:38
fuente

Lea otras preguntas en las etiquetas