SUID, SGID și Sticky Bits sunt permisiuni speciale, avansate, ce pot fi configurate pentru fișiere executabile și directoare în sistemele Linux, oferind control granular asupra modului în care sunt accesate și manipulate datele. Vom explora avantajele și potențialele riscuri ale utilizării acestor permisiuni.
Utilizarea Permisiunilor Avansate
Securizarea unui sistem de operare multi-utilizator ridică provocări complexe. Un exemplu este gestionarea parolelor. Acestea trebuie stocate într-un mod în care sistemul să le poată compara la autentificare cu cele introduse de utilizatori. În mod evident, parolele, fiind esențiale, necesită protecție strictă.
În Linux, parolele stocate sunt protejate prin criptare și prin restricționarea accesului la fișierul care le conține doar utilizatorilor cu privilegii de root. Deși sună solid, apare o problemă: dacă doar root poate accesa parolele, cum își modifică parola un utilizator obișnuit?
Elevarea Privilegiilor
În general, programele și comenzile Linux rulează cu permisiunile utilizatorului care le lansează. Când root execută comanda passwd pentru a schimba o parolă, aceasta rulează cu permisiuni de root, având acces nelimitat la fișierul /etc/shadow, unde sunt stocate parolele.
Soluția ideală ar fi ca oricine să poată lansa passwd, dar ca programul să funcționeze cu permisiunile ridicate de root. Astfel, fiecare utilizator și-ar putea schimba propria parolă. Acesta este rolul bitului Set User ID (SUID). El face ca programele să ruleze cu permisiunile proprietarului fișierului, nu cu cele ale utilizatorului care le-a lansat.
Securitatea în Programe
Aici apare o altă problemă. Trebuie evitat ca un utilizator să modifice parola altuia. Linux, prin SUID, permite rularea aplicațiilor cu permisiuni împrumutate temporar, dar aceasta nu este întreaga poveste.
Mecanismul care împiedică un utilizator să interacționeze cu parolele altor utilizatori se află în codul programului passwd, nu în sistemul de operare în sine sau în mecanismul SUID.
Programele care funcționează cu privilegii ridicate pot prezenta riscuri de securitate dacă nu sunt proiectate cu principiul „securitate prin design”. Aceasta înseamnă că securitatea trebuie să fie prioritatea principală. Nu trebuie să scriem un program și apoi să încercăm să adăugăm securitatea ulterior.
Un avantaj important al software-ului open source este posibilitatea de a verifica codul sursă sau de a consulta analize de încredere. În codul sursă al passwd, există verificări care determină dacă utilizatorul care rulează programul este root. Funcții diferite sunt activate dacă utilizatorul are privilegii de root (sau folosește sudo).
Codul de mai jos este cel care identifică dacă utilizatorul este root:
// Exemplu cod - preluat din articol
if (geteuid() == 0) {
// Utilizatorul este root
// Se omit anumite verificări
}
De exemplu, deoarece root poate modifica orice parolă, programul nu mai face verificări suplimentare. Pentru root, se sar aceste verificări și se iese din funcția de verificare.

În cazul utilitarelor de bază Linux, codul este atent verificat și securizat. Desigur, există întotdeauna riscul unor vulnerabilități necunoscute, dar actualizările și patch-urile apar rapid pentru a contracara astfel de probleme.
Cu software-ul terț, mai ales dacă nu este open-source, trebuie să fim precauți când folosim SUID. Este esențial să ne asigurăm că utilizarea lui nu va expune sistemul unor riscuri. Nu este recomandat să ridicăm privilegiile unui program care nu se va auto-gestiona corect.
Comenzi Linux cu SUID
Câteva comenzi Linux care folosesc SUID pentru a acorda privilegii ridicate unui utilizator obișnuit sunt:
ls -l /bin/su
ls -l /bin/ping
ls -l /bin/mount
ls -l /bin/umount
ls -l /usr/bin/passwd

Observați că numele fișierelor sunt evidențiate cu roșu, indicând că bitul SUID este setat.
Permisiunile unui fișier sau director sunt reprezentate de trei grupuri de trei caractere: rwx, care înseamnă citire, scriere și execuție. O literă indică permisiunea acordată, iar o cratimă - indică absența acestei permisiuni.
Cele trei grupuri se referă la permisiunile pentru proprietarul fișierului, membrii grupului și ceilalți utilizatori. Când bitul SUID este setat, un s în locul permisiunii de execuție a proprietarului indică acest lucru. Dacă SUID este setat pe un fișier fără permisiune de execuție, se folosește S majusculă.
Un exemplu concret: utilizatorul obișnuit dave introduce comanda passwd:
passwd

Comanda passwd îi cere lui Dave noua parolă. Utilizând ps, putem vizualiza detaliile proceselor care rulează.
Folosim ps cu grep într-o altă fereastră de terminal pentru a localiza procesul passwd. Utilizăm opțiunile -e (toate procesele) și -f (format complet) cu ps.
Introducem următoarea comandă:
ps -e -f | grep passwd

Apar două linii, a doua fiind procesul grep. Prima linie ne interesează, reprezentând procesul passwd lansat de Dave.
Observăm că procesul passwd rulează ca și cum ar fi fost lansat de root.
Configurarea Bitului SUID
Bitul SUID se modifică ușor cu chmod. Modul simbolic u+s setează bitul SUID, iar u-s îl elimină.
Pentru a demonstra conceptele bitului SUID, am creat un mic program numit htg, localizat în directorul de bază al lui dave și fără bitul SUID setat. La rulare, el afișează ID-urile de utilizator reale și efective (UID).
UID-ul real aparține utilizatorului care a lansat programul, iar cel efectiv reprezintă contul prin care programul se comportă.
Introducem următoarele:
ls -lh htg
./htg

