euid, ruid, suid

Reading time: 7 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks

User Identification Variables

  • ruid: stvarni korisnički ID označava korisnika koji je pokrenuo proces.
  • euid: Poznat kao efektivni korisnički ID, predstavlja identitet korisnika koji sistem koristi za utvrđivanje privilegija procesa. Generalno, euid odražava ruid, osim u slučajevima kao što je izvršavanje SetUID binarnog fajla, gde euid preuzima identitet vlasnika fajla, čime se dodeljuju specifične operativne dozvole.
  • suid: Ovaj sačuvani korisnički ID je ključan kada proces sa visokim privilegijama (obično pokrenut kao root) treba privremeno da se odrekne svojih privilegija kako bi izvršio određene zadatke, samo da bi kasnije povratio svoj prvobitni povišeni status.

Important Note

Proces koji ne radi pod root-om može samo da modifikuje svoj euid da odgovara trenutnom ruid, euid ili suid.

Understanding set*uid Functions

  • setuid: Suprotno prvobitnim pretpostavkama, setuid prvenstveno modifikuje euid umesto ruid. Konkretno, za privilegovane procese, usklađuje ruid, euid i suid sa određenim korisnikom, često root, efikasno učvršćujući ove ID-ove zbog nadjačavajućeg suid. Detaljne informacije mogu se naći na setuid man page.
  • setreuid i setresuid: Ove funkcije omogućavaju suptilno podešavanje ruid, euid i suid. Međutim, njihove mogućnosti zavise od nivoa privilegija procesa. Za procese koji nisu root, modifikacije su ograničene na trenutne vrednosti ruid, euid i suid. Nasuprot tome, root procesi ili oni sa CAP_SETUID sposobnošću mogu dodeliti proizvoljne vrednosti ovim ID-ovima. Više informacija može se dobiti iz setresuid man page i setreuid man page.

Ove funkcionalnosti nisu dizajnirane kao mehanizam sigurnosti, već da olakšaju predviđeni operativni tok, kao kada program preuzima identitet drugog korisnika menjajući svoj efektivni korisnički ID.

Važno je napomenuti da, iako setuid može biti uobičajen izbor za podizanje privilegija na root (pošto usklađuje sve ID-ove sa root), razlikovanje između ovih funkcija je ključno za razumevanje i manipulaciju ponašanjem korisničkih ID-ova u različitim scenarijima.

Program Execution Mechanisms in Linux

execve System Call

  • Functionality: execve pokreće program, određen prvim argumentom. Prihvaća dva niza argumenata, argv za argumente i envp za okruženje.
  • Behavior: Zadržava memorijski prostor pozivaoca, ali osvežava stek, heap i podatkovne segmente. Kod programa se zamenjuje novim programom.
  • User ID Preservation:
  • ruid, euid i dodatni grupni ID-ovi ostaju nepromenjeni.
  • euid može imati suptilne promene ako novi program ima postavljen SetUID bit.
  • suid se ažurira iz euid nakon izvršenja.
  • Documentation: Detaljne informacije mogu se naći na execve man page.

system Function

  • Functionality: Za razliku od execve, system kreira podproces koristeći fork i izvršava komandu unutar tog podprocesa koristeći execl.
  • Command Execution: Izvršava komandu putem sh sa execl("/bin/sh", "sh", "-c", command, (char *) NULL);.
  • Behavior: Pošto je execl oblik execve, funkcioniše slično, ali u kontekstu novog podprocesa.
  • Documentation: Dodatne informacije mogu se dobiti iz system man page.

Behavior of bash and sh with SUID

  • bash:
  • Ima -p opciju koja utiče na to kako se tretiraju euid i ruid.
  • Bez -p, bash postavlja euid na ruid ako se prvobitno razlikuju.
  • Sa -p, prvobitni euid se čuva.
  • Više detalja može se naći na bash man page.
  • sh:
  • Ne poseduje mehanizam sličan -p u bash.
  • Ponašanje u vezi sa korisničkim ID-ovima nije eksplicitno pomenuto, osim pod -i opcijom, naglašavajući očuvanje jednakosti euid i ruid.
  • Dodatne informacije su dostupne na sh man page.

Ovi mehanizmi, različiti u svojoj operaciji, nude raznovrsne opcije za izvršavanje i prelazak između programa, sa specifičnim nijansama u načinu na koji se upravlja i čuva korisnički ID.

Testing User ID Behaviors in Executions

Primeri preuzeti sa https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail, proverite za dodatne informacije

Case 1: Using setuid with system

Objective: Razumevanje efekta setuid u kombinaciji sa system i bash kao sh.

C Code:

c
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>

int main(void) {
setuid(1000);
system("id");
return 0;
}

Kompilacija i Dozvole:

bash
oxdf@hacky$ gcc a.c -o /mnt/nfsshare/a;
oxdf@hacky$ chmod 4755 /mnt/nfsshare/a
bash
bash-4.2$ $ ./a
uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0

Analiza:

  • ruid i euid počinju kao 99 (nobody) i 1000 (frank) respektivno.
  • setuid usklađuje oba na 1000.
  • system izvršava /bin/bash -c id zbog symlink-a sa sh na bash.
  • bash, bez -p, prilagođava euid da se poklapa sa ruid, što rezultira da oba budu 99 (nobody).

Slučaj 2: Korišćenje setreuid sa system

C Kod:

c
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>

int main(void) {
setreuid(1000, 1000);
system("id");
return 0;
}

Kompilacija i Dozvole:

bash
oxdf@hacky$ gcc b.c -o /mnt/nfsshare/b; chmod 4755 /mnt/nfsshare/b

Izvršenje i Rezultat:

bash
bash-4.2$ $ ./b
uid=1000(frank) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0

Analiza:

  • setreuid postavlja i ruid i euid na 1000.
  • system poziva bash, koji održava korisničke ID-ove zbog njihove jednakosti, efikasno delujući kao frank.

Slučaj 3: Korišćenje setuid sa execve

Cilj: Istraživanje interakcije između setuid i execve.

bash
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>

int main(void) {
setuid(1000);
execve("/usr/bin/id", NULL, NULL);
return 0;
}

Izvršenje i Rezultat:

bash
bash-4.2$ $ ./c
uid=99(nobody) gid=99(nobody) euid=1000(frank) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0

Analiza:

  • ruid ostaje 99, ali je euid postavljen na 1000, u skladu sa efektom setuid-a.

C Primer Koda 2 (Pozivanje Basha):

bash
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>

int main(void) {
setuid(1000);
execve("/bin/bash", NULL, NULL);
return 0;
}

Izvršenje i Rezultat:

bash
bash-4.2$ $ ./d
bash-4.2$ $ id
uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0

Analiza:

  • Iako je euid postavljen na 1000 pomoću setuid, bash resetuje euid na ruid (99) zbog odsustva -p.

C Primer koda 3 (Korišćenje bash -p):

bash
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>

int main(void) {
char *const paramList[10] = {"/bin/bash", "-p", NULL};
setuid(1000);
execve(paramList[0], paramList, NULL);
return 0;
}

Izvršenje i Rezultat:

bash
bash-4.2$ $ ./e
bash-4.2$ $ id
uid=99(nobody) gid=99(nobody) euid=100

Reference

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks