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

domingo, 9 de septiembre de 2018

XSS al subir archivos

Un input para cargar archivos es una gran oportunidad para realizar ataques XSS. El área restringida de un usuario como cargar una imagen de perfil es una gran oportunidad, y nos brinda el poder realizar este ataque por fallo del programador. Básicamente podríamos tener los siguientes ataques.

1) Cambiar el nombre del archivo

El nombre del archivo en si puede estar reflejado o persistente en una pagina, por lo cual se trata solamente de nombrar el archivo.


"><img src=X onerror="alert(document.domain)">.png

Es recomendable utilizar un sistema linux para este tipo de ataques.

Pueden probar con w3schools ya que es vulnerable a este ataque: https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_fileupload_value


2) Metadatos

Usando exiftool es posible alterar los metadatos que puedan llevar una ataque xss reflejado en alguna parte.

Syntax:  exiftool [OPTIONS] FILE

Ejemplo: exiftool -make='<script>alert(/xss/)</script>' FILE



3) Contenido

Si la aplicación le permite la carga de un archivo SVG (que también es un tipo de imagen), se puede usar un archivo con el siguiente contenido para ejecutar un XSS:

<svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.domain)"/>


4) Fuente

Es fácil crear una imagen GIF que lleve un payload javascript para utilizarlo como fuente en algún script. Esto es útil para eludir el CSP (La cabecera de política de seguridad de contenido) "script src 'self'" (que no permite <script>alert(1)</script> por ejemplo), si podemos inyectar con éxito en el mismo dominio, como se muestra a continuación.

Para crear una imagen de este tipo simplemente utilícela como contenido y guárdela con la extensión .gif

GIF89a/*<svg/onload=alert(1)>*/=alert(document.domain)//;


La firma de un archivo GIF, GIF89a se usa como una variable de javascript asignada a la función de alerta. Sin embargo, entre ellos hay un vector XSS comentado en caso de que la imagen se pueda recuperar como un MIME de texto/HTML, permitiendo así la ejecución de un payload simplemente solicitando el archivo.

Como también podemos ver a continuación, el comando similar al de UNIX junto a las funciones de PHP exif_imagetype() y getimagesize() lo reconocen como un archivo GIF. Por lo tanto, si una aplicación esta usando solo esto para validar la imagen, el archivo se cargara (pero puede desinfectarse mas adelante).


Para mas tipos de archivos que tienen su propia firma para la asignación de un javascript puede verificar esto: https://en.wikipedia.org/wiki/List_of_file_signatures

Hay ejemplo mas elaborados que usan archivos de imagen, generalmente omitiendo filtros como los de la biblioteca GD. Un ejemplo:
https://github.com/d0lph1n98/Defeating-PHP-GD-imagecreatefromgif

Traducido por Arthusu
Entrada creada en Brute Logic: https://brutelogic.com.br/blog/file-upload-xss/

jueves, 1 de mayo de 2014

[Parte 5] CURL en PHP

Funciones interesantes

curl_multi_init


Una de las extensiones mas usadas en PHP es cURL, y es genial para devolver documentos remotos. Para situaciones donde necesitas devolver multiples documentos se usa curl_multi_init y curl_multi_exec trabajan mejor con multiples documentos.

La funcion curl_multi_exec es muy poderosa, pero en la documentacion de PHP la hacen ver mas dificil de lo que realmente es. Aqui una demostracion usando Google, Bing y Facebook todos devueltos:

 $urls = array('http://www.google.com/', 'http://www.facebook.com/', 'http://www.bing.com/');
$url_count = count($urls); // cuenta el numero de urls

$curl_array = array(); // creamos un array llamado curl_array
$ch = curl_multi_init(); // iniciamos un multirecurso curl
// para las urls hay una clave que contiene su url
foreach($urls as $count => $url) {
 $curl_array[$count] = curl_init($url); // establecemos la url en una sesion curl refiriendonos a cada 1 con su clave
 curl_setopt($curl_array[$count], CURLOPT_FOLLOWLOCATION, 1); // le damos una opcion de seguir el header location
 curl_setopt($curl_array[$count], CURLOPT_RETURNTRANSFER, 1); // devolvemos el contenido
 curl_multi_add_handle($ch, $curl_array[$count]); // añadimos a cada url con sus opciones en el multirecurso
}
// mientras se esten ejecutando las urls realiza lo siguiente
do {
 curl_multi_exec($ch, $exec);
} while($exec > 0);


En este ejemplo hay 3 urls establecidas para devolverse al mismo tiempo. 


curl_multi_getcontent

Para leer el contenido de las peticiones que hicimos anteriormente podriamos usar la funcion curl_multi_getcontent. Vamos a ver como podemos hacerlo... (el codigo siguiente se puede añadir al anterior):


 //para cada url devolvemos el contenido junto con la url
foreach($urls as $count => $url) {
 $returned = curl_multi_getcontent($curl_array[$count]);
 echo "$url - $returned";
}



Cerrar el manejador de cURL


Algunos programadores prefieren usar curl_close() despues de haberlo usado. Usted en lugar de utilizar curl_close() deberia utilizar curl_multi_close(), y curl_multi_remove_handle() despues de que el contenido se haya devuelto. Veamos un ejemplo:



//para cada url eliminamos el manejador, cerramos la peticion multi recurso y cada peticion de una sesion curl la cerramos 
foreach($urls as $count => $url) {
 curl_multi_remove_handle($ch, $curl_array[$count]);
}

curl_multi_close($ch); 

foreach($urls as $count => $url) {
 curl_close($curl_array[$count]);
}


Como anteriormente dijimos el codigo anterior puede añadirse a lo que habiamos puesto antes... de esta manera todo el codigo quedaria asi:


 <?php
$urls = array('http://www.google.com/', 'http://www.facebook.com/', 'http://www.bing.com/');
$url_count = count($urls);

$curl_array = array();
$ch = curl_multi_init();

foreach($urls as $count => $url) {
 $curl_array[$count] = curl_init($url);
 curl_setopt($curl_array[$count], CURLOPT_FOLLOWLOCATION, 1);
 curl_setopt($curl_array[$count], CURLOPT_RETURNTRANSFER, 1);
 curl_multi_add_handle($ch, $curl_array[$count]);
}

do {
 curl_multi_exec($ch, $exec);
} while($exec > 0);
foreach($urls as $count => $url) {
 $returned = curl_multi_getcontent($curl_array[$count]);
 echo "$url - $returned";
}
foreach($urls as $count => $url) {
 curl_multi_remove_handle($ch, $curl_array[$count]);
}

curl_multi_close($ch); 

foreach($urls as $count => $url) {
 curl_close($curl_array[$count]);
}
?>

Fuente: http://www.fusionswift.com/2011/08/php-curl_multi_exec-example/



curl_setopt_array()


Con esta funcion podemos configurar multiples opciones para una transferencia cURL. Veamos un ejemplo:



 <?php
 // creamos un nuevo recurso curl
 $ch = curl_init();
 // establecemos las opciones apropiadas para la url
 $options = array(
  CURLOPT_URL => 'http://www.google.com/',
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_USERAGENT => 'Googlebot/2.1 (+http://www.google.com/bot.html)',
  CURLOPT_RETURNTRANSFER => true
  );
 curl_setopt_array($ch, $options);
 $output = curl_exec($ch);
 curl_close($ch);
 echo $output;
?>



curl_getinfo()


Esta funcion obtiene informacion relativa a una transferencia especifica. Los valores que devuelve son los siguientes:


  • "url"
  • "content_type"
  • "http_code"
  • "header_size"
  • "request_size"
  • "filetime"
  • "ssl_verify_result"
  • "redirect_count"
  • "total_time"
  • "namelookup_time"
  • "connect_time"
  • "pretransfer_time"
  • "size_upload"
  • "size_download"
  • "speed_download"
  • "speed_upload"
  • "download_content_length"
  • "upload_content_length"
  • "starttransfer_time"
  • "redirect_time"
  • "certinfo"
  • "request_header" 





curl_version()

Obtiene la informacion de la version de cURL





cURL File

