lunes, 30 de mayo de 2016

¿Cómo funciona la inclusión local de archivos (LFI)?

Local File Inclusion (LFI) o, en español, Inclusión local de archivos, es una técnica que consiste en la inclusión de ficheros locales, es decir, archivos que se encuentran en el mismo servidor de la web (a diferencia de Remote File Inclusión, que incluye archivos alojados en un servidor externo). 


Imagen 1: ¿Cómo funciona la inclusión local de archivos (LFI)? 

La vulnerabilidad se produce como consecuencia de un fallo en la programación de la página, que filtra de manera inadecuada lo que se incluye al usar funciones en PHP para la inclusión de archivos. El problema reside en que si se presenta un escenario como este, un "atacante" podría modificar los parámetros de lo que se incluye e indicarle al sitio web que incluya otros archivos que también están en el mismo servidor, comprometiendo por completo la seguridad del mismo. Un claro ejemplo podría ser el archivo de contraseñas /etc/passwd en sistemas Linux.

Para entender mejor como funciona esta vulnerabilidad, usaremos un laboratorio de pruebas llamado bts_lab. Es un entorno el cual viene ya preparado con las configuraciones con los fallos que necesitamos para llevar a cabo las pruebas, sin cometer ningún delito. En la siguiente imagen se puede ver cómo un atacante podría leer el archivo que hemos mencionado anteriormente en un sistema Linux,  el cual obtiene información sensible del servidor:


Imagen 2: vemos como se podría leer el archivo passwd

Podemos observar cómo en la dirección URL se inserta el comando para leer el archivo en cuestión (/etc/passwd). Teniendo en cuenta que (../) se utiliza para subir un directorio, lo que hace el comando es subir directorios hasta llegar a la raíz del sistema operativo, para luego ingresar en etc y mostrar el archivo passwd.

Para poder corroborar si un sitio es vulnerable, se puede colocar un valor ilógico a la variable. En nuestro ejemplo tenemos: http://localhost/index.php?page= donde se coloca un valor, en este caso http://localhost/index.php?page=78se3, algo aleatorio que no se encuentre registrado. Si arroja cualquier error como Warning: main()… o Warning: include()… o algo parecido entonces probablemente sea vulnerable a RFI o LFI. 


Así es como se verían los respectivos códigos en PHP:

Código vulnerable:

<?php include $_GET[‘pagina’]; ?>

Código no vulnerable:

<?php include(‘pagina.php’); ?>


Para que una web sea vulnerable a LFI se necesita poder modificar los parámetros de lo que se va a incluir; el código no vulnerable anteriormente mostrado, include(‘pagina.php’), no es vulnerable a LFI porque no hay nada que pueda modificar, ya que nada más se incluye pagina.php.

En cambio, si el código es como el anteriormente mostrado (include $_GET[‘pagina’];) entonces sí nos permite modificar los parámetros de lo que se incluye: GET pasa los datos por URL, por lo que en la barra de direcciones veríamos algo como esto:  http://localhost/index.php?pagina=78se3.php, donde se incluye el archivo 78se3.ph. La manipulación de este archivo puede modificar lo que se incluye para mostrar, por ejemplo, el fichero de contraseñas de linux /etc/hosts.

Para evitar que esta técnica tenga mayor impacto, es muy importante montar el servidor con el mínimo privilegio posible, limitando la posibilidad de acceso a archivos del servidor dentro de su propia carpeta. Con esto conseguiremos evitar el acceso a archivos del sistema, aunque no a ficheros propios de la aplicación.

Aparte si queremos una protección mediante programación en vez  de controlar mediante permisos el servidor, hay que tener en cuenta que las rutas a ficheros se pueden escribir de dos maneras:

Directa: escribimos la ruta donde se encuentra el fichero directamente. Se debería eliminar los caracteres “\” o “/” de los datos enviados por los usuarios.

Relativa: subir hacia directorios superiores mediante el uso de “..\” o “../”. Lo podríamos evitar excluyendo, además de lo anteriormente mencionado, los puntos.

Por último aquí tienes algunas recomendaciones a tener en cuenta publicadas por OWASP:

  • Usar un mapa de referencias indirectas a objetos: Donde se ha usado una vez un nombre de fichero parcialmente, una buena alternativa es usar cifrado de una vía en la referencia parcial.
  • Enjaular usuarios con el comando chroot: Incorporar algún otro mecanismo de sandbox como la virtualización para aislar las aplicaciones entre sí por ejemplo, esto permitirá reducir escalamientos de privilegios.
  • Comprobar cualquier archivo o nombre de archivo ingresado por el usuario: Siempre es recomendable tomar los controles necesarios a la hora de ingresar algún tipo de dato por el usuario, si bien la mayoría de usuarios usará el servicio legítimamente, un atacante podría tratar de vulnerar el sistema a través de las falta de controles adecuados.
  • Validación estricta de la entrada del usuario.
  • PHP: deshabilitar allow_url_fopen y allow_url_include: Dentro del archivo .ini se recomienda compilar PHP localmente sin incluir esta funcionalidad. Muy pocas aplicaciones necesitan esta funcionalidad y para estos casos estas opciones deberían habilitarse desde la base de la aplicación.
  • PHP: deshabilitar register_globals y usar E_STRICT para encontrar variables no inicializadas.
  • PHP: ser extremadamente cuidadoso si pasa datos a system(), eval(), passthru() o (el operador de backtick).
  • PHP: asegúrese de que todas las funciones de ficheros y flujos de datos (stream_*) son controladas rigurosamente: La aplicación debe revisar siempre que los datos de usuario, no son proporcionados a ninguna función que tenga como argumento un nombre de fichero, incluyendo:

include() include_once() require() require_once() fopen() imagecreatefromXXX() file() file_get_contents() copy() delete() unlink() upload_tmp_dir() $_FILES move_uploaded_file()


domingo, 22 de mayo de 2016

Introducción a SQLmap: ataques SQL Injection

El día de hoy hablaremos de SQLmap, una de las herramientas más conocidas y utilizadas para la automatización de inyecciones SQL (SQL Injection). Está escrita en Python y funciona realizando peticiones a los parámetros que se le indiquen a una url, ya sea mediante una petición GET, POST, en las cookies, etc. Por otra parte es capaz de explotar cualquier tipo de SQLi, como union-base, time-base-blind, base-blind-injection, heavy-queries...

Imagen 1:Introducción a SQLmap: ataques SQL Injection 

Como ya vimos en esta demostración básica de Injección SQL, esta es una técnica de ataque a páginas o aplicaciones web, que intenta inyectar código SQL dentro de la aplicación destino, para de esta forma poder acceder a información sensible. Inyección SQL es un método de inclusión de código intruso que se vale de una vulnerabilidad informática presente en una aplicación en el nivel de validación de las entradas para realizar consultas a una base de datos. 

Parámetros básicos de SQLmap
  • -url  url  (-u) con la variable vulnerable ejemplo: https://rememberhackingsite.php?id=1
  • -p (buscar otra variable vunlerable) https://rememberhackingsite.php?id=1&user
  • --data si hay un formulario GET,POST los campos vulnerables
  • --level=n cinco niveles según dificultad
  • -dbs listar las bases de datos
  • --dbms  motor de la base de datos (MySQL,SQL Server ,etc)
  • -D indicamos la base de datos a utilizar (-Database)
  • --tables mostrar las tablas disponibles 
  • -t nombre de la tabla --columns
  • --dump vuelca resultados, mostrar contenido de las tablas
  • -C (Columnas) columnas a mostrar
  • --wizard ejecuta un asistente
  • --threads=n número de procesos (por defecto 1)
  • --delay=n segundos de espera entre peticiones http
  • -current-db base de datos que está usando actualmente
  • --current-user ver usuario que está ejecutando
  • --is-dba –current-db ver si el usuario es el dba de la BD
  • --privileges ver los privilegios del usuario (alter, create, drop, execute)
  • --file-read path (ruta) leer ficheros
  • --sql-shell obtener una sql en shel
  • --os-shell obtener shell en el servidor (asp es la 1, aspx 2, jsp 3, php 4) (si se poseen los suficientes privilegios y un FPD (Full Path Disclosure)
  • --headers= cabeceras del navegador
  • --random-agent cabeceras del navegador aleatorias
  • --time-sec= Segundos para retrasar la respuesta de DBMS (por defecto 5)
  • ---technique= : Se utiliza para seleccionar la técnica que se va a utilizar en la inyección ( B - E - U - S - T - Q.) Boolean-based, Error-based, Union, Stacked querys, Time-based, Inline queries

El listado completo lo tenéis en la documentación oficial:
https://github.com/sqlmapproject/sqlmap/wiki/Usage

SQLMap compara la página sin ningún tipo inyección, con la página con la inyección. Y en función de la variación entre ellas devuelve True o False (True si supera determinado ratio y False en el caso contrario).

Una vez sabemos todo esto pasaremos a ver un ejemplo, antes de nada necesitamos un objetivo sobre el que lanzar la herramienta. Una vez tengamos nuestro objetivo y hayamos comprobado que realmente es vulnerable a SQL Injection, es hora de ver lo que SQLmap es capaz de hacer.

Lo primero que vamos hacer será comprobar que nuestro objetivo es realmente injectable, para ello escribimos la siguiente instrucción:

sqlmap  -u url --dbs

Imagen 2: Instrucción para que nos muestre las las bases de datos

Imagen 3: Resultado de la petición para que nos muestre las bases de datos

Después de esto sqlmap nos devolverá como resultado el contenido de la base de datos. Para visualizar sus tablas tecleamos lo siguiente:

sqlmap  -u url -D nombredelabasededatos --tables

Imagen 4: Instrucción para que nos muestre las tablas

Imagen 5: Resultado de la petición para que nos muestre las tablas

Nos mostrará todas las tablas que contiene esa base de datos en concreto, ahora seleccionaremos la tabla que nos interesa para que nos muestre su contenido:

sqlmap  -u url -D nombredelabasededatos -T nombredelatabla --columns

Imagen 6:  Instrucción para que nos muestre las columnas

Imagen 7: Resultado de la petición para que nos muestre las columnas

Por último solo tenemos que añadir las columnas que creamos necesarias, y le agregamos la instrucción --dump para que se realice el volcado de datos.

sqlmap  -u url -D nombredelabasededatos -T nombredelatabla -C nombredelacolumna --dump

Imagen 8: Instrucción para que realice el volcado de datos

Imagen 9: Resultado del volcado de datos