martes, abril 08, 2008

Pipper v1.25 by Mandingo

Descripción
La idea de crear este programa surge como necesidad a la hora de automatizar peticiones en aplicativos Web. El programa en sí resulta lo suficientemente genérico como para llevar a cabo multitud de acciones que hasta ahora se realizaban mediante la creación de diversos "scripts" o bien, el uso de múltiples herramientas.Este programa no pretende ser la solución a todos los problemas de auditoría Web, pretende ser más bien una ayuda adicional a los auditores de este tipo de aplicativos, ya que se presupone un conocimiento previo de las tareas que se realizan comúnmente; Pipper únicamente muestra información numérico-visual (códigos de error, número de líneas y palabras devueltas, textos coloreados, etc.), tal y como se verá más adelante. Esta información deberá de ser interpretada posteriormente por el auditor, el cual tendrá que ser capaz de diagnosticar "qué está ocurriendo".Un buen uso de este programa reducirá notablemente los tiempos de prueba/error dedicados a "bruteforcear" variables/cookies/credenciales, búsqueda de ficheros (páginas, cgi's, etc...), localizar fallos de "Cross-Site Scripting", "SQL Injections", etc.
Requerimientos
La versión actual necesita de lo siguiente para funcionar correctamente:
Sistema operativo Unix/Linux.
Interprete PERL.
Software "curl" instalado en el sistema.
Un cerebro resulta también muy recomendable ;-)
Modo de empleo
Ficheros necesarios
Pipper se compone de varios ficheros. A continuación se muestra un listado de los mismos y su descripción:
Fichero
Descripción
pipper.pl
Programa principal.
payloads.xml
Fichero de definición de ¿payloads¿ en formato XML.
sql_inj.txt
Diferentes vectores de ataque usados en inyecciones SQL. Opcional.
nulls.txt
Ejemplo de vector de ataque para usar en inyecciones SQL tipo "union" usando variables de tipo "null". Opcional.
ones.txt
Igual que el ejemplo anterior usando variables numericas, en este caso 1's. Opcional.
Nota: Los ficheros "big.txt", "common.txt", "english.txt" que aparecen en los ejemplos, y que no se distribuyen con el programa, pertenecen a la herramienta dirb de DarkRaver. Estos ficheros pueden descargarse junto con la utilidad dirb disponible en: http://www.open-labs.org/dirb200.tar.gz
Ayuda
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:==[Pipper v1.25 by Mandingo]=========================================================== Usage : pipper [postData] [options]==[Options]============================================================================ -pa-pp-pr : All parameter's Payload Append/Prepend/Replace -hc-hl-hw : Hide those response codes/lines/words (comma separated) -ht : Hide responses that matches -st : Show responses that matches -min-med-max-html : Minimalist/Medium/Full(default)/html Output -sf : Show responses like First -v : Use those payloads vars (var1=val1,var2=val2...) -pn : Force this payload name -j : Jump to payload -u-u2 : Set server user and password (-u Basic, -u2 NTLM) -x : Set proxy server and port (-jap -> 127.0.0.1:4001) -X : Set socks server and port (-tor -> 127.0.0.1:9050) -t : Number of threads (def. 20) -c : Set this cookie -C : Retrieve cookie from URL -H : Set those header (head1:val1,head2:val2...) -p : Path to payloads -m : 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 404En 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.asphttp://www.servidor.com/main.asphttp://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 -> %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 "", "%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:

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.
Payloads
Introducción
Pipper se distribuye con un conjunto predefinido de "payloads", tal y como puede verse en el apartado "ejemplos". Estos "payloads" se encuentran identificados unívocamente por un nombre, los cuales deberán de ser llamados entre corchetes [] para su uso.
Podemos utilizar estos "payloads":
En cualquier parte de la URL. Ejemplos:./pipper.pl "http://[file]/null.htw" -v file=urls.txt./pipper.pl http://www.servidor.com/index.php?accion=view&id=[range] -v range=1:999 -hl 100
En los datos enviados mediante POST. Ejemplo:./pipper.pl "http://www.servidor.com/login.php" "user=bob&passwd=[file]" -v file=/wordlists/english.txt
En las cookies. Ejemplo:./pipper.pl "http://www.servidor.com/admin.php" -c "userid=[range]" -v range=1:100
En la autenticación (básica o NTLM). Ejemplo: ./pipper.pl "http://www.servidor.com/private" -u "admin:[file]" -v file=/wordlists/english.txt
Creación de payloads
Existen dos opciones para crear nuevos "payloads", una, editar el fichero "payloads.xml" y añadirlo donde creamos oportuno, y otra, añadirlo a un nuevo fichero xml de definición de "payloads". Al arrancar el programa se cargarán todos los ficheros xml con "payloads" del directorio actual. Si deseamos cargar los "payloads" contenidos en otro directorio, podremos usar la opción "-p ".
El formato de los "payloads" es el siguiente:



