Vulnerabilidades comunes de C

May 10 2022
Introducción El lenguaje de programación C es bien conocido por ser extremadamente susceptible en una variedad de formas. Incluso hoy en día, cuando a los estudiantes de programas de pregrado se les enseña a codificar, primero se les expone a los lenguajes de programación C o Java.
Foto de Chris Ried en Unsplash

Introducción

El lenguaje de programación C es bien conocido por ser extremadamente susceptible en una variedad de formas. Incluso hoy en día, cuando a los estudiantes de programas de pregrado se les enseña a codificar, primero se les expone a los lenguajes de programación C o Java. Python, Ruby y lenguajes de programación adicionales se agregarán más adelante. Pero, lo que es más importante, ¿se les enseña con las mejores prácticas en mente? Desafortunadamente, este no es el caso. Practican e implementan las mismas funcionalidades peligrosas, y los resultados de sus esfuerzos son evidentes en los proyectos que producen. El resultado es un ciclo interminable de errores y parches.

Como parte de este artículo de blog, nos gustaría presentar algunas de las funciones más utilizadas y vulnerables, junto con algunas vulnerabilidades que son inherentes al lenguaje de programación C.

obtiene()

La función gets() se usa para aceptar la entrada del usuario. Pero, ¿qué podría tener de malo aceptar la entrada de un usuario? Los programas requieren que los usuarios interactúen con ellos. Los ejemplos incluyen indicaciones de inicio de sesión, una calculadora simple, etc.

El problema surge porque gets() no realiza una verificación de límites, lo que significa que un usuario puede hacer que el programa acepte una cadena con un tamaño infinito. Esto puede provocar un ataque de desbordamiento de búfer al sobrescribir el área de la memoria y también provocar la ejecución del código.

Código C inseguro:

#include <stdio.h>
int main () 
{
 char str[50];
 printf("Enter a string : ");
 gets(str);
 printf("You entered: %s", str);
 return(0);
}

strcpy()

strcpy significa copia de cadena y se usa para copiar una cadena desde la fuente a la ubicación de destino.

La sintaxis es strcpy(dest, src). La cadena presente en el src se copiará en la variable dest.

Si se proporciona una cadena lo suficientemente grande al src, puede provocar un ataque de desbordamiento de búfer.

Código C inseguro:

#include <stdio.h>
#include <string.h>
int main() {
char src[20] = "C programming";
char dest[20];
// copying src to dest
strcpy(dest, src);
puts(dest); // C programming
return 0;
}

strcat()

La función strcat() se usa para agregar una cadena de origen a una cadena de destino. Sin embargo, al igual que las funciones mencionadas anteriormente, no verifica la longitud/límite. Esto puede conducir fácilmente a una falla de segmentación o un ataque de desbordamiento de búfer.

Programa C inseguro:

#include <stdio.h>
#include <string.h>
int main() {
char s1[100] = "This is an ", s2[] = "insecure implementation";
// strcat concatenates str1 and str2
// the resultant string is stored in str1.
strcat(s1, s2);
return 0;
}

strcmp()

strcmp significa comparación de cadenas. Esta función compara dos cadenas y devuelve un número entero basado en la comparación. El entero será menor, igual o mayor que 0, si el primer valor es menor, igual o mayor que el segundo valor.

strcmp() se puede usar fácilmente para causar ataques de desbordamiento de búfer. Todo lo que tiene que hacer un actor malicioso es proporcionar una cadena lo suficientemente grande como para que la variable realmente pueda contener.

Programa C vulnerable

#include <stdio.h>
#include <string.h>
int main() {
 char str1[20], str2[] = "abCd", str3[] = "abcd";
 int result;
 gets(str1);
 // comparing strings str1 and str2
 result = strcmp(str1, str2);
 printf("strcmp(str1, str2) = %d\n", result);
 // comparing strings str1 and str3
 result = strcmp(str1, str3);
 printf("strcmp(str1, str3) = %d\n", result);
return 0;
}

Vulnerabilidad de cadena de formato

El lenguaje C hace uso de especificadores de formato para aceptar e imprimir la entrada del usuario.

Por ejemplo, para imprimir un valor de tipo de fecha entero, puede utilizar el especificador de formato %d, %s para cadena, etc.

Por ejemplo

int x;
scanf(“%d”, x);
printf(“%d”,x);

Esto puede conducir a la fuga de datos, fallar el programa, escribir datos arbitrarios en ubicaciones arbitrarias. (Posible especificando el especificador de formato %n).

Programa C vulnerable:

#include<stdio.h>
int main(int argc, char* argv[])
{
printf(argv[1]);
return 0;
}

Por ejemplo, printf(“%s”,argv[1]);

Desbordamiento y subdesbordamiento de enteros

Los tipos de datos en la mayoría de los lenguajes de programación, incluido C, tienen un tamaño fijo. El tipo de datos int en C tiene un tamaño de 4 bytes. El rango dentro del cual una variable declarada como de tipo entero puede almacenar un valor estará entre -2,147,483,648 a 2,417,483,647.

Pero alguna vez pensó qué sucedería si almacena un valor superior a 2.417.483.647 o inferior a -2.417.483.648 o realiza una operación con números enteros y el resultado es superior a 2.417.483.647 o inferior a -2.417.483.648.

A ver, Programa C Vulnerable :

#include <stdio.h>
int main()
{
int x = 2147483649;    //2147483647 + 2
printf(“%d”,x);
return 0;
}

Es posible que haya esperado 2147483649 como salida, pero dado que está por encima del rango máximo del tipo de datos enteros, alcanzó el final -ve y agregó 1 a -2,147,483,648 .

Mitigación : utilice controles para asegurarse de que los valores no excedan el límite superior.

Conclusión:

Esta publicación de blog cubrió algunas de las vulnerabilidades que vienen con el lenguaje de programación C. Por supuesto, un desarrollador puede agregar vulnerabilidades mediante el uso de mala lógica, pero estas son algunas de las vulnerabilidades que siempre existirán en las funciones mencionadas. Debes asegurarte de que tus programas estén lo más alejados posible de estas funciones.

© Copyright 2021 - 2022 | unogogo.com | All Rights Reserved