Nebula level01

Share it!

En este nivel nos proporcionan lo siguiente:

«There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it?»

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
int main(int argc, char **argv, char **envp)
{
gid_t gid;
uid_t uid;
gid = getegid();
uid = geteuid();</p>
setresgid(gid, gid, gid);
setresuid(uid, uid, uid);</p>
system("/usr/bin/env echo and now what?");
}

Recordando C, aplicando llamadas en sistemas GNU\Linux

stdlib.h

  • Conversión, memoria, control de procesos, ordenación y búsqueda, matemáticas.
  • abort
  • exit
  • atexit
  • getenv
  • system

 

unistd.h

  • Header que provee acceso al API POSIX de los sistemas operativos GNU\Linux \ Unix.
  • POSIX: Portable Operating System Interface (standard/portabilidad).
  • Es parte de la C POSIX library, junto con assert.c, limits.h, stdarg.h, stdio.h, etc)
  • Es una interfaz para las syscalls

 

string.h

  • Manejo de cadenas, strcpy,strcmp,etc

 

sys/types.h

  • Funciones de búsqueda y ordenamiento de directorios y manipulación de archivos

 

stdio.h

  • Funciones de entrada/salida

 

Un programa en C siempre comienza con la llamada a la funcion main(), siendo la primera funcion que se ejecuta cuando corremos un programa.

El tipo de retorno que nos da el programa será int ( 0 ) si se ha producido con éxito, cualquier otro valor de retorno de la funcion main() que no sea 0 significa algún tipo de error.

Esta funcion main() acepta 3 argumentos:

int main(int argc, char **argv, char **envp)

  • int argc =  nº de command line arguments
  • **argv = lista de los command line arguments
  • **envp = array de cadenas que representan las variables de entorno del usuario

Posteriormente, declaramos los tipos de las variables gid_t y uid_t y las seteamos con getegid() y geteuid();, que devuelven el Group ID y el User ID del usuario que está ejecutando el proceso ( el que nos interesa, que es flag01)

Explicandolo un poco, todo proceso en los sistemas Unix tienen al menos dos UID ( User id number ), que suelen ser los mismos:

  • real UID number ( identifica al usuario que lanza el proceso )
  • effective UID number ( determina que recursos accede el proceso, cuando un proceso  abre un fichero,el propietario se determina con el effective UID )
  • Y un tercer UID, el saved UID number, que es un tipo de effective UID.

Ahora sólo nos queda setear con setresgid() y setresuid() con el siguiente formato setresuid(ruid,euid,suid) y ejecutar entonces la llamada al sistema.

Empieza el truco cuando se ejecuta la llamada al sistema /usr/bin/env, que nos devuelve la totalidad de las variables de entorno que tenemos configuradas para nuestro usuario, entonces el proceso, a través de env busca en  el PATH, que es el siguiente

$ env|grep PATH

$ PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

Lo siguiente que hay que conocer es que cuando agregas un directorio al PATH, se agrega y ejecuta de izquierda a derecha, de manera que si creamos un ejecutable que se llame echo ( que es lo que invoca el source code ) en un directorio en el que tengamos permiso de escritura para todos ( /dev/shm a.k.a /tmp ) y agregamos ese directorio al PATH, quedará de la siguiente manera:

$ PATH=/dev/shm:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

Creamos un ejecutable, le llamamos echo, ejecuta una shell via /bin/sh lo guardamos en /dev/shm, and here we go, privilege escalation via command execution !

Share it!
Esta entrada fue publicada en Privilege Escalation. Guarda el enlace permanente.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>