Como veíamos en la parte 4 de curl, subiamos un archivo con el uso de @, pero apartir de PHP 5.5.0 ese prefijo esta obsoleto, por lo que se recomienda utilizar esta funcion.

CURLFile::__Construct--curl_file_create - Crea un objeto CURLFile

Estilo orientado a objetos:


public CURLFile::__construct ( string $filename [, string $mimetype [, string $postname ]] )

Estilo orientado a procedimientos:


CURLFile curl_file_create ( string $filename [, string $mimetype [, string $postname ]] )

Crea un objeto CurlFile, utilizado para transferir (upload) un fichero con CURLOPT_POSTFIELDS.

filename - indica la ruta de acceso al fichero a ser transferido
mimetype - Tipo mime del fichero
postname - nombre del fichero

Ejemplo, estilo orientado a objetos:



 <?php
/* http://example.com/upload.php:
<?php var_dump($_FILES); ?>
*/

// Crea un gestor cURL
$ch = curl_init('http://example.com/upload.php');

// Crea un objeto CURLFile
$cfile = new CURLFile('cats.jpg','image/jpeg','test_name');

// Asigna los datos POST 
$data = array('test_file' => $cfile);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

// Ejecuta el gestor
curl_exec($ch);
?>


Estilo por procedimientos:



 <?php
/* http://example.com/upload.php:
<?php var_dump($_FILES); ?>
*/

// Crea un gestor cURL
$ch = curl_init('http://example.com/upload.php');

// Crea un objeto CURLFile
$cfile = curl_file_create('cats.jpg','image/jpeg','test_name');

// Asigna los datos POST
$data = array('test_file' => $cfile);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

// Ejecuta el gestor
curl_exec($ch);
?>


Usar cURL con Expresiones regulares

Como en ejemplos anteriores usabamos la funcion preg_match y preg_match_all para ver si se encontraba determinado texto o link para poder mostrar el resultado que necesitabamos, para mas informacion sobre expresiones regulares por favor consulte:
http://www.arthusu.com.mx/2013/07/phpexpresiones-regulares-pcre.html

Como en el ejemplo de subidas de archivos en la parte 4  de curl, veíamos un upload con el cual sacábamos los links usando expresiones regulares:



 <?php
   set_time_limit(0);
   $url = "http://www0.xup.in/exec/xupload.php?uid=&key=";
   $user_agent = "Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0";
   $referer = "http://www.xup.in/";
   $directory=dirname(__FILE__).'\files/';
   if(isset($_FILES['f1'])){
      move_uploaded_file($_FILES['f1']['tmp_name'],"files/".$_FILES['f1']['name']);
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
      curl_setopt($ch, CURLOPT_REFERER, $referer);
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POSTFIELDS, array("F1"=>"@".$directory.$_FILES['f1']['name']));
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
      $result = curl_exec($ch);
      if(curl_errno($ch))
  {
      echo 'Curl error: ' . curl_error($ch);
  }
      curl_close($ch);
      unlink($directory.$_FILES['f1']['name']);
      //echo $result;
      preg_match_all('/<input type="text" name="t1" size="90" class="inp" value="(.*?)" onclick="highlight\(this\);" \/>/', $result, $matches);
      //echo '<p><img src="'.$matches[1][0].'" alt="img" /></p>';
      echo '<p><b>Link: <a href="'.$matches[1][0].'" target="_blank">Archive Link</a></p>';
      //print_r($matches);
   }else{
      echo '
         <form action="upload_curl.php" method="post" enctype="multipart/form-data">
            <label for="f1">Filename:</label>
            <input type="file" name="f1" id="f1"><br>
            <input type="submit" name="submit" value="Submit">
         </form>

      ';   
   }
?>
 

domingo, 27 de abril de 2014

[Parte 4] CURL en PHP

Cabecera post personalizada a un host remoto 

Esto sucede cuando solo podemos ver ciertas partes de un sitio web, el sitio necesita unas cabeceras especiales, que tendriamos que olfatear con algun intermediario tal como puede ser: Live HTTP HEADERS, HTTPFox, Burp Suite, Tamper Data...


En este ejemplo estoy olfateando las cabeceras HTTP usando de intermediario HTTPFox (Complemento de firefox).

En este caso nosotros usaremos la opcion CURLOPT_HTTPHEADER.

CURLOPT_HTTPHEADER - Un array de campos a configurar para el Header HTTP, en el formato: array('Content-Type: text/plain','Content-length: 100');

CURLOPT_HEADER - TRUE para incluir el header en el OUTPUT.

 <?php

 $url = "https://tuhost.com/";
 $referer = "https://tuhost.com";

 $ch = curl_init(); // iniciamos curl
 curl_setopt($ch, CURLOPT_URL, $url); // establecemos la url
 curl_setopt($ch, CURLOPT_VERBOSE, 1); // muestra como pasa todo
 curl_setopt($ch, CURLOPT_HEADER, 1); // muestra las cabeceras que el servidor nos devuelve
 curl_setopt($ch, CURLOPT_STDERR, fopen('log_curl.txt','a+')); // en este archivo se guarda lo de verbose
 curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/plain')); //modificamos nuestra cabecera
 curl_setopt($ch, CURLOPT_REFERER, $referer); // ponemos desde donde venimos
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // devolvemos el contenido de la pagina
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // quitamos la verificacion del certificado
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // seguimos cualquier redireccion
 curl_setopt($ch, CURLOPT_COOKIEFILE, fopen('cookies.txt','a+')); // le decimos donde van las cookies
 curl_setopt($ch, CURLOPT_COOKIEJAR, fopen('cookies.txt','a+')); // le decimos que escriba las cookies aqui

 $result = curl_exec($ch); // ejecutamos y guardamos
 
  curl_close($ch); // cerramos curl, liberamos memoria

 print $result; // mostramos el resultado

?>

Subir un archivo a un sitio remoto usando un formulario HTML

Tu debes usar un formulario utilizando el metodo POST pero con algunos cambios. En este ejemplo, donde el formulario contiene enctype='multipart/form-data'. Usamos el array superglobal $_FILE para leer el archivo y pasarlo por los campos post con el signo @. Tal como lo siguiente:

 curl_setopt($ch, CURLOPT_POSTFIELDS, array("$field_name"=>"@".$_FILES['file']['tmp_name']));

En este ejemplo les muestro como subimos un archivo remotamente a la pagina xup.in:

 <?php
   set_time_limit(0);
   $url = "http://www0.xup.in/exec/xupload.php?uid=&key=";
   $user_agent = "Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0";
   $referer = "http://www.xup.in/";
   $directory=dirname(__FILE__).'\files/';
   if(isset($_FILES['f1'])){
      move_uploaded_file($_FILES['f1']['tmp_name'],"files/".$_FILES['f1']['name']);
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
      curl_setopt($ch, CURLOPT_REFERER, $referer);
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POSTFIELDS, array("F1"=>"@".$directory.$_FILES['f1']['name']));
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
      $result = curl_exec($ch);
      if(curl_errno($ch))
  {
      echo 'Curl error: ' . curl_error($ch);
  }
      curl_close($ch);
      unlink($directory.$_FILES['f1']['name']);
      //echo $result;
      preg_match_all('/<input type="text" name="t1" size="90" class="inp" value="(.*?)" onclick="highlight\(this\);" \/>/', $result, $matches);
      //echo '<p><img src="'.$matches[1][0].'" alt="img" /></p>';
      echo '<p><b>Link: <a href="'.$matches[1][0].'" target="_blank">Archive Link</a></p>';
      //print_r($matches);
   }else{
      echo '
         <form action="upload_curl.php" method="post" enctype="multipart/form-data">
            <label for="f1">Filename:</label>
            <input type="file" name="f1" id="f1"><br>
            <input type="submit" name="submit" value="Submit">
         </form>

      ';   
   }
?>


En este caso tenemos un uploader y una carpeta llamada files/ en la cual se sube el fihcero luego envia una peticion subiendo el fichero y por ultimo nos envia el enlace, una cosa importante aqui es que agregamos la funcion curl_error($ch) que nos muestra si ocurre un error en cURL. Con la funcion curl_errno($ch) nos arroja un numero el cual tiene un mensaje especifico de error.

Nota: Recuerda que siempre que hago referencia a $ch es por que ahi se almacena la sesion de cURL.

Subir un archivo por FTP

Tu tienes la opcion en cURL de usar todos los comandos FTP. Por ejemplo, si quieres subir un archivo:

 <?php
if(isset($_POST['enviar'])){
    $ftp_user = "tuusuario";
    $ftp_pass = "tucontraseña";
    $url = "tuurloipdetuweb";
    $ftp_server = "ftp://". $ftp_user . ":" . $ftp_pass . "@" . $url;
    $archivo_a_subir = realpath($_FILES['userfile']['tmp_name']);
    $tamaño_del_archivo = filesize($archivo_a_subir);
    $fp = fopen($archivo_a_subir, 'rb');
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $ftp_server . $_FILES['userfile']['name']);
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_UPLOAD, 1);
    curl_setopt($ch, CURLOPT_INFILE, $fp);
    curl_setopt($ch, CURLOPT_INFILESIZE, $tamaño_del_archivo);
    if(curl_errno($ch)){
        echo "Ha ocurrido un error: " . curl_error($ch);
    }
    $result = curl_exec($ch);
    curl_close($ch);
    echo "Archivo subido correctamente<br />";
    print $result;
}else{
    echo '
        <form action="" method="post" enctype="multipart/form-data">
            <p><input type="file" name="userfile" /></p>
            <p><input type="submit" name="enviar" value="Subir!" /></p>
        </form>
    ';
}
?>

CURLOPT_INFILE - El fichero que el proceso de transferencia debe leer a la hora de subir el archivo.

CURLOPT_INFILESIZE - El tamaño esperado en bytes, del fichero cuando se esta subiendo un fichero al sitio remoto. Tenganse en cuenta que el uso de esta opcion no detendra a libcurl a la hora de enviar mas datos, exactamente lo que se envia depende de CURLOPT_READFUNCTION.

Eliminar un archivo y mostrarlos por FTP

Tu tienes la opcion de usar comandos FTP con cURL. Alguna lista de comandos puedes encontrarla en: http://en.wikipedia.org/wiki/List_of_FTP_commands

Veamos un ejemplo de Eliminar un archivo y como mostrar los archivos tambien de una carpeta.

 <!DOCTYPE html>
<html>
<head>
 <title>ELIMINAR ARCHIVOS FTP</title>
 <meta charset="utf8">
</head>
<body>
<h1>Eliminar archivo</h1>
<form action="" method="post">
 <p><b>Nombre de la carpeta: </b><input type="text" name="carpeta" placeholder="tucarpeta/" /><small>No es necesario especificarla</small></p>
 <p><b>Nombre del archivo: </b><input type="text" name="archivo" placeholder="archivo.jpg" /></p>
 <input type="submit" name="enviar" />
</form>
<h1>Mostrar archivos de la carpeta</h1>
<form action="" method="post">
 <p><b>Nombre de la carpeta: </b><input type="text" name="directorio" placeholder="tucarpeta/" /><small>Es necesario especificarla para mostrar el contenido del directorio</small></p>
 <input type="submit" name="enviar2" />
</form>
<?php
 /* Variables para el FTP */
 $ftp_user = "tuusuario";
    $ftp_pass = "tucontraseña";
    $url = "tuhost.com/";

    $ftp_server = "ftp://". $ftp_user . ":" . $ftp_pass . "@" . $url;

    /* Funcion para eliminar el archivo */
    if(isset($_POST['enviar'])){
    function delete($carpeta = null , $archivo){
     global $ftp_user, $ftp_pass, $url, $ftp_server;
  if($carpeta == null){
   $carpeta = "public_html/";
  }
  $postfields[] = "CWD ". $carpeta;
  $postfields[] = "DELE " . $archivo;

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $ftp_server);
  curl_setopt($ch, CURLOPT_POSTQUOTE, $postfields);
  $result = curl_exec($ch);
  if(curl_errno($ch)){
   echo curl_error($ch);
  }
  curl_close($ch);

  print $result;
 }
    $carpeta = $_POST['carpeta'];
    $archivo = $_POST['archivo'];
    delete($carpeta,$archivo);

 }
 /* Listar directorio */
 if(isset($_POST['enviar2'])){
  function listar_dir($directorio){
   global $ftp_user, $ftp_pass;
   $url = "tuhost.com/".$directorio;
   $ftp_server = "ftp://". $ftp_user . ":" . $ftp_pass . "@" . $url;
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $ftp_server);
   curl_setopt($ch, CURLOPT_FTPLISTONLY, 1);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   $output = curl_exec($ch);
   if(curl_errno($ch)){
     echo curl_error($ch);
    }
   curl_close($ch);
   $files = explode("\n", $output);
   print_r($files);
  }
  $directorio = $_POST['directorio'];
  listar_dir($directorio);
 }