Rulând programul local, observăm că UID-urile reale și efective sunt setate la dave, comportamentul fiind cel al unui program normal.
Îl copiem în /usr/local/bin pentru a fi accesibil și altor utilizatori.
Introducem comenzile de mai jos, folosind chmod pentru a seta bitul SUID, apoi verificăm dacă a fost setat:
sudo cp htg /usr/local/bin
sudo chmod u+s /usr/local/bin/htg
ls -hl /usr/local/bin/htg

Programul este copiat și bitul SUID setat. Îl rulăm din nou, de data aceasta copia din /usr/local/bin:
htg

Deși dave a lansat programul, UID-ul efectiv este setat la root. Dacă Mary lansează programul, rezultatul este similar, după cum se vede mai jos:
htg

UID-ul real este Mary, iar cel efectiv este root. Programul rulează cu permisiunile utilizatorului root.
Bitul SGID
Bitul Set Group ID (SGID) este asemănător cu SUID. Când SGID este setat pe un executabil, grupul efectiv este setat la grupul fișierului, iar procesul rulează cu permisiunile membrilor grupului, nu cu cele ale utilizatorului care l-a lansat.
Am modificat programul htg pentru a afișa și grupul efectiv. Vom schimba grupul lui htg în grupul implicit al lui mary, mary. Folosim modurile simbolice u-s și g+s cu chown pentru a elimina SUID și a seta SGID.
Pentru aceasta, introducem:
sudo chown root:mary /usr/local/bin/htg
sudo chmod u-s,g+s /usr/local/bin/htg
ls -lh /usr/local/bin/htg

Bitul SGID este notat cu s în permisiunile de grup. De asemenea, grupul este setat la mary, iar numele fișierului este acum evidențiat cu galben.
Înainte de a rula programul, să vedem grupurile de care aparțin Dave și Mary, folosind comanda id cu opțiunea -G. Apoi, vom rula htg ca Dave.
Introducem următoarele comenzi:
id -G dave
id -G mary
htg

Grupul implicit al lui Mary este 1001, iar grupul efectiv al programului htg este 1001. Deși a fost lansat de Dave, el rulează cu permisiunile grupului Mary, ca și cum Dave s-ar fi alăturat grupului Mary.
Aplicăm bitul SGID unui director. Mai întâi, creăm un director numit work și îi schimbăm grupul în geek. Apoi setăm bitul SGID în director.
Folosind ls pentru a verifica setările directorului, utilizăm și opțiunea -d (director) pentru a vedea detaliile directorului, nu conținutul său.
Introducem următoarele comenzi:
sudo mkdir work
sudo chown dave:geek work
sudo chmod g+s work
ls -lh -d work

Bitul SGID și grupul geek sunt setate. Acestea vor afecta toate elementele create în directorul work.
Introducem comenzile de mai jos pentru a intra în work, creăm un director demo și îi verificăm proprietățile:
cd work
mkdir demo
ls -lh -d demo

Bitul SGID și grupul geek sunt aplicate automat directorului demo.
Introducem următoarele pentru a crea un fișier cu comanda touch și îi verificăm proprietățile:
touch useful.sh
ls -lh useful.sh

Grupul noului fișier este setat automat la geek.
Bitul Sticky
Bitul sticky și-a primit numele de la scopul său istoric. Când era setat pe un executabil, sistemul de operare indica faptul că secțiunile de text ale acestuia ar trebui păstrate în memorie pentru reutilizare mai rapidă. În Linux, bitul sticky afectează doar directoarele, neavând sens în cazul fișierelor.
Când bitul sticky este setat pe un director, utilizatorii pot șterge doar fișierele proprii din acel director, indiferent de permisiunile fișierelor. Nu pot șterge fișierele altora.
Aceasta permite crearea unui director ce poate fi folosit ca spațiu de stocare partajat. Fișierele sunt protejate, deoarece nimeni nu poate șterge fișierele altor utilizatori.
Creăm un director numit shared. Folosim modul simbolic o+t cu chmod pentru a seta bitul sticky pe acel director. Apoi, verificăm permisiunile directorului, precum și ale directoarelor /tmp și /var/tmp.
Introducem comenzile:
mkdir shared
sudo chmod o+t shared
ls -lh -d shared
ls -lh -d /tmp
ls -lh -d /var/tmp

Dacă bitul sticky este setat, bitul de execuție al setului de permisiuni „alții” este setat la t. Numele fișierului este evidențiat cu albastru.
Directoarele /tmp și /var/tmp sunt exemple de directoare care au toate permisiunile setate pentru proprietar, grup și alții (de aceea sunt evidențiate cu verde). Sunt folosite ca locații partajate pentru fișierele temporare.
Cu aceste permisiuni, teoretic oricine ar trebui să poată face orice. Cu toate acestea, bitul sticky suprascrie aceste permisiuni, astfel încât nimeni nu poate șterge un fișier care nu îi aparține.
Rezumat
O listă scurtă de elemente cheie:
| SUID | Funcționează doar pe fișiere. |
| SGID | Poate fi aplicat directoarelor și fișierelor. |
| Sticky Bit | Poate fi aplicat doar directoarelor. |
| Observație | Dacă indicatorii s, g sau t apar cu majuscule, bitul executabil (x) nu a fost setat. |