domingo, 2 de marzo de 2014

[Parte 2] Seguridad en PHP

Formularios y URLs

En esta parte vamos a ver el tratamiento de formularios y URLS. Aprenderemos ataques como XSS, CSRF, falsificar formularios y enviar solicitudes manualmente.


Formularios y datos

Las tareas que hace PHP la mayoría son procesamiento de datos, son tareas tales como, por ejemplo: iniciar sesión, agregar elementos en carrito de compras, procesar una transacción por tarjeta de crédito, etc.


Los datos que se procesan pueden considerarse:

* maliciosos
* no maliciosos

Los no maliciosos podría ser por ejemplo, un email que tu sabes que muestras como salida, es algo de confianza por que tu mismo lo estas manipulando, tu mismo lo envías, pero por ejemplo, si alguien ingresa un email y no esta filtrada puede convertirse en un dato malicioso ya que no se filtra la entrada y no se escapa la salida.

Un usuario puede enviar los datos de tres formas predominantes:

* Por la url ($_GET)
* En el contenido de la solicitud ($_POST)
* En la cabecera HTTP ($_COOKIE)

La datos que se envian no cambian, sino la forma en que se envian, veamos un ejemplo:



Los datos son interceptados por Burp Suite Pro.

Ataques a URL semánticas

Los ataques de url semánticas son los cuales vas modificando la URL para ver que tipo de datos interesantes puedes obtener no solo por GET por que como ya vimos en las imágenes de arriba atrapamos los datos con Burp suite interceptándolos en el envió.

Las URL semánticas son las que tienen un significado para el usuario y son fáciles de recordar ya que van acorde con el contenido de la pagina web.

Otra de los aspectos importantes es que este tipo de URL pueden quedar almacenadas en buscadores como Google, de manera que pueden ser vistas por todo el publico y podemos empezar nuestro ataque.

Un ejemplo, podría ser un formulario donde los datos se envian por GET aunque comúnmente son por POST cambian su email alternativo para que su cambio de contraseña sea enviado a ese email.



De esta manera que pasa que no esta verificando al usuario por medio de sesiones sino por medio de un input, es tan facil como nosotros cambiar el usuario por el que nosotros queramos por ejemplo: user002 en lugar de user001 y el email por el de nosotros:


La manera de solucionar este problema seria el uso y manejo adecuado de sesiones. Un ejemplo de este tipo de ataque: http://www.securityfocus.com/archive/75/320768/2003-05-05/2003-05-11/0




Ataque de subida de archivos

Muchas de las paginas web hoy en día permiten la subida de archivos, tal y como son facebook, twitter, blogs, foros, etc. 

Un formulario de subida de archivos básico es como el siguiente:



Como se ve en la imagen, algo diferente que vemos a simple vista es que el formulario incluye enctype="multipart/form-data" esto se usa para la carga de archivos solamente, y también tenemos un campo oculto con una variable MAX_FILE_SIZE la cual tiene un valor de 1024 que seria lo máximo permitido para el peso del archivo aunque el HTML siempre se puede editar desde el lado del cliente no esta demás ponerlo, pero lo ideal seria validarlo desde el servidor, y por ultimo tenemos un campo llamado attachment de tipo file que es para buscar el archivo en nuestro ordenador que queramos subir.

Para procesar nuestro formulario desde el PHP seria usando el array superglobal $_FILES, veamos como se nos muestra el array en el navegador de manera que conozcamos como lo podemos usar:



Como se ve en la imagen tenemos las cabeceras y el archivo impreso en texto plano su variable $_FILES de esta manera podemos analizar rapidamente:

$_FILES['attachment']['name'] - Es el nombre de la imagen
$_FILES['attachment']['type'] - Es el tipo de archivo
$_FILES['attachment']['tmp_name'] - Donde se almacena el archivo temporalmente al subirse
$_FILES['attachment']['error'] - Es el tipo de error, en este caso por ejemplo, tuve que cambiar MAX_FILE_SIZE para que no me lanzase el error 2 que es el archivo excede el maximo tamaño permitido, podemos ver mas sobre ello aqui: http://www.php.net/manual/es/features.file-upload.errors.php
$_FILES['attachment']['size'] - Es el tamaño del archivo



