Jak używać capsh: Próbuję uruchomić nieuprzywilejowany ping z minimalnymi możliwościami
On 13 lutego, 2021 by adminEksperymentuję z możliwościami na Debian Gnu / Linux.
Skopiowałem / bin / ping do mojego bieżącego katalogu roboczego. Zgodnie z oczekiwaniami to nie działa, pierwotnie był to setuid root.
Następnie daję mojemu pingowi minimalne możliwości (nie root), wykonując sudo /sbin/setcap cap_net_raw=ep ./ping
, a ping działa zgodnie z oczekiwaniami.
Następnie sudo /sbin/setcap -r ./ping
, aby odwołać tę możliwość. Teraz nie działa zgodnie z oczekiwaniami.
Teraz próbuję uruchomić ping używając capsh
.
capsh
nie ma żadnych uprawnień, więc muszę uruchomić go jako root, ale potem porzucić root i wszystkie inne uprawnienia.
Myślę, że potrzebuję również secure-keep-caps
, nie jest to udokumentowane w capsh
, ale jest w stanie podręcznik. Numery bitów otrzymałem z /usr/include/linux/securebits.h
. Wydają się być poprawne, ponieważ dane wyjściowe --print
pokazują, że te bity są poprawne.
Bawiłem się przez wiele godzin, do tej pory mam to.
sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"
Jednak ping
błędy z ping: icmp open socket: Operation not permitted
tak się dzieje, gdy nie ma takiej możliwości. Również --print
pokazuje Current: =p cap_net_raw+i
, to nie wystarczy, że potrzebujemy e
.
sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"
ustawi możliwość Current: = cap_net_raw+eip
jest to poprawne, ale pozostawia nas jako root
.
Edit-1
Próbowałem teraz sudo /sbin/capsh --keep=1 --secbits=0x11 --caps=cap_net_raw+epi --print -- -c "touch zz; ./ping -c1 localhost;"
Daje to:
touch: cannot touch `zz": Permission denied ping: icmp open socket: Operation not permitted
Pierwszy błąd jest oczekiwany jako secure-noroot: yes
Ale drugi to nie Current: = cap_net_raw+eip
Edit-2
Jeśli wstawię ==
przed --print
, to teraz pokazuje Current: = cap_net_raw+i
, więc to wyjaśnia poprzedni błąd, ale nie dlaczego tracimy możliwości przy wyłączaniu z roota, myślę, że secure-keep-caps
powinno napraw to.
Edit-3
Z tego co widzę, tracę Effective (e) i Permitted (p), kiedy wywoływana jest exec. Jest to oczekiwane, ale pomyślałem, że bezpieczne czapki powinny zapobiec ich zgubieniu. Czy coś mi brakuje.
Edycja-4
Poszedłem więcej badań i ponownie przeczytałem instrukcję. Wygląda na to, że zwykle funkcje e
i p
są tracone, gdy: zmieniasz się z użytkownika root
(lub zastosuj secure-noroot
, czyniąc roota zwykłym użytkownikiem), można to zmienić za pomocą secure-keep-caps
; kiedy dzwonisz do exec
, o ile wiem, jest to niezmienne.
O ile wiem, działa zgodnie z instrukcją. O ile wiem, nie ma sposobu na zrobienie niczego pożytecznego z capsh
. O ile wiem, aby korzystać z możliwości, musisz: używać możliwości plików lub mieć program uwzględniający możliwości, który nie używa exec
. Dlatego nie ma uprzywilejowanego opakowania.
Więc teraz moje pytanie brzmi: czego mi brakuje, do czego służy capsh
.
Edit-5
Dodałem odpowiedź dotyczącą możliwości otoczenia. Być może capsh
może być również używane z dziedziczonymi funkcjami, ale aby były użyteczne, musiałyby być ustawione w pliku wykonywalnym. Nie widzę, jak capsh może zrobić cokolwiek pożytecznego bez możliwości otoczenia lub pozwolić na dziedziczenie możliwości.
Wersje:
-
capsh
z pakietulibcap2-bin
wersja1:2.22-1.2
- przed edit-3 Mam najnowszy
capsh
zgit://git.debian.org/collab-maint/libcap2.git
i zacząłem go używać. -
uname -a
Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
Obszar użytkownika jest 32-bitowy.
Komentarze
Odpowiedź
Możliwości są właściwościami procesów. Tradycyjnie istnieją trzy zestawy:
- Dozwolone możliwości ( p ): możliwości, które mogą być „aktywowano” w bieżącym procesie.
- Efektywne możliwości ( e ): możliwości, które są aktualnie dostępne w obecnym procesie.
- Dziedziczone możliwości ( i ): możliwości plików, które mogą być dziedziczone.
Programy uruchamiane z uprawnieniami administratora zawsze mają pełne dozwolone i efektywne możliwości, więc „dodawanie” kolejnych możliwości nie ma zauważalnego efektu. (Zestaw dziedziczonych możliwości jest zwykle pusty). Z setcap cap_net_raw+ep ping
domyślnie włączasz te możliwości dla każdego użytkownika uruchamiającego ten program.
Niestety, te możliwości są powiązane z wykonywany plik i nie są zachowywane po wykonaniu nowego procesu potomnego. W Linuksie 4.3 wprowadzono Możliwości otoczenia , które pozwalają na dziedziczenie możliwości przez procesy potomne. (Zobacz także Transformacja możliwości podczas execve () w Możliwości (7) .)
Podczas zabawy możliwości, zwróć uwagę na następujące pułapki:
- Podczas zmiany użytkownika z roota na innego niż root, efektywne i dozwolone możliwości są czyszczone (zobacz Wpływ zmian identyfikatora użytkownika na możliwości w możliwościach (7) ). Możesz użyć opcji
--keep=1
capsh
, aby uniknąć czyszczenia zestawów. - Zestaw możliwości otoczenia jest czyszczony, gdy zmiana identyfikatorów użytkowników lub grup. Rozwiązanie: dodaj możliwości otoczenia po zmianie identyfikatora użytkownika, ale przed wykonaniem procesu potomnego.
- Zdolność można dodać tylko do możliwości otoczenia set, jeśli jest już w zestawie dozwolonych i dziedziczonych możliwości.
Od libcap 2.26, program capsh
uzyskał możliwość modyfikowania możliwości otoczenia za pomocą opcji, takich jak --addamb
( zatwierdzenie ). Zauważ, że kolejność opcji jest znacząca. Przykładowe zastosowanie:
sudo capsh --caps="cap_net_raw+eip cap_setpcap,cap_setuid,cap_setgid+ep" \ --keep=1 --user=nobody --addamb=cap_net_raw -- \ -c "./ping -c1 127.0.0.1"
Wskazówka: możesz dodać opcję --print
w dowolnym miejscu capsh
wiersza poleceń i zobacz jego aktualny stan możliwości.
Uwaga: cap_setpcap
jest potrzebny dla --addamb
podczas gdy cap_setuid,cap_setgid
są potrzebne dla opcji --user
.
Komentarze
- Jaki konkretny numer wersji libcap ma od tego czasu capsh –addamb? Uwagi do wydania 2.32 wspominały o nowych funkcjach capsh, ale słowa były niejasne.
- @ 把 友情 留 在 无 盐 Kiedy pierwotnie pisano odpowiedź, obsługiwany był tylko przez git master. Od tamtej pory libcap 2.26 został wydany z obsługą opcji
--addamb
. Odpowiednio zaktualizowałem odpowiedź. - Niestety te możliwości są powiązane z wykonywanym plikiem i nie są zachowywane po wykonaniu nowego procesu potomnego. – przez proces potomny Zwykle myślę o
fork(2)
, który dziedziczy możliwości. Tylkoexecve(2)
nie ' dziedziczy możliwości, ale nie ' nie tworzy dziecka proces. Czy się mylę? - Cytując
man capabiltiies
: Dziecko utworzone za pomocąfork(2)
dziedziczy kopie swojego rodzica ' zestawy możliwości.
Odpowiedź
Odpowiedź Lekensteyna wydaje się dokładna i kompletna, ale spróbuję przedstawić inne wyjaśnienie z innego punktu widzenia, które spróbuję podkreślić problem, który rozwiązuje zestaw funkcji otoczenia.
Po uruchomieniu sudo capsh --user=<some_user> --
Istnieją 2 interesujące wywołania systemowe, które powodują ponowne obliczenie (i potencjalne odrzucenie) możliwości:
-
setuid
: Zgodnie zman capabilities
:
SECBIT_KEEP_CAPS Ustawienie tej flagi zezwala na wątek, który ma co najmniej jeden identyfikator UID aby zachować swoje możliwości, gdy zmienia wszystkie swoje identyfikatory UID na wartość niezerową. Jeśli ta flaga nie jest ustawiona, taki przełącznik UID powoduje utratę wszystkich możliwości wątku.
Innymi słowy, w naszym capsh
poleceniu powyżej musimy upewnić się, że SECBIT_KEEP_CAPS jest ustawiony podczas setuid
wywołanie systemowe. W przeciwnym razie utracone zostaną wszystkie możliwości. To właśnie robi --keep=1
. Teraz polecenie zmienia się w sudo capsh --user=<some_user> --keep=1 --
-
execve
: Jeśli użyj opcji--keep=1
, wszystkie zestawy możliwości (efektywne, dozwolone, dziedziczone) są zachowane do wywołanie systemoweexecve
, jednakexecve
powoduje również ponowne obliczenie możliwości (dla użytkowników innych niż root) i nie tak oczywisty sposób.Krótko mówiąc, przed dodaniem możliwości otoczenia ustaw , aby możliwe było bycie w wątku „s” dozwolone ” po wywołaniuexecve
, albo:- Plik musi mieć tę możliwość w swoim „dozwolonym” zestawie . można wykonać za pomocą
setcap cap_net_raw+p /bin/bash
. W ten sposób całe ćwiczenie staje się bezużyteczne, ponieważ zestawy możliwości wątku (inne niż zestaw ograniczający) nie mają już żadnego efektu. - Zarówno plik, jak i wątek muszą mieć tę możliwość w swoich „dziedzicznych” zestawach . Możesz pomyśleć, że
setcap cap_net_raw+i
załatwi sprawę, ale okazuje się, żeexecve
powoduje porzucenie nieodkrytych uprawnień wątku, gdy zostanie wywołany przez użytkownik nieuprzywilejowany (którym obecnie jesteśmy dziękisetuid
). Nie ma więc możliwości spełnienia tego warunku jako użytkownik nieuprzywilejowany.
- Plik musi mieć tę możliwość w swoim „dozwolonym” zestawie . można wykonać za pomocą
Możliwości otoczenia wprowadzone w Linuksie 4.3 umożliwiają wątkowi zachowanie swoich możliwości nawet po setuid
do nieuprzywilejowanego użytkownika, po którym następuje execve
, bez konieczności polegania na możliwościach plików.
Odpowiedź
W jądrze może być błąd / funkcja. Odbyła się dyskusja:
- https://bugzilla.altlinux.org/show_bug.cgi?id=16694
- http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-03/5224.html
Nie mam pojęcia, czy coś zostało d jeden, aby to naprawić.
Nie zrozum mnie źle – obecne zachowanie jest bezpieczne. Ale jest tak bezpieczny, że przeszkadza w działaniu, które wydaje się działać.
Edycja: Zgodnie z http://man7.org/linux/man-pages/man7/capabilities.7.html jest nowy zestaw możliwości Ambient (od Linuksa 4.3). Wygląda na to, że pozwoli to na to, co jest potrzebne.
Odpowiedź
Nieznaczne dostosowanie odpowiedzi Lekensteyn daje krótsze wywołanie dla najnowszych jąder:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw -- \ -c "./ping -c1 localhost"
Uwaga: w zależności od pliku sudoers może to spowodować bałagan w twoim środowisku (np. zmiana HOME). capsh zmieni twój uid, ale nie zrobi nic, by cofnąć zmiany środowiska sudo.
Więc o co tu chodzi? Zobaczmy:
-
sudo /usr/sbin/capsh
: Zaczynamy jako root, który ma wszystkie możliwości w swoich efektywnych (może to zrobić) i dozwolonych (może dodać to do efektywnych) zestawach, ale nic w innych zestawach . Za chwilę zajmiemy się tymi innymi zestawami. -
--keep=1
: Ze względów bezpieczeństwa (czytaj: starsze) możliwości zwykle nie dziedziczą po root- > przełączniki identyfikatora innego niż root. Ta flaga włącza funkcję o nazwieSECBIT_KEEP_CAPS
, która na to pozwala. Warto zauważyć, że jest ona automatycznie czyszczona przy exec , co jest dobrym pomysłem. -
--user=$USER
: Teraz, gdy nie stracimy wszystkich naszych możliwości przy zmianie UID, wypadamy z roota. DziękiSECBIT_KEEP_CAPS
zachowujemy przywileje roota, co pozwala nam jeszcze bardziej zepsuć nasze możliwości. -
--inh=cap_net_raw
: Dodaje to naszą docelową zdolność do dziedziczonego zbioru, ponieważ nie można utworzyć otoczenia zdolności (zobacz następny element), jeśli nie jest ona dziedziczona. -
--addamb=cap_net_raw
: Mimo że zażądaliśmySECBIT_KEEP_CAPS
,execve
nieuprzywilejowanego (bez setuid / setgid / setcap) pliku binarnego będzie nadal wyczyść nasze możliwości, co spowoduje brak uprawnień. Linux 4.3 dodał zestaw otoczenia, który jest dodawany z powrotem do efektywnych i dozwolonych zestawów podczas wykonywania nieuprzywilejowanych plików binarnych. Idealnie! -
-- -c ...
: Po skonfigurowaniu wszystkiego wykonujemy bash z tymi argumentami. Zestawy możliwości są wyczyszczone (ponieważ bash jest nieuprzywilejowany), zestaw otoczenia jest dodawany z powrotem i voila! Mamy niezbędne uprawnienia do otwierania surowego gniazd.
Możesz to sprawdzić za pomocą specjalnego ==
argument capsh, który powoduje, że wykonuje się sam z resztą wiersza poleceń:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw == --print Current: = cap_net_raw+eip
Co oznacza, że mamy cap_net_raw jako efektywny (może to zrobić), dziedziczony (może przekazać to procesom potomnym) i dozwolony (może to uzyskać). I żadnych innych możliwości w żadnej z nich.
Aby uzyskać więcej informacji na temat możliwości i sposobu ich działania, najlepszym rozwiązaniem jest strona podręcznika opisująca możliwości (7) . W szczególności nagłówek Transformation of capabilities during execve()
.
Komentarze
- Co masz na myśli przez To jest zrobione wcześnie, ponieważ wymaga wielu dodatkowych możliwości, które ' nie mogą spaść, dopóki nie ' skończone. ?W Twoim przypadku wykonujesz jako ” root „, więc nawet w ten sposób
--user
nie było ' nie zmieniłeś, ' czy nadal masz potrzebne funkcje później? - Dziękuję za zwrócenie uwagi! Poprzednia wersja tego wiersza poleceń wyraźnie porzucała privs, więc wcześniej było konieczne ustawienie setuid. Teraz, gdy uprawnienia są domyślnie usuwane jako część exec, ' nie jest konieczne.
capsh
z repozytorium collab-maint nie dałoby ci „najnowszego”capsh
, pakiet Debiana nadal nie obsługuje możliwości otoczenia. Upstream 2.27 tak.capsh
, gdy nie ma otoczenia (tak jak było pierwotnie). Czego mi brakuje. Musi mieć zastosowanie.