ClickCease Los errores detrás de las vulnerabilidades - Parte 2

Tabla de contenidos

Únase a nuestro popular boletín

Únase a más de 4.500 profesionales de Linux y el código abierto.

2 veces al mes. Sin spam.

Los errores detrás de las vulnerabilidades - Parte 2

Joao Correia

14 de noviembre de 2022 - Evangelista técnico

Seguimos analizando los problemas de código que causan las vulnerabilidades que afectan al mundo de las TI. En esta entrega de nuestra serie de blogs de cinco partes que exploran estos fallos, repasamos los fallos del nº 20 al nº 16 en el Mitre CWE Top 25 para 2022, proporcionando contexto e información adicional sobre los problemas de código reales que conducen a vulnerabilidades en aplicaciones y sistemas en general.

Puede consultar la entrada anterior de esta serie aquí.

20 - Permisos por defecto incorrectos

Esta clase de fallos proviene de la forma en que se preparan los paquetes de software -ya sea a nivel de sistema operativo o de aplicación- incluyendo permisos para un subconjunto de elementos demasiado amplio. Por lo general, esto se refiere a archivos ejecutables que tienen permisos que permiten a usuarios sin privilegios ejecutar dichos archivos cuando no deberían poder hacerlo o que dichos archivos se ejecuten con tales privilegios que puedan manipular otros componentes del sistema de forma no intencionada.

También puede ocurrir al revés: tener un permiso en un archivo ejecutable que sea demasiado restrictivo, y que luego el sistema operativo encuentre automáticamente una alternativa ubicada en una ubicación controlada por el atacante (en lugar del componente incluido en el paquete original).

El principal riesgo es que estos por defecto por lo que, en cuanto se despliegue el paquete, estará inmediatamente en peligro sin necesidad de realizar ninguna otra acción. Esto desplaza el vector de riesgo de uso a despliegue.

19 - Restricción Indebida de Operaciones dentro de los Límites de un Buffer de Memoria

Normalmente denominada "desbordamiento de búfer" o "desbordamiento de búfer", esta anomalía intenta leer una posición en memoria fuera del espacio preestablecido para una variable determinada, o escribir en dicha posición. 

Esto puede ocurrir bien pasando intencionadamente una posición de memoria que quede fuera del buffer o bien utilizando el resultado de una operación como posición a leer/escribir sin validar si es aceptable o no en el contexto dado.

Tomemos el siguiente ejemplo:


int main (int argc, char **argv) {

char *items[] = {"A", "B", "C", "D"};

int index = AskUserForIndex();

printf("You selected %s\n", items[index-1]);

}

