¿La inicialización de la variable a NULL o 0 o -1 es una mala práctica desde el punto de vista de la seguridad?

7

Estoy tratando de aprender un poco sobre la aplicación de blindaje contra la ingeniería inversa. En un artículo leí que inicializar variables a NULL o 0 o -1 es tan seguro (vs RE) como usar contraseñas comunes en las aplicaciones. En resumen, se dice que deberíamos usar RNG para producir datos aleatorios que inicialmente "almacenamos" en nuevas variables declaradas. Otro enfoque sería utilizando el operador XOR. Desafortunadamente, olvidé marcar este artículo y no tuve tiempo de leerlo todo.

La pregunta sería: ¿es cierto que si utilizamos datos aleatorios y / o un operador XOR al inicializar las variables, agregaremos la defensa de la aplicación contra la ingeniería inversa?

EDITAR: Parece que mi pregunta no fue lo suficientemente clara. Lo que pregunto es cuál es mejor (o no hay ninguna diferencia)

  • int variable = 0;

o

  • int variable = random(seed);

Supongamos que, por el bien de la pregunta, random(seed) es en verdad una aleatoriedad.

Sobre el operador XOR. Como dije solo leí parcialmente el artículo. Vi dos párrafos, uno llamado algo como "Usar generador de números aleatorios" y el otro "Usar XOR para inicializar variables". El uso de XOR no está claro para mí y solo lo menciono aquí para llamar la atención si alguien sabe algo más sobre él.

    
pregunta StupidOne 05.08.2013 - 22:28
fuente

3 respuestas

3

Parece que estás mezclando dos objetivos de seguridad: protección del código contra ingeniería inversa y protección de la aplicación contra ataques. Estos objetivos son a menudo contradictorios: las protecciones contra la ingeniería inversa aumentan la complejidad del código y, por lo tanto, hacen que sea más probable que el código sea vulnerable a los ataques porque se comporta de manera inesperada en ciertas circunstancias.

Caso en cuestión: si inicializa variables a valores aleatorios, es más difícil determinar cuándo se realiza una ingeniería inversa que un bloque de memoria no está inicializado. Por otro lado, el rastreo de llamadas al RNG mostrará dónde se están inicializando las variables. Por lo tanto, no hay beneficios de inicializar variables a valores aleatorios.

Cuando se trata de seguridad, inicializar variables a valores aleatorios es malo. Los ceros son mucho más seguros. Si resulta que la variable se usa sin inicializarse, un cero a menudo es menos dañino: puede verificar si el valor no es 0, y si es un puntero, dará lugar a una caída limpia. Primera vez que está desreferenciado. Por el contrario, un valor aleatorio llevaría a un comportamiento impredecible, un posible agujero de seguridad.

Proteger contra la ingeniería inversa es tan costoso (porque la depuración es más difícil que la programación, y eso se duplica) es extremadamente raro que valga la pena. Si ha determinado que necesita dedicar esfuerzos a la ofuscación, probablemente subestime la dificultad. Si elige ofuscar de todos modos, la inicialización de variables a valores aleatorios no es una técnica muy útil, porque es fácil ver en el análisis estático o dinámico que los valores aleatorios no se usan de todos modos. La ofuscación requeriría que utilices los valores aleatorios para realizar cálculos, pero que el resultado final no dependa del valor.

Desde el punto de vista de seguridad , inicializar variables a NULL, 0 u otro valor seguro y reproducible es una buena práctica.

    
respondido por el Gilles 07.08.2013 - 02:48
fuente
10

En muchos lenguajes de programación, la inicialización de las variables locales es forzada, o el motor se negará rotundamente a leer datos sin inicializar. Incluso en los idiomas en los que puede leer variables sin inicializar y así obtener una copia de lo que quedó en la RAM en ese emplazamiento, no puede contar con que sea "aleatorio"; Tendrá una tendencia a contener siempre el mismo valor, dependiendo de lo que hizo la aplicación anteriormente. De hecho, en C, las variables locales son de la pila y / o almacenadas en caché en los registros de la CPU, y estos son recursos que se reutilizan constantemente en toda la aplicación.

Si el artículo que lees recomienda no inicializar la variable local, y luego para leerlos, y esperan que esto genere "aleatoriedad" , entonces este artículo será quemado a la estaca, por muchas razones:

  • La lectura de datos no inicializados es una clara violación de las especificaciones; en el estándar de lenguaje de programación C, esto se denomina "comportamiento indefinido" y puede producir resultados problemáticos, incluido un bloqueo de la aplicación o, lo que es peor, corrupción de memoria silenciosa.

  • Este tipo de aleatoriedad no será bueno, por cualquier concepto de "aleatoriedad" del que valga la pena hablar.

  • El comportamiento reproducible es bueno . Al tratar de obtener valores no reproducibles a partir de variables locales, el artículo simplemente promueve la imposibilidad de depurar el código, que solo se puede describir como una cosa estúpida y sangrienta por hacer . En particular por la seguridad. Esto casi garantizará la presencia de agujeros de seguridad duraderos y difíciles de detectar.

Si desea aleatoriedad, use lo que proporciona el sistema operativo, por ejemplo. %código%. Es incomparablemente mejor, desde todos los puntos de vista, que los rituales caseros irracionales destinados a propiciar a los dioses de la aleatoriedad.

Editar: Como señala @TerryChia, su pregunta podría ser sobre forzar una inicialización aleatoria de variables (locales o no) desde un PRNG, en lugar de dejar el valor predeterminado valor allí (si hay hay un valor predeterminado, por supuesto; en muchos lenguajes de programación, las variables locales no tienen ningún valor predeterminado). Lo que llamas "XOR" en ese contexto no está claro.

En ese caso, tampoco lee las variables antes de almacenar un valor significativo en ellas, en cuyo caso lo que las variables inicialmente contenían es completamente irrelevante: no afecta el comportamiento de su código. O bien, do lee las variables y luego obtiene estos valores aleatorios más o menos, lo que hace que el código de la aplicación no sea reproducible y provoque los problemas explicados anteriormente; a saber, que el código será difícil de depurar, lo que aumenta la probabilidad y la densidad de las vulnerabilidades reales.

    
respondido por el Thomas Pornin 05.08.2013 - 22:49
fuente
2

Inicializar variables proporciona un comportamiento consistente. Debe usar un RNG que sea suficientemente aleatorio por sí mismo. XORIAR su salida aleatoria con lo que sea que esté en esa ubicación de memoria de manera realista no debería proporcionar ningún beneficio.

En general, no se recomienda confiar en una solución de este tipo para aumentar la aleatoriedad de un valor.

Pero tenga cuidado de no romper las cosas al corregirlas .

    
respondido por el tylerl 05.08.2013 - 22:40
fuente

Lea otras preguntas en las etiquetas