You are on page 1of 33

Programación Segura

Javier Fernández-Sanguino Peña

Curso de Verano: ”Administración y seguridad en entornos


GNU/Linux”

jfs () Programación Segura 6 de junio 2006 1 / 31


Estructura de la charla

1 ¿Qué es la programación segura?

2 Problemas frecuentes de seguridad en programas

3 Conclusiones

4 Referencias

jfs () Programación Segura 6 de junio 2006 2 / 31


1 ¿Qué es la programación segura?

jfs () Programación Segura 6 de junio 2006 3 / 31


Definiciones
Programación segura
Es la arquitectura, diseño y desarrollo de programas que siguen unos
principios básicos con el objetivo de reducir la existencia de problemas
de seguridad en su código y garantizar los principios básicos de
seguridad.

Vulnerabilidad
Un error en un sistema que permite violar la polı́tica de seguridad
definida.

Ataque
(o exploit) el aprovechamiento de una vulnerabilidad para violar una
polı́tica de seguridad (en inglés puede referirse al hecho o a la
herramienta)

jfs () Programación Segura 6 de junio 2006 4 / 31


Conceptos básicos aplicables

Confidencialidad

Integridad

Disponibilidad

jfs () Programación Segura 6 de junio 2006 5 / 31


Conceptos básicos aplicables (II)

Todos los programas tienen erratas


Los problemas de seguridad (vulnerabilidades) son un tipo de
errata
Análisis relalizado por Coverity: 0.3 vulnerabilidades por cada
100.000 lı́neas de código en FLOSS

Vulnerabilidades
Existen distintos tipos y con distintos niveles de riesgo (CVVS):
Aprovechamiento: remoto vs. local
Consecuencias: Denegación de servicio vs. ejecución de código

Variación de las vulnerabilidades en el tiempo


Nuevos tipos...

jfs () Programación Segura 6 de junio 2006 6 / 31


La ventana de vulnerabilidad

jfs () Programación Segura 6 de junio 2006 7 / 31


Ciclo de vida de las vulnerabilidades

Evolución de una vulnerabilidad


Alguien descubre una vulnerabilidad
La vulnerabilidad se pone en conocimiento de los desarrolladores
Se desarrolla un parche para la vulnerabilidad
Se publica un parche
Los usuarios del programa aplican el parche

Otros eventos
Alguien desarrolla un ataque
Se publica un ataque
Se desarrollan herramientas automatizadas que utilizan el ataque
Los sistemas que utilizan ese programa quedan comprometidos

jfs () Programación Segura 6 de junio 2006 8 / 31


Principios básicos del desarrollo seguro
Diseño simple: más fácil de depurar y auditar..
Diseño abierto: la seguridad del programa no puede depende de
que su código esté escondido, seguridad por oscuridad...
Separación de privilegios: mı́nimo privilegio, modularidad,
resistente a escalada...
Control de acceso apropiado: controles cómodos, sesiones...
Valores seguros por omisión: instalación bastionada, sin
contraseñas por omisión, limitado en funciones...
Gestión apropiada de fallos: deben verificarse los errores
producidos, auto-limitación de recursos, degradación de forma
segura, contención de fallos...
Múltiples capas de defensa: defensa en profundidad...
Reutilización de código: el código testado y probado es más
seguro, no es fácil implementar funciones criptográficas o
algoritmos de control autenticación...
jfs () Programación Segura 6 de junio 2006 9 / 31
La seguridad en el ciclo de desarrollo
La seguridad debe estar incluı́da en el ciclo de vida de un
programa

Arreglar problemas de seguridad lo antes posible


Menor coste para arreglar el mismo problema
Mejor RdI

jfs () Programación Segura 6 de junio 2006 10 / 31


2 Problemas frecuentes de seguridad en programas
Programas: abstracción y simplificación
Vulnerabilidades comunes
Ejemplos de código

jfs () Programación Segura 6 de junio 2006 11 / 31


Concepción abstracta

Visualización abstracta de un programa

jfs () Programación Segura 6 de junio 2006 12 / 31


Concepción abstracta

Problemas potenciales de seguridad

