Los desbordamientos del búfer son grandes. Nada en C se verifica por rango de forma predeterminada, por lo que es muy fácil sobrescribir un búfer. Hay una función de biblioteca estándar gets()
, que no se puede evitar que desborde el búfer, y casi nunca se debe usar.
Existen algunas técnicas de nivel de implementación para impedir la explotación, como codificar bloques de almacenamiento dinámico, pero eso no detendrá el desbordamiento del búfer en los búferes locales, que a menudo pueden hacer cosas interesantes como cambiar la dirección a la que volverá una función.
No hay una buena solución general en C. Muchas funciones de la biblioteca tienen versiones que limitarán la cantidad que escribirán. aunque calcular eso puede ser torpe. Hay un software que puede detectar desbordamientos del búfer de almacenamiento dinámico en la prueba, siempre que se ejecute la prueba adecuada, y el desbordamiento de la pila a menudo aparecerá como un bloqueo en la prueba. Aparte de eso, es una cuestión de codificación cuidadosa y revisión de código.
Un problema relacionado es el problema de escribir en un búfer demasiado pequeño por un carácter, olvidando que una cadena C que tiene una longitud de n caracteres requiere n + 1 caracteres en la memoria, debido al '\0'
terminador. Si el atacante puede almacenar una cadena sin el terminador, cualquier función de C que espere una cadena continuará procesándose hasta que llegue a un byte cero, lo que podría resultar en copiar o generar más información de la deseada (o golpear la memoria protegida para un ataque de DOS ) La solución, nuevamente, es la concientización, la atención y las revisiones de código.
Hay otro riesgo con la printf()
familia. Si alguna vez escribe char * str; ... printf(str);
, se está preparando para problemas si str
contiene un '%' cuando se imprime. La %n
directiva de formato permite printf()
escribir en la memoria. La solución es printf("%s", str);
o puts(str);
. (Además, use el C99 en snprintf()
lugar de sprintf()
).
El uso de enteros sin signo, particularmente como índices de bucle, puede causar problemas. Si asigna un pequeño valor negativo a un sin signo, obtendrá un gran valor positivo. Eso puede socavar cosas como procesar solo N instancias de algo, o en funciones limitadas como strncpy()
. Examine todos los enteros sin signo. Es posible que desee evitar unsigned short
, ya que un valor grande en uno de esos se convertirá en un valor positivo grande en un int
.
No olvides que un carácter constante, en C, es en realidad un int
. Escribir algo así char c; while((c = getchar()) != EOF) ...
puede fallar fácilmente, ya EOF
que no será representable en a char
.
Hay muchos más errores característicos de C en los que puedo pensar, pero estos podrían causar problemas de seguridad.