Reino: API Abuse

Un API es un contrato entre un autor de llamada y un receptor de llamada. Las formas de abuso de API más comunes los produce el autor de llamada cuando no consigue atender su fin de este contrato. Por ejemplo, si un programa no consigue llamar chdir() después de llamar chroot(), se viola el contrato que especifica cómo cambiar el directorio de origen activo de una forma segura. Otro buen ejemplo de un abuso de manual es esperar que el receptor devuelva una información de DNS de confianza al autor de llamada. En este caso, el autor de llamada abusa el API del receptor haciendo determinadas suposiciones sobre su comportamiento (que el valor de retorno se puede usar con fines de autenticación). También se puede violar el contrato entre el autor de llamada y el receptor desde el otro lado. Por ejemplo, si un codificador envía SecureRandom y devuelve un valor no aleatorio, se viola el contrato.

Directory Restriction

Abstract
El uso inadecuado del sistema chroot() podría permitir a los usuarios malintencionados escapar de un aprisionamiento chroot.
Explanation
La llamada al sistema chroot() permite a un proceso cambiar su percepción del directorio raíz del sistema de procesamiento de archivos. Después de llamar correctamente a chroot(), un proceso no puede acceder a ningún archivo que se encuentre fuera del árbol de directorios definido por el nuevo directorio raíz. Un entorno de este tipo recibe el nombre de aprisionamiento chroot y se utiliza normalmente para impedir la posibilidad de que los procesos puedan subvertirse y usarse para obtener acceso a archivos no autorizados. Por ejemplo, muchos servidores FTP se ejecutan en aprisionamientos chroot para impedir que un usuario malintencionado que descubra una nueva vulnerabilidad en el servidor descargue el archivo de contraseñas u otros archivos confidenciales del sistema.

El uso inadecuado de chroot() puede permitir a los usuarios malintencionados escaparse del aprisionamiento chroot. La función chroot() no cambia el directorio de trabajo actual del proceso, por lo que las rutas relativas aún pueden hacer referencia a los recursos del sistema de archivos que se encuentran fuera del aprisionamiento chroot una vez que se haya llamado a chroot().

Ejemplo 1: tenga en cuenta el siguiente código de origen de un (hipotético) servidor FTP:


chroot("/var/ftproot");
...
fgets(filename, sizeof(filename), network);
localfile = fopen(filename, "r");
while ((len = fread(buf, 1, sizeof(buf), localfile)) != EOF) {
fwrite(buf, 1, sizeof(buf), network);
}
fclose(localfile);


Este código se encarga de leer un nombre de archivo de la red, abriendo el archivo correspondiente en el equipo local y enviando el contenido a través de la red. Este código se puede utilizar para implementar el comando GET de FTP. El servidor FTP llama a chroot() en sus rutinas de inicialización en un intento de impedir el acceso a los archivos ubicados fuera de /var/ftproot. Sin embargo, como el servidor no cambia el directorio de trabajo actual llamando a chdir("/"), un usuario malintencionado podría solicitar el archivo "../../../../../etc/passwd" y obtener una copia del archivo de contraseña del sistema.
References
[1] J. Viega, G. McGraw Building Secure Software Addison-Wesley
[2] A. Chuvakin Using Chroot Securely
desc.semantic.cpp.directory_restriction