1

Onderwerp: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Stel dat :
   - je een server-applicatie schrijft, bestemd voor 'gewone' clients
   - de applicatie moet bepaalde taken uitvoeren waarvoor root-privileges verplicht zijn
   - tegelijkertijd wil je, vanuit veiligheidsoverwegingen, de 'gewone' clients NIET een applicatie aanbieden die onder het root-account draait

Ik had daar laatst mee te maken; m'n applicatie moest eenmalig, bepaalde gegevens inlezen uit een tekst-bestand dat verdere informatie
bevatte die niet toegankelijk is voor het 'gewone' publiek. Ook wilde ik, voor het gemak, via chroot(), een andere root-directory emuleren.

Voor dat tekst-bestand geldt dat alleen root alle rechten heeft, verder hebben alle users en 'others' geen enkel recht.

Linux man page zegt over chroot() het volgende:
int chroot(const char *path);
chroot() changes the root directory to that specified in path. This directory will be used for pathnames beginning with /. The root directory is
inherited by all children of the current process.

Only a privileged process (Linux: one with the CAP_SYS_CHROOT capability) may call chroot(2).

Het komt erop neer dat je voor het succesvol aanroepen van chroot() root privileges moet hebben.


Ok, hoe doen we dat:
Schrijf je programma (zometeen meer daarover) en maak de executable (onder je gewone user-account.)
Log vervolgens in als root en verander de rechten mbt dit applicatie-bestand als volgt:
- verander de eigendomsrechten van de applicatie naar: de user/group root (binnen SuSe10.3 en Konqueror, rechtsklikken op het bestand
   en vervolgens  properties/Permissions kiezen)
- geef alleen de root user/group alle rechten mbt de applicatie en ontneem  alle rechten van de overige group's
- verander de advanced permissions (zo heet dat tenminste vanuit SuSe10.3 met Konqueror) van de applicatie. Selecteer Set UID en
  kies voor Add Entry, kies vervolgens voor Named User en kies uit de lijst van users het user-account waaronder je
  je applicatie wil laten draaien , geef deze user tenslotte de rx-rechten mbt het applicatie-bestand.

Als alles goed ging, zijn alleen users uit de root-group gemachtigd de applicatie te starten PLUS die ene user die via Set UID rechten heeft verkregen.

Uiteindelijk moet die ene 'user' (die waarschijnlijk niet tot de root-group behoort) slechts zeer tijdelijk, zo kort als mogelijk, die root-privileges
hebben. Dus als het tekst-bestand is ingelezen en als chroot() is uitgevoerd moeten de root-privileges uitgezet worden.
Vanuit de bovengenoemde applicatie kunnen die 'root-rechten' vrij simpel, weer ontnomen worden.



Veranderen van effective-UID vanuit je applicatie.

Onder Linux bestaan er 4 UID's (user id's) die met een proces ge-associeerd zijn: real, effective, saved and filesystem user ID's.

Binnen dit verhaaltje gaat het om het real en effectiveUID.

UI's zijn numerieke waarden, elke user heeft een uniek nummer. De waarde van het root UID is in principe altijd 0.

Stel dat je op een bepaalde Linux-doos inlogt en dat Linux jou dan een UID waarde van 1003 toekent. Als je vervolgens een programma start,
dan zijn binnen de context van dat programma je real- en effective UID in principe allebei 1003.

Tijdens het draaien van een programma controleert Linux, indien nodig, als bijvoorbeeld via het programma bestanden ge-opend worden, of de aan het programma gekoppelde effective-UID beschikt over voldoende rechten.

Dus Linux gebruikt het effective-UID voor het controleren van user-privileges !


Hierboven beschreef ik al hoe ik de privileges/ownership van m'n applicatie veranderde: owner van de applicatie is root maar via
Set UID heeft bijvoorbeeld Pietje rechten gekregen om het programma ook de draaien, verder is het programma voor niemand toegankelijk.

Als Pietje (met bijv. een UID van 1003) nu het programma start, dan zal Linux aan dat proces een real-UID van 1003 toekennen maar omdat
root de owner is van het programma zal Linux het effective-UID van de root toekennen, een effective UID van 0.
Via dit effective-UID heeft Pietje, binnen de context van het programma dus root-privileges.