jfs () Programación Segura 6 de junio 2006 12 / 31


Concepción abstracta

Consecuencias de un aprovechamiento

jfs () Programación Segura 6 de junio 2006 12 / 31


Problemas más frecuentes

Las vulnerabilidades más frecuentes varı́an en función del tipo de


aplicaciones analizadas pero es habitual encontrar problemas:

Derivados del tratamiento de la entrada


Problema de implementación (filtrado)
Se da en todos los lenguajes
Con consecuencias muy peligrosas: ejecución de código

Derivados de la implementación errónea de la salida


Exceso de información al usuario
Habilitación de información de error

jfs () Programación Segura 6 de junio 2006 13 / 31


Problemas más frecuentes (II)

Derivados de errores de codificación


Errores de implementación en la lógica del programa
Difı́ciles de detectar

Derivados de errores de diseño


Habilitación de funciones no necesarias
Excesivos privilegios para un programa o el usuario que lo ejecuta

jfs () Programación Segura 6 de junio 2006 14 / 31


Distribución de vulnerabilidades
Vulnerabilidades publicadas de la distribución Debian
GNU/Linux
Sobrecarga de búfer: 26,9 %
Gestión incorrecta de la entrada: 26,3 %
Problemas de diseño: 18,2 %
Tratamiento de condiciones excepcionales: 7,4 %
Condiciones de frontera: 5,7 %
Validación de acceso: 5,6 %
Sin clasificar: 3,9 %
Condiciones de carrera: 2,8 %
Aprox. 65 % aprovechables de forma remota (datos de 1998-2006,
1369 vulnerabilidades arregladas a través de parches)

Los problemas más comúnes están asociados al tratamiento de


la entrada
jfs () Programación Segura 6 de junio 2006 15 / 31
Ejemplo en C: sobrecarga e inyección
(...)
static char cmd[128];
static char format[] = "which %s\n";
(...)
int main(int argc, char *argv[])
{
char buf[10];
(....)
printf ("Which command?: ");
gets(buf);
sprintf(cmd, format, buf);
printf("You are looking for:\n");
system(cmd);
exit(0);
}

¿Cuántos problemas puedes detectar?


jfs () Programación Segura 6 de junio 2006 16 / 31
Ejemplo en C: sobrecarga e inyección (II)

Errores
Fijada de antemano el tamaño máximo de entrada: sobrecarga
Falta de validación de entrada: inyección de código

Consecuencias
Ejecución de código en el sistema operativo
Si fuera un demonio o servicio, con los priviliegios del usuario que
lo ejecuta

jfs () Programación Segura 6 de junio 2006 17 / 31


