Entendiendo y haciendo Inyección de Código en C

Estoy un poco confundido en la idea de la inyección de código en C. Si alguien pudiera explicarlo y mostrar cómo está hecho, lo apreciaría.

Así que digamos que en C tienes una matriz Char de tamaño 512 que se está escribiendo en el contenido de un socket de longitud 1024, y que la matriz char ahora tiene algún tipo de código pero solo la mitad de lo que se escribió.

¿Cómo se ejecuta el código malicioso en un desbordamiento de búfer? Creo que estoy confundido en la estructura del proceso (stack, montón, datos, texto).

El truco general tiene que ver con cómo el código y las variables del progtwig se distribuyen en la memoria. Por ejemplo, cuando se llama a una función, el progtwig (código insertado por el comstackdor) debe almacenar la dirección de la instrucción para regresar. Entonces, si esta es la palabra de 32 bits justo antes del comienzo de la stack, uno podría hacer:

void foo() { int array[5]; int var = 0; int var2 = 0; // read in user input printf("Enter index and value to write:"); scanf("%i", var); scanf("%i", var2); // malicious user might set var to -1 and var2 to an address to execute // if say the 32-bit value before the stack variables is the instruction to // return to array[var] = var2 // return now goes to malicious code } 

(Entonces, su trabajo es construir un código para que tal cosa no sea posible. :))

Las reglas sobre cómo se implementa una llamada de función, las variables de stack asignadas, los valores pasados ​​y los valores devueltos devueltos se denominan la convención de llamada . Recomiendo leer el artículo adjunto para una buena cobertura en profundidad de las convenciones de llamadas de C.

Si asigna un búfer en la stack y se desborda, se escribe en la stack. La stack contiene el puntero de retorno para la función que asignó el búfer. Por lo tanto, si desborda un búfer en la stack, puede establecer el puntero de retorno en algo arbitrario; por lo que le da el control del hilo de ejecución.

En cuanto a inyectar realmente el código, eso depende. La stack, o más bien la página que la contiene, a menudo se configura para no permitir la ejecución de código; pero históricamente habría sido posible almacenar pequeños progtwigs maliciosos en el búfer en la stack. La progtwigción orientada hacia el retorno es una variante bastante nueva del ataque de retorno a libc , que funcionan alrededor de los bits NX.

Una stack típica para cada subrutina podría verse así:

  • parámetros (valores que se pasaron como parámetros a esta subrutina)
  • Dirección de retorno (dirección del código desde el que se llamó esta rutina)
  • valores de registro guardados
  • variables locales

Si una subrutina tiene una variable local, y de alguna manera escribe más allá del final de la variable local, entonces sobrescribe los valores (en la stack) como la dirección de retorno, es decir, la dirección del código que se ejecutará al final de la subrutina cuando La subrutina hace un “retorno”.