Pietje is een beste kerel maar geef hem niet te lang root-privileges. Het programma moet dus gauw dat afgeschermde  bestand inlezen en ook
gauw de chroot() uitvoeren. Daarna veranderen we het effective-UID snel in 1003, vanaf dat moment heeft het programma weer
de gewone rechten die user Pietje altijd al had (en niets meer).

Hieronder de source voor een test-programmaatje. P.S., vergeet niet, nadat je het gecompileert/gelinkt hebt om de hierboven beschreven
veranderingen van de privileges/ownership uit te voeren. De naam van het zgn. afgeschermde bestand is hier "hallo.txt", voor het testen van
dit programmaatje moet je hallo.txt, via het instellen van privileges, alleen toegankelijk maken voor user/group root, de rest allemaal totaal
geen toegang/ownership.


#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int real_uid, effective_uid;
    FILE *stream;

    real_uid = getuid();
    effective_uid = geteuid();

    printf("real UID=%d  -------- effective UID=%d\n", real_uid, effective_uid);

    if ((stream = fopen("hallo.txt", "r")) == NULL)
        {
        printf ("1 - Kan bestand niet openen (moet toch kunnen)\n");
        return(1);
    }
    else
    {
        printf("Eerste maal:File succesvol geopend (klopt), gaan hem nu weer sluiten\n\n\n");
        fclose(stream);
    }

    printf("Gaan nu effective_uid gelijk maken aan real_uid en dan kijken of\n"
           "de file hallo.txt van root nog steeds geopend mag worden (zou niet mogen)\n\n");

    seteuid(real_uid);

    if ((stream = fopen("hallo.txt", "r")) == NULL)
    {
        printf ("2 - Kan bestand niet openen (dat klopt)\n\n");
        //return(1);
    }
    else
    {
        printf("Tweede maal:File succesvol geopend (zou niet mogen), gaan hem nu weer sluiten\n\n\n");
        fclose(stream);
    }

    return(1);
}

2

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Ik zou het gewoon met rechten regelen.
- creeer een groep xyz
- zorg dat de betreffende mensen lid zijn van die groep
- zorg dat de betreffende files onder die groep te lezen zijn.

Alternatief (lijkt er aardig op)
maak gebruik van setgid om de bestanden te kunnen lezen, al heb je daar natuurlijk de nodige rechten voor nodig.

Ook kun je nog gebruik maken van het suid bit, maar das natuurlijk zoals bekend geen verstandige oplossing.

Pascal's Blobfree Homepage
Een dag geen NedLinux is een dag niet geleefd

3

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Groep xyz zal niet altijd voldoende zijn omdat je bijv. chroot() alleen als root mag aanroepen en als je server-applicatie bijv. een web/socketserver is, wil je de clients via een 'minimaal account'  toegang tot je server geven.

4

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Geen idee wat je van plan bent, maar het klinkt iig gruwelijk eng !
kenlijk wil je gebruikers zelf iets laten beheren. altijd vragen om problemen.
Als je het goed wilt doen laat gebruikers dan een bestandje aanmaken waarin beschreven wordt wat er moet gebeuren, en laat het verder door een crontaak oplossen.

Ok... een ouderwetse oplossing maar wel heel wat beter dan al die smerige webbased dingen van tegenwoordig doen.

Pascal's Blobfree Homepage
Een dag geen NedLinux is een dag niet geleefd

5 Laatst bewerkt door chromisX (17 Sep 2009 16:02:39)

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Wat pascal waarschijnlijk probeert te zeggen is dat je een dergelijk resultaat (dat met die file) gewoon met rechten valt te regelen, maar natuurlijk valt er een constructie te bedenken waarvoor dat net niet kan en daarom moet je dan door allerlei hoepels springen. Dat gebeurt voornamelijk als je met anderen te maken hebt die het nou eenmaal zo hebben ingeregeld.

GeorgeE schreef:

Groep xyz zal niet altijd voldoende zijn omdat je bijv. chroot() alleen als root mag aanroepen en als je server-applicatie bijv. een web/socketserver is, wil je de clients via een 'minimaal account'  toegang tot je server geven.

