Członkostwo w grupach i procesy setuid / setgid

10

Procesy, które zmniejszają uprawnienia za pośrednictwem setuid()i setgid()nie wydają się dziedziczyć członkostwa w grupach ustawionego identyfikatora UID / GID.

Mam proces serwera, który należy wykonać jako root, aby otworzyć uprzywilejowany port; potem następuje eskalacja do konkretnego nieuprzywilejowanego identyfikatora UID / gid, 1 - np. użytkownika foo(UID 73). Użytkownik foojest członkiem grupy bar:

> cat /etc/group | grep bar
bar:x:54:foo

Dlatego jeśli zaloguję się jako foo, mogę odczytać plik /test.txto następujących cechach:

> ls -l /test.txt
-rw-r----- 1 root bar 10 Mar  8 16:22 /test.txt

Jednak następujący program C (kompilacja std=gnu99) po uruchomieniu roota:

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

int main (void) {
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}   

Zawsze zgłasza odmowę dostępu . Wyobrażam sobie, że ma to związek z tym, że jest to proces bez logowania, ale to rodzaj ścięgien w sposób, w jaki powinny działać uprawnienia.


1. Który często jest SOP dla serwerów, i myślę, że musi być jakiś sposób na obejście tego, ponieważ znalazłem raport o tym, że ktoś robi to z apache - apache został dodany do grupy audio i najwyraźniej może następnie użyć systemu dźwiękowego. Oczywiście dzieje się tak prawdopodobnie w rozwidleniu, a nie w oryginalnym procesie, ale w rzeczywistości sprawa jest taka sama w moim kontekście (jest to proces potomny rozwidlony po wywołaniu setuid).

Złotowłosa
źródło
Przełącz setuid()/ setgid()wywołuje.
vonbrand
@ vonbrand ROTFL Myślałem, że mam tam twarz - ale taki sam wynik, więc zredaguję pytanie, aby wyeliminować czerwony śledź.
goldilocks
1
Jeśli użyjesz setgid(54)zamiast setgid(73)(jak w /etc/groups, grupa barma gid 54), czy to działa?
lgeorget
@lgeorget Pewnie, ale to przeczy celowi. Proces potrzebuje własnego identyfikatora GID z innych powodów, a pliki te muszą mieć odpowiednie uprawnienia. Dlatego konieczne jest członkostwo w grupach w liczbie mnogiej - np. Co, jeśli masz dwóch użytkowników, którzy muszą to zrobić. Zauważ, że nie możesz setuid()ponownie po tym, jak to zrobisz ... ale, hmmm ... Myślę, że możesz z seteuid()...
goldilocks
1
Moje pytanie polegało na upewnieniu się, że nie ma gdzieś innego ukrytego subtelnego problemu. :-)
lgeorget

Odpowiedzi:

14

Problemem jest to, że setuidi setgid nie są wystarczające, aby dać swój proces wszystkie poświadczenia potrzebuje. Autoryzacje procesu zależą od

  • jego UID
  • jego GID
  • jego grupy dodatkowe
  • jego możliwości.

Zobacz, man 7 credentialsaby uzyskać bardziej szczegółowy przegląd. W twoim przypadku problem polega na tym, że poprawnie ustawiłeś UID i GID, ale nie ustawiłeś dodatkowych grup procesu. Grupa barma GID 54, nr 73, więc nie jest rozpoznawana jako grupa, w której znajduje się Twój proces.

Powinieneś zrobić

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <grp.h>

int main (void) {
    gid_t supplementary_groups[] = {54};

    setgroups(1, supplementary_groups);
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}  
lgeorget
źródło
1
To było interesujące pytanie, które zasługuje na więcej pochwał, ponieważ może być przydatne dla wielu ludzi. :-)
lgeorget
Miałem podobny problem z portami szeregowymi. Zaimplementowałem to dla dialoutgrupy i zadziałało to po raz pierwszy.
tl8 11.07.17
0

OK, trochę przetoczyłem się po sieci. Z początku myślałem, że APUE będzie zawierać wszystkie odpowiedzi, ale się myliłem . A moja kopia (stare wydanie) jest w pracy, więc ... Rozdział 5 Podręcznika administrowania Unixem i Linuksem wygląda obiecująco, ale nie mam go (tylko kopia dwóch pierwszych wydań, również w pracy).

Małe zasoby, które znalazłem (google dla „demona pisania unixa”) mówią o ważnych krokach, takich jak jak oddzielić się od tty itp. Ale nic o UID / GID. O dziwo, nawet obszerna kolekcja HOWTO na http://tldp.org nie wydaje się zawierać szczegółów. Tylko excetion Jason Short Napiszmy Linux Daemon - część I . Pełne informacje o tym, jak działa SUID / SGID i cały ten bałagan, zostały zdemistyfikowane SUID Chen, Wagnera i Deana (artykuł w USENIX 2002). Ale bądź ostrożny, Linux ma dodatkowy UID, FSUID (patrz Uwagi Woltera dotyczące niezgodności Unixa: Funkcje ustawiania UID w celu dyskusji).

Demonizacja procesu zdecydowanie nie jest dla osób o słabym sercu. Ogólne uwagi na temat bezpieczeństwa podano w D. Wheeler Secure Programming for Linux and Unix HOWTO - Creating Secure Software . Systemd obiecuje uprościć większość z nich (a tym samym zmniejszyć miejsce na błędy, które prowadzą do problemów z bezpieczeństwem), patrz instrukcja demona .

vonbrand
źródło
1
Pytanie nie dotyczy demonizacji. Pomylono bit SUID (nadając procesowi uprawnienia właściciela jego pliku wykonywalnego) setuid(), co pozwala procesowi dowolnie zmienić jego identyfikator UID. SUID zwykle ma na celu umożliwienie eskalacji uprawnień (nieuprzywilejowane -> uprzywilejowane), podczas gdy setuid()może zrobić tylko odwrotnie.
goldilocks,