El código de la imagen ha sido sacado de W3schools y es un ejemplo seguro de subir imágenes, en este caso como al procesar el formulario de las imágenes, lo primero que hacemos es tomar la extensión del archivo y verificar si es cualquier tipo de imagen, después verificamos que si el archivo que subimos concuerda con cualquier tipo de imagen permitido que nos muestre que se subió, si el archivo existe que nos muestre un mensaje de que existe, si el archivo no esta entre las extensiones permitidas es invalido, y si pasa algún error también lo mostrara.




Aquí en este imagen mostramos como queremos evitar la extensión JPG por una PHP, pero el caso es que no esta validando la cabecera Content-Type si no la extensión por lo cual nos arroja que el archivo es invalido, ya que no entre su lista de archivos permitidos.

Otra manera de evitar este tipo de ataques seria usar un archivo .htaccess (archivo para modificar directivas Apache sin tener que usar el archivo httpd.conf) y crear unas reglas donde solo permitamos imágenes y solamente eso. Esto se subiria claro en el directorio donde estamos subiendo las imágenes.



deny from all<Files ~ "^\w+\.(gif|jpe?g|png)$">order deny,allowallow from all</Files>






Cross Site Scripting (XSS)

Esta es una de las vulnerabilidades mas conocidas.




Cualquier aplicación que muestre un campo de entrada puede ser victima de este ataque, este ataque se puede dar en foros, blogs, y webs de las mas conocidas, para poner como ejemplo a Google.

Un ejemplo de este ataque podría ser el siguiente:



¿Y que pasa con esto? Que como no esta validado podemos inyectar script en la pagina web, esto lo hacemos por que nuestro html es interpretado tal y como nosotros quisiésemos un ejemplo seria obtener las cookies del usuario y poder ingresar a su web con su nivel de privilegios.




Esto nos daría un resultado como el siguiente:


Lo ideal para eliminar este ataque seria usar HTMLENTITIES aunque también existen librerías tales como htmlpurifier si es que quieres aceptar algunas etiquetas html, veamos el ejemplo anterior con nuestro código de nuevo:




Cross site request forgery (CSRF)

El CSRF (del ingles cross site request forgery o falsificación de petición en sitios cruzados) es un tipo de exploit malicioso de un sitio web en el que comandos no autorizados son transmitidos por un usuario en el cual el sitio web confía. 

Un ejemplo de este ataque puede ser una aplicación en la cual puedes comprar lapices o plumas...




Esta aplicacion lo que hace es que compras lapices o plumas,con lo cual si lo compras (aunque en este caso es de ejemplo por que nisiquiera llenamos datos :P) correctamente te dice que tu compra se realizo correctamente pero sino te dice que hubo un error al procesar el pedido  

Se estarán preguntando, ¿Pero no esta por method $_GET?, Bueno en realidad el PHP tiene $_REQUEST el cual acepta $_POST y $_GET pero les mostrare como se puede explotar de las dos maneras, por que muchos piensan que si es $_POST este ataque no puede ser vulnerado, pero no es así en realidad.


Como ves en este ejemplo, se realiza la compra, y esto sin que el usuario que ejecuto esto haya confirmado su compra, imagina que tuvieses un XSS Persistente, de esta manera te puedes montar un Phishing con XSS y realizar un Ataque CSRF o solamente puedes enviar la pagina, ejemplo de método POST:



No creo que sea necesario explicar lo que realiza, pero de todas maneras lo diré, lo que hace es ejecutar los campos por método post en cuanto carga esta pagina, los campos están ocultos y se procesan rápidamente, y el ataque ha sido realizado.

Entonces, ¿Que tan malo es este ataque?,pues con el puedes realizar muchos tipos de cosas (ya sean administrativas el usuario que lo tiene que ejecutar es el administrador ...) como por ejemplo, eliminar un usuario por la URL al no tener un token o una pagina donde te diga que si deseas proceder con la acción tan importante, puede realizar el ataque.

La manera de asegurarse en PHP de que no pase esto es como ya comentamos los "tokens" o una pagina donde diga que si desea proceder con tal acción, aunque aveces es fastidioso ese tipo de paginas se opta muchas veces por los tokens...

Los tokens pueden ser algo (como un PIN por ejemplo) que identifique ser que el usuario que esta realizando tal acción tiene suficientes permisos para realizarla y es ese usuario en realidad y no otro, y ¿por que aumenta esto nuestra seguridad? por que el usuario atacante no sabe cual es nuestro token entonces no podrá ejecutar su ataque CSRF ;).



¿Que esta pasando aquí?, como ves estamos haciendo nuestra compra y como el token es correcto nos da un mensaje de que nuestra compra se realizo con éxito, en este caso el token no tiene limitación, es decir, no tiene fecha de caducidad algo que también se puede aplicar :P, bueno pero antes que eso, veamos que podría hacer si fuera el atacante, pues solo tratar de adivinar el token algo que seria muy difícil :P entonces si no tengo el token mi exploit falla:

Y pues por ultimo les muestro el código con el que estaba haciendo las pruebas, que en realidad no seria así programado en una aplicación web real, pero para un ejemplo, puede verse como en realidad son usados los tokens:



Y en el ejemplo de tiempo como lo habíamos dicho mas arriba, seria por ejemplo esto:


Un ejemplo en una aplicación web famosa tal y como es Wordpress, podemos ver este tipo de ataque en la siguiente URL: http://www.exploit-db.com/exploits/18791/

Falsificar Formularios

Falsificar un formulario es modificarlo de tal manera que quede como tu quieras y puedas enviar los datos tal y como tu quieras, en este caso seria el atacante...

Imaginemos que tenemos un formulario el cual envía un correo al administrador, este correo seria un mensaje de reporte o un mensaje que tu quisieras, todo funciona normalmente si no falsifican el formulario:



Enviamos el mensaje:


Tal como se ve lo recibimos correctamente, pero si miramos el código fuente el correo puede ser falsificado...


La imagen anterior estamos usando el complemento Firebug para firefox tambien esta disponible en Google Chrome.


Como vemos hay un campo oculto, que es el correo al cual se envían todos los mensajes, ¿que pasaría con esto?, si fuésemos el atacante podríamos enviar mensajes desde la aplicación a quien nosotros queramos y con el correo que nosotros queramos :3


Como podemos ver hemos metido otro correo en el valor de ese campo con solo dar doble clic podemos editarlo usando firebug.


Y al enviarlo se envía al correo que nosotros deseemos, estamos falsificando el formulario por medio de firebug.

O también podemos copiar el código HTML de la pagina y editarlo en nuestra maquina y enviarlo en action a esa web, para asegurar el código en ese caso seria checar la cabecera Referer (De donde viene la petición) o validar y filtrar los campos tal y como debe de hacerse, o simplemente declarar en el PHP y no en el formulario las cosas que no son necesarias, este correo podría ser declarado en el PHP como una constante por ejemplo.


Falsificando Solicitudes HTTP

Como vimos en la parte de arriba usamos burp suite estábamos viendo las cabeceras, en este caso podríamos falsificar solicitudes HTTP con el mismo Burp suite usando la acción de repetir la solicitud, pero para no complicarlo lo haremos con el live http headers que esta disponible como complemento para firefox, también existe tamper data...



Un ejemplo fácil y no seria vulnerable, pero si mostramos como podemos falsificar la solicitud HTTP:



Como podemos ver el color elegido fue, el color rojo, podemos falsificar la solicitud dando clic en repetir y poner el color que nosotros queramos aunque no se encuentre en esa lista :)



¿Por que es importante esto de falsificar solicitudes HTTP?, simplemente por que si tenemos datos que enviamos por POST y no los validamos y escapamos correctamente todo eso puede ser editado de la manera que quiera el atacante, y aunque enviemos datos por AJAX (sin que la pagina cargue) podemos ver todas las cabeceras enviando solicitudes HTTP.

Para corregir esto como se ya se dijo en la parte 1 es validar y escapar datos de entrada.

Hasta aqui la parte 2 espero que les haya gustado, nos vemos en la proxima parte, comentarios y criticas constructivas son recibidas :)

Referencias:

Essential PHP Security
Wikipedia
SecurityFocus
Acunetix
W3schools

No hay comentarios:

Publicar un comentario