Normaliter doe je "the other way around": je start je daemon als root, doet chroot of een socket aanmaken, en vervolgens verander je de relevante UID's naar diegene van de gebruiker (b.v. http of xyz).

6

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

@chromisX:
dat bedoel ik dus zo ongeveer.

@pascal:
Wat is er mis met "die smerige webbased dingen van tegenwoordig" ?
Ik ben bezig een web-servertje te maken met een paar specifieke eigenschappen (epoll en comet).

7

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

George,

Die dingen maken overal een puinhoop van.
Dit leid in zeer veel gevallen tot een (web)server met de nodige problemen.
Maar ach wat maak ik mij weer druk. niemand is geintereseerd in een fatsoenlijk opgezet systeem.

Pascal's Blobfree Homepage
Een dag geen NedLinux is een dag niet geleefd

8

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Pascal,
ik stel wel belang in fatsoenlijk opgezette systemen en denk dat dat ook haalbaar kan zijn bij web-applicaties.

Wat is er volgens jou (principieel ?) fout aan webbased systemen?

9

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Dit lijkt me een discussie die beter in een nieuw topic kan worden gehouden

Help mee om KDE 5 in het Nederlands te vertalen!!

10

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Hmmm George,  Rinse heeft in princype gelijk al zijn er diverse threads die over dit onderwerp gaan.
Kijk gewoon eens een beetje rond op de afdeling Netwerk beveiliging en server software in zo'n beetje elke thread met als koptekst in de trant van ik ben 12 jaar en wil de beste isp van Nederland worden komt dit uitgebreid aan de orde.
Webbased beheerde systemen hebben als regel grote veiligheids issues of zorgen (meestal ongemerkt) voor een hoop overlast.
Meer dan eens ben ik in paniek gebeld om een dergelijk systeem te fixen nadat het door de eigenaar, of door een grapjas opgeblazen was.
Beheertools als DirectAdmin, Plesk en hoe ze ook mogen heten veroorzaken een hoop elende.
Ligt overigens niet altijd aan het paket maar vaak ook aan de onwetendheid van de beheerder.

Een zelfde probleem kom je bij wel meer van dergelijke pakketen tegen.
Neem nu phpMyAdmin.
Op zich heel aardig, maar daar slechts een beperkte groep beheerders weet hoe je een db moet inregelen zodanig dat iedere gebruiker de juiste rechten heeft.

Zoek voor de aardigheid eens op dit forum naar chmod 777.
Voor vrijwel al deze posts geld dat de schrijver ervan maar beter geen beheerder kan zijn, dat zullen slechts weinigen ontkennen.

Terug naar je onderwerp.
Zoals ik aangaf laat de gebruiker een soort van menu samen stellen.
Dat kun je mooi bij elkaar klikken.
Controleer goed of dat menu geen fouten of ranzige issues bevat (regexpen zijn daar ideaal voor) vervolgens laat je een script dat regelmatig en automatisch gestart wordt de boel verwerken.
Vroeger werkte de meeste isp's zo.

Pascal's Blobfree Homepage
Een dag geen NedLinux is een dag niet geleefd

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Behalve de terechte kritiek van Pascal en ChromisX (je doet het gewoonlijk inderdaad andersom, als root beginnen, chrooten() en dan privileges 'droppen'): chroot is niet veilig. Tenminste niet zonder veel andere maatregelen (bijvoorbeeld een goed ingesteld mandatory access control framework). Googlen naar 'break out chroot' zal genoeg literatuur verschaffen wink.

12

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Ik zie overigens (wellicht om door Daniel genoemde reden) nog maar weinig Hosters die hun beveiliging op een chroot gooien.
Meestal is het gewoon een eigen home dir waaronder de webdir hangt (ik ga gemakshalve even uit van een webserver, want dat is wat iedereen wil en waarover iedereen vragen stelt)

Pascal's Blobfree Homepage
Een dag geen NedLinux is een dag niet geleefd

Re: C programmeren: Tijdelijk root-privileges geven aan gewone gebruiker

Ik snap dat het soms moeilijk is om pakketten als DirectAdmin en consorten te gebruiken. Enige mager acceptabele pakketje is Webmin (en evt usermin en virtualmin).

Meer weten over security-issues.... http://www.mrleejohn.nl/linux-security.htm