?>
</body>
</html>

CURLOPT_POSTQUOTE - Un array de comandos FTP a ejecutar en el servidor despues de que se realice la peticion FTP.

CURLOPT_FTPLISTONLY - TRUE para solo listar nombres de un directorio FTP.


Opciones LibcURL

Podemos ver una lista de opciones sobre la libreria cURL en: http://www.php.net/manual/es/function.curl-setopt.php

Rastrear peticiones

Rastrear las peticiones o ver sus cabeceras, es una manera de saber si estamos haciendo bien algo en cURL, existen muchas herramientas las cuales podemos utilizar como intermediario para poder ver las peticiones, como vimos arriba usabamos HTTP FOX.
Y como comentabamos esta disponible tambien Burp Suite, Live HTTP Headers, Tamper Data, etc.

 
Hasta aqui la parte de este tutorial, nos vemos en la proxima parte que espero sea la ultima :).
 

miércoles, 6 de marzo de 2013

SQL injection MySQL V4 + Upload Shell

En este tutorial intentare mostrar como inyectar en una database MySQL Version 4....
Antes que nada debemos tener un poco de conocimientos de SQL o MySQL.
Bueno tenemos una url vulnerable.... En este caso pues yo ya se que es Version 4...
Empecemos....

Primero empezaremos viendo si la pagina es vulnerable para ello pondremos en la consulta host de la pagina un ' o " o \ o cualquier caracter no valido que pueda romper una query(peticion)....


Bueno como vemos hemos roto la consulta con un ' y sabemos que nuestra DBMS es MySQL.... ahora empecemos a ordernar columnas :D

 hicimos un order by 10 es decir que ordenemos las columnas por la columna 10... pero como esa columna no existe nos envia un error "Unknown column '10' in 'order clause' " que dice que no existe la columna 10 en order by clause ....

entonces vamos intentando menos... como sabemos que no existe 10 por logica entonces debemos intentar menos por que no 5? :D

vemos que nos arroja la pagina entonces con esto sabemos que si logro ordenar por 5 columnas esto no quiere decir que tenga 5... intentemos ponerle 6 :D order by 6 :P

Ahora si estamos seguros de que esta consulta tiene 5 columnas por que a la 6 nos arrojo que no existia entonces estaria algo asi:

$query='select column1,column2,column3,column4,column5 from table where id=$id';

bueno entonces como ya sabemos cuantas columnas contiene solamente las unimos.... union select 1,2,3,4,5



cuando hacemos el union de columnas nos arroja unos numeros con eso sabemos que esos son los campos vulnerables 3 y 4 y podemos inyectar ahi nuestras funciones.... por ejemplo: version() user() database(), etc...


bueno ahi tenemos sacamos la version() que es 4.1.22 y el user con el que podriamos conectar a mysql....

entonces como sabemos que es una version 4 en esta version no se encuentra la base de datos de tipo metadatos information_schema con la que se podria conseguir las otras bases de datos, tablas, columnas y registros por lo que en este caso tendriamos que adivinar :D

entonces si ya sabemos los numeros de columnas que hay en la query solo haria falta saber desde que tabla esta seleccionando esos datos.... para ello vamos a hacer adivinando (modo bruteforce) entonces nuestra consulta formada seria de la siguiente manera:

union select 1,2,version(),user(),5 from admin 