...

Donde tipo y valor deberán de ser una de las siguientes opciones:
Tipo
Valor
Ejemplos
values
Valores separados por comas.(a menos que se especifique otro valor con "separator")
values="lunes,martes,miercoles,jueves,viernes,sabado,domingo"values="par,impar"
charset
Cadena con los valores a usar. Similar a "values" en el que cada elemento ocupa solamente un carácter.
charset="0123456789"charset="abcdefghijklmnopqrstuvwxyz"
file
Nombre del fichero a leer.
file="sql_inj.txt"
range
Rango en formato "inicial:final"
range="0:9"range="a:z"range="0000:9999"
La propiedad "separator" tiene una función especial y es, en una lista de valores (tipo "values"), indicar un alternativo a la coma (,). Por ejemplo:
El "payload" final generado se obtiene "expandiendo" cada uno de los "items" en sus valores, combinándose posteriormente éstos con los obtenidos en los restantes "items".
Este sencillo ejemplo:
Generaría los siguientes "payloads":
me gusta el futbolme aburre el futbolno me gusta el futbolno me aburre el futbolAhora, si quisiésemos usarlo con Pipper, podríamos hacer lo siguiente:
./pipper.pl http://www.servidor.com/foro/publish.php "topic=[prueba1]&text=to+pipper+or+not+to+pipper"
Paso de parámetros
Resulta posible pasar parámetros a los "payloads", tal y como ocurre con "file", "fileExt" y "range".Estos parámetros se pasan desde la línea de comandos con la opción "-v". Por ejemplo, en la siguiente petición:
./pipper.pl http://www.servidor.com/[fileExt] -v file=/wordlists/big.txt,ext=-.php-.inc -r -hc 400,404Tanto "file" como "ext" son parámetros que se pasan a "fileExt". Si nos fijamos la definición de este "payload", podremos ver donde usa esos parámetros:
Resulta conveniente, pero no indispensable, indicar en los comentarios si ese "payload" necesita o no parámetros adicionales.En este ejemplo podemos ver que se ha usado como delimitador el carácter "-". Ésto resulta necesario, al menos de momento, ya que si usásemos una coma ",", el programa no sabría distinguir si lo que viene después de ella es un nuevo parámetro o un valor.
Cambios v1.23-v1.25
Añadida opción "-ht "; inversa de la función "-st ".
Añadida una nueva opción que permite generar una salida XML con los resultados de la ejecución del programa. Uso: pipper -o
Descarga
Descargar pipper v1.25
Agradecimientos
Como no podía faltar, los agradecimientos van a todos aquellos que me habéis apoyado durante el proyecto, aportado ideas, o que habéis sufrido con el duro "betatesting". Por orden alfabético, estos agradecimientos van para:
Dark Raver
Iam
Mitrein
Turk182
Gracias a todos :)

No hay comentarios: