Seguridad En Programación

57
Seguridad en Programación vladimir dot calderon at gmail dot com (16 – mayo – 2009)

description

Una pequeña presentación sobre lo que se debería tomar en cuenta par ala programación en torno a la seguridad + bonus code exploit en fácil.

Transcript of Seguridad En Programación

Page 1: Seguridad En Programación

Seguridad en Programación

vladimir dot calderon at gmail dot com(16 – mayo – 2009)

Page 2: Seguridad En Programación

Programa

• SQL Injection– Presentación– Formas de evitarlo

• Code Exploits– Formas de evitarlo

• El menospreciado try-catch– Error más común

• Un ejemplo de todo el ensamblado en una CAD• Generación de código

Page 3: Seguridad En Programación

SQL INJECTION

Page 4: Seguridad En Programación

SQL Injection

• Un usuario solicita datos al gestor de la base de datos, generalmente indicando un criterio de selección

• Los datos son devueltos al usuario de acuerdo al criterio de selección colocado en la consulta Gestor de Base de Datos

Cliente/Usuario

Page 5: Seguridad En Programación

SQL : Tipos de comandos

Comandos DCL (Data Control Language Statements)

Cláusulas

Comandos DML (Data Manipulation Language Statements)

Comandos DDL (Data Definition Language Statements)

Operadores de Comparación

Page 6: Seguridad En Programación

SQL : Comandos Básicos

Comandos DDL (Data Definition Language Statements)

CREATE Utilizado para crear nuevas tablas, campos e índices.

DROP Empleado para eliminar tablas e índices.

ALTERUtilizado para modificar las tablas agregando campos o

cambiando la definición de los campos.

Comandos DCL (Data Control Language Statements)

GRANT Utilizado para otorgar permisos.

REVOKE Utilizado para revocar permisos.

DENY Utilizado para denegar acceso.

Page 7: Seguridad En Programación

SQL : Comandos Básicos

Comandos DML (Data Manipulation Language Statements)

SELECTUtilizado para consultar registros de una base de datos

que satisfagan un criterio determinado.

INSERTUtilizado para cargar lotes de datos en la base de datos

en una única posición.

UPDATEUtilizado para modificar los valores de los campos y

registros específicos.

DELETEUtilizado para eliminar registros de una tabla de base de

datos.

Page 8: Seguridad En Programación

SQL Injection

• SQL Injection es cuando se pueden introducir consultas SQL en los formularios de una aplicación en una consulta previamente establecida.

• Mediante SQL Injection se logra manipular la manera en que el programa responde normalmente.

Page 9: Seguridad En Programación

Por qué hablar de SQL Injection?

• Porque a pesar de que la técnica original tiene un par de años, aún hoy sigue siendo efectiva

• Porque el presente y parte del futuro de la seguridad informática se encuentra de una u otra forma relacionada con las aplicaciones web y los almacenes de datos.

• Porque en esencia es una técnica de intrusión sumamente sencilla, aspecto que la hace sumamente peligrosa.

Page 10: Seguridad En Programación

Esquema simplificado

Internet

Web Server

FirewallDatabase Server

Usuario/Intruso

Usuario/Intruso

App.Web

App.Web

App.Web

App.Web

Page 11: Seguridad En Programación

Típica página web

11

sql = “SELECT * FROM users WHERE username = '" + usuario + "' AND userpass = '" + clave + "' "

Page 12: Seguridad En Programación

Comilla Simple : Single Quote

• Si logramos que la consulta interprete un texto con solamente una comilla simple, tendremos:

• Lo cual concluye en un error de sintáxis SQL!

SELECT * FROM users WHERE username = ‘ ‘ ' AND userpass =‘xx123'

Page 13: Seguridad En Programación

Objetivos SQL Injection

• Identificar componentes dinámicos en el sitio web• Intentar formarse una idea de la estructura de la

aplicación

• Dónde encontramos posibles vulnerabilidades?– Páginas de Identificación y Autenticación de usuarios– Formularios de ingreso de datos– URIs / URLs en donde se lean valores / Variables

• En general es susceptible de ataque cualquier input del usuario

Page 14: Seguridad En Programación

Pasando la autenticación

• En las páginas de autentificación trataremos de:– Ingresar a zonas restringidas– Falsear un usuario estándar– Identificar a un posible administrador y utilizarlo

• Algunas opciones:

'or 1=1-- admin'-- 'OR''=''--

Page 15: Seguridad En Programación

Evadiendo la autenticación

• Por qué las opciones indicadas deberían funcionar?

SELECT * FROM users WHERE username = '' OR''=''-- AND userpass =''

SELECT * FROM users WHERE username = 'admin' -- AND userpass =''

'OR''=''--

admin'--

SELECT * FROM users WHERE username = '' or 1=1--' AND userpass =''

'or 1=1--

Page 16: Seguridad En Programación

Evitando SQL Injection

• Lo más importante de conocer un ataque es poder evitarlo.

• Dependiendo del lenguaje de programación utilizado se deben aplicar las técnicas correspondientes.

• En reglas generales, – Se DEBEN utilizar los métodos nativos del lenguaje para la

asignación de parámetros a consultas SQL– Se ACONSEJA utilizar procedimientos almacenados para todas

las consultas y manejo de la base de datos

Page 17: Seguridad En Programación

SQL Injection .vs. PHP

• Para leer datos numéricos o de un tipo definido (no para STRINGs)

<?php

settype($offset, 'integer');$consulta = "SELECT id, nombre FROM productos ";$consulta .= "LIMIT 20 OFFSET %d;";

// note el simbolo %d en la cadena de formato// usar %s no tendría sentido$consulta = sprintf($consulta, $offset);

?>

Page 18: Seguridad En Programación

SQL Injection .vs. PHP

• Para incluir las variables en consultas SQL estándar (select, update, insert, etc)

<?php

$query = "INSERT INTO usuarios(nombre,contr) VALUES('%s','%s');“;$consulta = sprintf($query, pg_escape_string($nombre_usuario), md5($contrasenya));$resultado = pg_query($conexion, $consulta);

$query = "SELECT 1 FROM usuarios WHERE nombre='%s' AND contr='%s';“;$consulta = sprintf($query, pg_escape_string($nombre_usuario), md5($contrasenya));$resultado = pg_query($conexion, $consulta);?>

Page 19: Seguridad En Programación

SQL Injection .vs. ASP.NET

• ASP.NET maneja esto de manera más transparente y haciendo uso de los objetos adecuados no debería tener problemas

string query="select * from Customers where city = @City“;SqlCommand cmd = new SqlCommand(query, conn);

SqlParameter param = new SqlParameter(); param.ParameterName = "@City"; param.Value = inputCity;

cmd.Parameters.Add(param); SqlDataReader reader = cmd.ExecuteReader();

Page 20: Seguridad En Programación

SQL Injection .vs. JAVA

• Similar a ASP.NET (más bien ASP.NET similar a JAVA):

String query = "Select favorita from comida where gato = ?“;

