Existen muchos riesgos de seguridad por tener un contacto cercano con el hardware en lugar de usar API bien probadas y probadas de lenguajes de programación de alto nivel. Es mucho más fácil causar un desbordamiento del búfer en C que en un lenguaje como Java.
¿Cuáles son los riesgos o vulnerabilidades (por ejemplo, desbordamientos de búfer) que todos los programadores de C deben tener en cuenta (vulnerabilidades de IE relevantes para los programadores de C)? ¿A qué problemas podrían conducir estos? ¿Cómo evitarlos y cuáles son los errores comunes que hacen que estos ocurran en los programas?
Respuestas:
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 escribechar * str; ... printf(str);
, se está preparando para problemas sistr
contiene un '%' cuando se imprime. La%n
directiva de formato permiteprintf()
escribir en la memoria. La solución esprintf("%s", str);
oputs(str);
. (Además, use el C99 ensnprintf()
lugar desprintf()
).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 evitarunsigned short
, ya que un valor grande en uno de esos se convertirá en un valor positivo grande en unint
.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, yaEOF
que no será representable en achar
.Hay muchos más errores característicos de C en los que puedo pensar, pero estos podrían causar problemas de seguridad.
fuente
printf("%s", str)
una cuerda desnuda cuandoputs(str)
haga el mismo trabajo.puts
agrega un carácter de nueva línea mientrasprintf
que no lo hace.fputs(str, stdout)
, que no lo hace.Algunos de los riesgos específicos de C incluyen: desbordamientos de búfer , formateo de ataques de cadena y desbordamientos de enteros .
fuente
Aquí hay un riesgo fácil de pasar por alto que puede causar problemas que llevará horas solucionar.
Considere el siguiente código, que se compilará sin problemas.
Cuando verifica si
lpstr_current_state
está dentroCONST_EMERGENCY_STATE_HOLY_CRAP
, en realidad está asignando. Es mejor poner siempre la variable constante a la izquierda. Cuando coloca la constante a la izquierda, el compilador fallará porque no puede asignar un valor a una variable.Entonces puedes decirte fácilmente a ti mismo: "Mierda, eso podría haber sido malo", mientras arreglas el código para leer ...
fuente
=
y==
.Solo hay un riesgo de seguridad: el hecho de que haya personas externas que harán todo lo posible para detectar cualquier vulnerabilidad en su software y explotarlo para su propio beneficio. Todo lo demás se sigue de allí.
Entonces, cuando piensas que "nadie en su sano juicio lo haría ...", entonces debes pensar de inmediato "excepto que alguien que quiera hackear las computadoras de otras personas haría exactamente eso".
La mayor consecuencia es que cada vez que reacciona a eventos externos (por ejemplo, procesando datos entregados desde el exterior), debe asumir que estos datos estaban bajo el control de su peor enemigo.
fuente