como ven admin es una tabla que no sabemos si es o no admin solo que estamos adivinando.... podria ser cualquier otra pueden usar, ya hay tablas mas usadas para ello pueden usar las que dejo seth http://pastebin.com/LkGT4Dii

entonces que nos saldra con la de admin ....
union select 1,2,version(),user(),5 from admin.....


como ven dice que la tabla admin no existe con eso sabemos que tenemos que buscar otra tabla y asi hasta dar con una tabla que pueda ser interesante....

el error seria:

table database.admin doesn't exist 

entonces seguiremos intentando con las tablas.....

como la pagina se mostro normal con las columnas que insertamos entonces sabemos que la tabla es correcta, la tabla seria administrators....

union select 1,2,version(),user(),5 from administrators

ahora entre los campos vulnerables tenemos que empezar a buscar adivinando las columnas que pueda haber en la tabla administrators....

y bueno para no seguir lo mismo pueden usar la tabla de arriba e intentar adivinar (bruteforce) por ejemplo puedes usar id que seria normal que haya muchos usuarios en esa tabla entonces insertamos id como columna....

union select 1,2,id,user(),5 from administrators

vemos que id es un campo correcto entonces podemos ir anotando datos en un bloc de notas, gedit, kate, etc....

seguimos intentando a bruteforce (adivinando), hasta encontrar todos los campos en este caso encontre que eran: id,user_name,user_password ....

entonces podriamos hacer un group_concat para que nos mostrara todos los registros juntos, group_concat no puede devolver todos los registros si son demasiados por lo que muchas veces necesitaras utilizar solamente concat o concat_ws con un limit de los registros a devolver.....

en este caso seria algo asi:
union select 1,2,group_concat(id,0x2d,user_name,0x2d,user_password),user(),5 from administrators

donde 0x2d seria un campo hexadecimal un divisor para que sepamos donde esta cada registro 2d es igual a - en hex pero para que mysql lo reconosca como hexadecimal agregamos 0x :P


entonces tenenemos dos usuarios administrators esto lo sabemos por el separador o divisor - id-user_name-user_password

como ven nuestro usuario esta encriptado y para saber el tipo de encriptacion solo hay que saber algo sobre criptografia.....

en este caso es un md5($pass,$salt)
podemos usar un software como john the ripper o hashcat para intentar desencriptarlo por medio  de diccionarios.....
o tambien puedes utizar webs online que realizan este trabajo de una manera mas rapida por que tienen guardados los datos en su base de datos.....


encontradas las passwords podemos buscar si esta aplicacion tiene programado algun panel de admin pero como tiene user y pass deberia tener no(?)
 :P entonces podriamos empezar a buscar por robots.....

pagina.com/robots.txt

muchas veces podemos encontrar cosas interesantes....

la otra opcion que se puede usar es google o bing o cualquier buscador :D

site: http://pagina.com/

y encontrar enlaces que puedan servir....

otra opcion es algun directory fuzzer o admin panels finders hay online tambien de estos..... aunque en este caso no utilizare por que se cual es podrias usar por ejemplo: OWASP DirBuster o un servicio online

Bueno ahi tenemos nuestro login entonces lo que aqui sabemos es que es un CMS osCommerce nos logeamos con el user y password(desencriptada)

Encontre que la pagina de administracion tenia un script que redirigia a otra web despues de acceder por lo que active noscript para que no se ejecutara el script....

revisando la pagina de administracion no tenia nada para subir shell, entonces lo que hice es como tenemos acceso a la administracion y sabemos que tenemos un cms un poco desactualizado buscamos algunas vulenrabilidades por google :D

y me encontre con uno http://www.exploit-db.com/exploits/12811/
lo siguiente subir mi shell.....


Listo de aqui terminaria el articulo podriamos hacer mas ataques de vulnerabilidades, o simplemente borrar la shell dejar un simple txt para darte un credito y avisar al administrador..... nunca defacear por que como dijo okol en su articulo de vulnerabilidades web comunes muchos webmasters se enojan y te buscan para encarcelarte, otros puede que sean tus amigos pero la mayoria se enojaria a nadie le gusta que le digan sus errores xD :P