PreparedStatement preparedStatement = connection.prepareStatement(query); preparedStatement.setString(1, “mufasa");

ResultSet resultSet = preparedStatement.executeQuery();

while (resultSet.next()) { System.out.println(“La comida favorita de mufasa " + resultSet.getString(1)); }

Page 21: Seguridad En Programación

CODE EXPLOITS

Page 22: Seguridad En Programación

Qué es un exploit?

• Un exploit es explotar una vulnerabilidad en un programa.

• Por cada 1000 líneas de código es probable que existan entre 6 a 8 errores. (peer review)

• Siempre se podrán encontrar fallas en los programas de cualquier índole: Windows, Linux, Mac, etc.

• No depende del lenguaje tampoco.• Quiénes?

– Hackers, crackers, especialistas en seguridad informática

Page 23: Seguridad En Programación

Tipos de vulnerabilidades

• Buffer Overflow– Stack

• Integer Overflow• Format String• Cadenas sin terminación• SQL Injection• Cross Site Scripting• Manipulación de variables

Page 24: Seguridad En Programación

Algo de terminología

• ASR: Address Space Randomisation– Es cuando el sistema operativo está preparado para que las

funciones cargadas en el mismo se encuentren en direcciones de memoria que muy probablemente cambian cada vez que se reinicia la máquina

• Registros de CPU– Son los registros de la máquina que se utilizan para ejecutar los

procesos y mantener el estado del proceso en ejecución: próxima línea a ejecutar, dirección de retorno de la función, etc

Page 25: Seguridad En Programación

Un poco más de terminología

• Shellcode– Son simplemente comandos Assembler. Típicamente, se crean

programas que abran un shell o que ejecuten algún comando en particular.

• GDB– El debogueador de Linux, muy poderoso para encontrar

exactamente las direcciones de memoria en cualquier llamado

• GCC– Compilador de C/C++ que también compila assembler y otros

Page 26: Seguridad En Programación

Llamado a una función en C

• Ejemplo del assembler producido por un código vulnerable

Int main(int argc, char* argv[]){

char buffer[256];

if (argc != 2)

exit(1);

Page 27: Seguridad En Programación

Llamado a una función en C

• La continuación

strcpy(buffer, argv[1]);

return 0;

}

Page 28: Seguridad En Programación

Overflow y Memoria

• Cuando ocurre un Overflow, datos pasan a sobre escribir lugares donde hay código, por lo tanto se vuelven ejecutables. Para ver cómo ocurre esto hay que entender cómo funciona la memoria:

• Una página es una parte de la memoria con direccionamiento propio. El kernel asigna un espacio (páginas) de memoria para el proceso, esta memoria consta de 3 partes:– Segmento de Código: instrucciones assembler que el CPU ejecuta. EIP

es el registro que tiene la próxima línea a ejecutarse

– Segmento de Datos: Para variables y bufferes dinámicos

– Segmento de Pila: utilizado para pasar argumentos a las funciones. ESP es el registro que apunta a la punta del Stack

Page 29: Seguridad En Programación

Cómo se %$&! la memoria

Page 30: Seguridad En Programación

Qué puede ocurrir?

• En el Shellcode que coloquemos podemos hacerle hacer lo que querramos

• Los espacios se llenan con NOPs o INCs

• Hay generadores de Shellcode http://www.metasploit.com

Page 31: Seguridad En Programación

En la práctica

• Tenemos un programa que tiene un problema potencial:

void trucho (void) { char small[30]; gets (small); printf("%s\n", small); }

int main() { trucho (); return 0; }

Page 32: Seguridad En Programación

Mostrando la vulnerabilidad

• Se puede observar cómo surge la vulnerabilidad• Los hackers buscan por todos los medios este

comportamiento en una aplicación

Page 33: Seguridad En Programación

Busquemos las direcciones (GDB)

• Dirección de retorno interesante 0x08048418 (esto está originalmente en EBP)

Page 34: Seguridad En Programación

La función trucho()

• Aumenta en 0x28 = 40 el stack. Esto viene de que nuestro char[] es de 30 + padding mod 16 = 32 + 8 (para las direcciones del EBP) = 40.

Page 35: Seguridad En Programación

Cómo vemos el overflow?

• Se puede ver cómo justamente en el lugar donde se produce el overflow se va rellenando con los valores de datos el lugar del EBP (note que se llena en sentido contrario)

Page 36: Seguridad En Programación

Modificando la dirección

• Se debe encontrar la dirección donde queremos ir:

main() { int i=0; char buf[44]; for (i=0;i<=40;i+=4) *(long *) &buf[i] = 0x84130804; puts(buf); }

Page 37: Seguridad En Programación

Viendo el resultado

• Observe que también se debe tener cierto conocimiento para pasar el texto que queremos

• Salta el error y vuelve a ejecutarse la función trucho()

Page 38: Seguridad En Programación

Shellcode

• Es un código assembler que va en el espacio donde existe la vulnerabilidad.

• Se debe programar un shellcode con tamaños diferentes (dependiendo del tamaño del buffer)

• Luego se convierte el shellcode a un hex char. De manera que tenemos algo así:

static char shellcode[]= "\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d" "\x4e\x08\x31\xd2\xcd\x80\xe8\xe4\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58";

Page 39: Seguridad En Programación

Finalmente

• Se debe escribir un programa que:– Explote la vulnerabilidad enviando el Shellcode al lugar de la

memoria que corresponda– El shellcode generalmente puede ser una llamada a /bin/sh

• El resultado es que, cuando ejecutamos nuestro exploit, obtenemos un shell.

• El exploit puede ser a un programa, a un servicio (DNS, web, etc)

Page 40: Seguridad En Programación

Programación Defensiva

Page 41: Seguridad En Programación

Por qué?

• Según SANS, la primera de las 10 peores vulnerabilidades que hay es:

• ISO 27001

NO VERIFICACION de los parámetros de ENTRADA y SALIDA de las funciones de nuestros programas

12.2.1: El insumo de data en las aplicaciones debe ser validado para asegurar que esta data sea correcta y apropiada.12.2.2, 12.2.3 y 12.2.4: Que no hayan errores, integridad y validar output.

Page 42: Seguridad En Programación

Políticas de programación

• La primera cosa que se debe hacer es redactar una política de programación, que contenga:– Las cosas que NO se deben hacer– La existencia de patrones– El know-how de la empresa o grupo de desarrolladores– Explícitamente indicar la suma importancia del seguimiento de

las reglas– Complejidad ciclomática

• Técnicamente, se puede cumplir con estas reglas– Logging (log4net, log4j)– Peer review (revisión de pares)– Try / catch

Page 43: Seguridad En Programación

Logging

• Aproximadamente un 4% del código debe estar destinado a operaciones de logging (McConnell)

• Muy difícil enseñar a hacer buen logging, tiempo de aprendizaje aprox. 1 año.

• Mejor herramienta de logging: log4j / log4net: http://logging.apache.org

• Cada vez que ocurre una falla en el programa, podemos estar enterados por correo!!

Page 44: Seguridad En Programación

Ejemplo Logging (log4net)

protected void Logon_Click(object sender, EventArgs e){ log.Info("Trata de autenticarse: " + UserEmail.Text + "/********"); if (verificar(UserEmail.Text, UserPass.Text)) { log.Info("Usuario autenticado"); … // redirección o a Inicio } else { log.Error("Usuario " + UserEmail.Text + "/" + UserPass.Text + " incorrectos"); Msg.Text = "Nombre o Clave de Usuario son inválidos, o el usuario ha sido dado de baja"; }}

Page 45: Seguridad En Programación

Revisión de Pares

• SUMAMENTE difícil de implementar, sin embargo• De los 8 a 10 errores posibles en 1000 líneas de

código, 9 se resuelven / detectan con revisión de pares ANTES de la compilación o testeo

• En qué consiste?– REVISION sesuda del código por un tercero

• Consejo para la implementación– Bob realiza el código a ser aprobado por TOM– Alice presenta el código a ser aprobado a TOM– Si TOM descubre algún error, Alice es castigada

Page 46: Seguridad En Programación

Try / catch

• Se debe utilizar este patrón en todo lugar donde sea necesario, las veces que sea necesario, es importante el uso de programación defensiva en este sentido.

try {

File f = new File(“algo.txt”); FileReader fr = new FileReader(f);

} catch {

log.error(“Algo pasó”); }

File f = null;FileReader fr = null;try { f = new File(“algo.txt”);} catch(Exception e) { log.error(“error”, e);}try { fr = new FileReader(f);} catch(Exception e) { log.error(“error”, e);}

Page 47: Seguridad En Programación

Beneficios en producción

• Una vez se toman todos (al menos varios) de los recaudos en el tema de seguridad

• Una vez que se tienen los patrones en la empresa y se los aplica y la gente los conoce se pueden crear:– Herramientas de generación de código– Revisiones más ligeras aumentando la velocidad de desarrollo– Actualizar el software de manera más sencilla– No dependencia en los programadores

Page 48: Seguridad En Programación

Generadores de código

Una pequeña aplicación con una DAO

Page 49: Seguridad En Programación

Objetivo

• Las necesidades para el ejercicio son:

– Crear una librería de acceso a datos profesional

– Manejando concurrencia

– ABM de registros vistos como objetos

– Posible migración a otra base de datos o archivos no debe ser un problema

Page 50: Seguridad En Programación

Modelo base

• Patrón de diseño J2EE DAO• http://java.sun.com/blueprints/corej2eepatterns/P

atterns/DataAccessObject.html

Page 51: Seguridad En Programación

Modelo base – Abstract Factory

Page 52: Seguridad En Programación

Resultado esperado

• Agregando un singleton a nivel del Factory se puede tener un patrón para consultas:

• Este patrón– No depende de la base de datos y no es necesario conocer la

manera en que el DAO ha sido implementado

Factory factory = Factory.getOrCreate();PersonaDAO dao = factory.nuevoPersonaDAO();

Persona dto = dao.seleccionar(4);dto.Nombre = “pedro”;

dao.actualizar();

Page 53: Seguridad En Programación

Modelo extensible Objeto

Page 54: Seguridad En Programación

Modelo extensible DAO

Page 55: Seguridad En Programación

Generando…

Page 56: Seguridad En Programación

Et voilà!!

FactoryDAO factory = FactoryDAO.Instancia;PersonaDAO dao = factory.newPersonaDAO();Persona dto = dao.nuevo();

dto.Nombre = txtNombre.Text;dto.Numero = Convert.ToInt32(txtNumero.Text);dto.Salario = Convert.ToDouble(txtSalario.Text);

dao.actualizar();

Page 57: Seguridad En Programación

MUCHAS GRACIAS