Ejemplo en Java: error de codificación e inyección
private static boolean check_user (String username, String
(...)
bAuthenticated = true;
try {
UserRecord urecord = fetch_user(username);
if ( password != urecord.password ) {
bAuthenticated = false;
print_to_user("Contraseña incorrecta");
}
if ( urecord.locked == true ) {
bAuthenticated = false;
print_to_user("Usuario bloqueado");
}
(...)
if ( urecord == null ) { print_to_user("El usuario
}
catch { // hacer gestión de errores, pero continuar }
(...)
return bAuthenticated;
} jfs () Programación Segura 6 de junio 2006 18 / 31
Ejemplo en Java: error de codificación e inyección (II)
private static UserRecord fech_user (String username) {
UserRecord record = null; String query = null;
try {
query = "SELECT password FROM users WHERE ";
query = query + "username = ’" + username + "’";
Statement stmt = con.createStatement ();
ResultSet rs = stmt.executeQuery (query);
record = retrieve_record(rs);
(...)
}
catch (SQLException ex) {
print_to_user("Error: " + ex.getMesssage());
print_to_user ("Codigo: "+ ex.getErrorCode ());
}
return record; }

¿Cuántos problemas puedes detectar?

Fuente: OWASP Testing Guide, v2.1


jfs () Programación Segura 6 de junio 2006 19 / 31
Ejemplo en Java: error de codificación e inyección (III)
Errores
La lógica del código no es correcta: se asume un usuario
autenticado (¿qué pasa con una excepción?)
Falta de validación de entrada: inyección en BBDD
Falta de validación de salida: se devuelve información sensible al
usuario
Exceso de información de salida: es posible enumerar usuarios y
atacar por fuerza bruta las contraseñas.

Consecuencias
Obtención de información sensible
Malversación del acceso a la aplicación
Ejecución de código en la BBDD con los priviliegios de la
aplicación

jfs () Programación Segura 6 de junio 2006 20 / 31


3 Conclusiones

jfs () Programación Segura 6 de junio 2006 21 / 31


Conclusiones finales

Gran parte de las vulnerabilidades en el software se deben a


errores de implementación

La explotación de vulnerabilidades tiene graves consecuencias

Es necesario aprender a programa de forma segura


Requiere aprendizaje y conocimiento de vulnerabilidades habituales
para evitarlas.

jfs () Programación Segura 6 de junio 2006 22 / 31


¿PREGUNTAS?

jfs () Programación Segura 6 de junio 2006 23 / 31


¡GRACIAS!

jfs () Programación Segura 6 de junio 2006 24 / 31


4 Referencias
Más ejemplos

jfs () Programación Segura 6 de junio 2006 25 / 31


Documentación adicional - libros

Libros
Practical Unix Security: Simon Garfinkel and Gene Spafford. ISBN
0-596-00323-4
Secure Coding, Principles and Practices: Mark Graff and Kenneth
R.van Wyk. ISBN: 0-596-00242-4
Secure Programming for Linux and Unix HOWTO: David Wheeler,
http://www.dwheeler.com/secure-programs/
A Guide to Building Secure Web Application and Web Services,
proyecto OWASP,
http://www.owasp.org/documentation/guide.html

jfs () Programación Segura 6 de junio 2006 26 / 31


Documentación adicional - Cursos

Cursos
Dan Bernstein’s UNIX Security Holes Course, Dan Bernstein:
http://cr.yp.to/2004-494.html
Secure Programming Educational Material, Universidad de
Purdue: http://projects.cerias.purdue.edu/secprog/
Programming Secure Applications for Unix-like systems, David A.
Wheeler: http:/www.dwheeler.com/secure-programs

jfs () Programación Segura 6 de junio 2006 27 / 31


Sitios web

Portales de referencia
Build Security In, http://buildsecurityin.us-cert.gov/
Taxonomoy of Coding Errors, Fortify:
http://vulncat.fortifysoftware.com/
OWASP, http://www.owasp.org/

Información de vulnerabilidades
CVE, http://cve.mitre.org/
Bugtraq,
http://www.securityfocus.com/vulnerabilities
NVD (antiguo ICAT), http://nvd.nist.gov/

jfs () Programación Segura 6 de junio 2006 28 / 31


Más ejemplos en C: hello-insecure y multiple-bugs.c

Programas de ejemplo con vulnerabilidades


Disponibles en http://people.debian.org/j̃fs/debconf6/security/samples/

Hello-insecure
Demonio que responde a conexiones al puerto 1025
Con errores de seguridad introducidos a propósito

multiple-bugs.c
Aplicación que busca una orden el sistema
Múltiples errores de seguridad introducidos a propósito

¿Cuántos problemas puedes detectar?

jfs () Programación Segura 6 de junio 2006 29 / 31


Hello-insecure

Errores de diseño: ejecuta como superusuario, activa un


programa de depuración accesible desde cualquier interfaz.
Errores de implementación:
I Programa de instalación: mala utilización de /tmp
I Programa servidor: sobrecarga de búfer, errores de cadenas,
registros en /tmp y denegación de servicio
Errores de distribución: -DDEBUG?

jfs () Programación Segura 6 de junio 2006 30 / 31


Multiple-bugs

Errores de implementación:
Sobrecarga de búfer: getenv() con sprintf()
Error de diseño: ficheros de registro en /tmp
Condiciones de carrera: uso de fopen()
Sobrecarga de stack: gets()
Sobrecarga de búfer por utilización de búfer estático: sprintf()
Sobrecarga de cadena de formato: syslog()
Inyección de código: system()

jfs () Programación Segura 6 de junio 2006 31 / 31

You might also like