(Ejemplo de código adaptado del presente en https://cwe.mitre.org/data/definitions/119.html)

En este ejemplo, si el usuario introduce "5" como índice, el programa cumplirá felizmente y devolverá el contenido de una posición de memoria fuera del array. Dependiendo del sistema operativo y de la arquitectura de memoria, pueden ocurrir varias cosas: que se devuelvan valores de memoria fuera del espacio del programa, que el programa se cuelgue, que otro programa se cuelgue (si se produce una escritura), que el estado del sistema se vea comprometido, o que nada se cuelgue y se repita el ataque. Es posible leer grandes cantidades de memoria repitiendo el proceso con diferentes valores de índice.

Esta clase de bugs puede crear problemas al leer, pero también al escribir valores en un buffer - escribiendo más datos de los que el buffer fue creado para acomodar. Si la región de memoria justo después del búfer contiene una bandera que indica si el usuario tiene privilegios o no, un simple cambio de byte podría convertir a un usuario normal en un administrador.

Aunque este tipo de error de código suele enseñarse en las clases de programación, así como la forma de evitarlo colocando comprobaciones antes de cualquier acceso a la memoria, a veces no es obvio dónde se produce el problema en primer lugar. Las herramientas de análisis estático del código, la revisión por pares y la programación en parejas son formas de intentar detectarlas antes de que lleguen al código de producción.

Otro concepto relacionado en programación es el "canario" (análogo a un canario en una mina de carbón), donde se escribe un valor justo después del búfer y luego se comprueba su presencia después de escribir un valor en el búfer. Si el valor original ya no está ahí, el programador puede asumir que se ha producido un desbordamiento del búfer y bloquear intencionadamente la aplicación para evitar daños mayores o solucionarlo alertando al usuario o mediante algún otro mecanismo. Aunque es útil, los atacantes astutos pueden evitarlo incluyendo el valor canario como parte del nuevo valor para no activarlo.

18 - Falta de autenticación para una función crítica

Cualquier característica que cambie la funcionalidad debe validar si el actor que realiza la acción está autorizado a hacerlo o no, e impedir la acción cuando el actor no esté autorizado a hacerlo. Cuando una aplicación no valida esto, entonces entra en esta categoría.

Las aplicaciones suelen realizar tareas como añadir, eliminar, modificar o borrar datos, usuarios o conexiones. Basta con que falte una de esas acciones, como una comprobación de autenticación para toda la aplicación, para que ésta se vea comprometida o no sea fiable. Y en cada una de esas operaciones intervienen varios pasos, por lo que lo ideal sería que la validación se produjera en cada paso o, en su defecto, en los puntos de entrada de cada proceso.

Otro ejemplo típico es la falta de comprobaciones de autenticación en el almacenamiento basado en la nube (es decir, "buckets S3 con fugas"), donde accidentalmente se almacenan datos confidenciales de forma accesible al público.

17 - Neutralización Indebida de Elementos Especiales utilizados en un Mando

Siempre que una aplicación acepta una entrada y luego la ejecuta, si no se comprueba adecuadamente, podría contener comandos, parámetros o banderas adicionales que modifiquen su propósito previsto. 

Si se supone que una aplicación del sistema debe ejecutar un comando con un parámetro proporcionado por el usuario, un usuario astuto podría incluir un carácter de terminación de comando seguido de un comando diferente que se ejecutaría con el mismo nivel de privilegio que el programa original. Este tipo de problemas están estrechamente relacionados con los fallos de "inyección SQL" y "control inadecuado del código generado", ya que todos proceden de la confianza implícita en las entradas. 

El origen del problema suele estar en el nivel arquitectónico, donde las cuestiones de seguridad no se tienen debidamente en cuenta, lo que introduce comportamientos inseguros en las aplicaciones. Como regla general, nunca debe confiarse en que una entrada sea buena, idealmente incluso a nivel de función individual, pero como mínimo a nivel de aplicación.

16 - Falta autorización

En el #18 vimos cómo partes de una aplicación podían omitir una comprobación de autenticación. En esta ocasión, veremos cómo la falta de autorización también puede causar problemas.

Es habitual que los sitios web protejan las secciones sensibles con mecanismos de autenticación, pero cada página individual tiene que aplicar esta comprobación a riesgo de que el acceso directo a una URL divulgue información que de otro modo sería inalcanzable. Esto se extiende a las descargas/cargas/consultas y no sólo a los accesos a páginas.

A nivel de aplicación tradicional, la falta de autorización se produce cuando se otorga una confianza implícita a un usuario o a una aplicación que llama desde el exterior. 

Al igual que el #17, el fallo suele tener su origen en la fase de arquitectura del desarrollo: no se tienen en cuenta las tácticas de seguridad adecuadas para aplicar mecanismos de control de acceso apropiados a todos los niveles. Identificar y luego corregir el código de una aplicación dada después de que se identifique este tipo de fallo suele conllevar una gran carga de trabajo, ya que el código necesita una amplia refactorización para estar debidamente protegido después del hecho.

A nivel del sistema operativo, este tipo de problema se produce cuando una herramienta no tiene asociada ninguna lista de control de acceso, lo que permite que cualquier usuario pueda ejecutarla.

 

Resumen
Los errores detrás de las vulnerabilidades - Parte 2
Nombre del artículo
Los errores detrás de las vulnerabilidades - Parte 2
Descripción
Seguimos analizando los fallos que causan las vulnerabilidades que afectan al mundo de las TI. Siga leyendo nuestra serie de blogs de cinco partes
Autor
Nombre del editor
TuxCare
Logotipo de la editorial

¿Desea automatizar la aplicación de parches de vulnerabilidad sin reiniciar el núcleo, dejar el sistema fuera de servicio o programar ventanas de mantenimiento?

Más información sobre Live Patching con TuxCare

Conviértete en escritor invitado de TuxCare

Empezar

Correo

Únete a

4,500

Profesionales de Linux y código abierto

Suscríbase a
nuestro boletín