Hvordan bruger jeg capsh: Jeg forsøger at køre en uprivilegeret ping med minimale muligheder
On februar 13, 2021 by adminJeg eksperimenterer med muligheder på Debian Gnu / Linux.
Jeg har kopieret / bin / ping til min nuværende arbejdsmappe. Som forventet fungerer det ikke, det var oprindeligt setuid-rod.
Jeg giver derefter min ping de minimale muligheder (ikke root) ved at udføre sudo /sbin/setcap cap_net_raw=ep ./ping
, og min ping fungerer som forventet.
Derefter sudo /sbin/setcap -r ./ping
for at tilbagekalde denne mulighed. Det fungerer nu ikke som forventet.
Jeg prøver nu at få ping til at arbejde ved hjælp af capsh
.
capsh
har ingen privilegier, så jeg er nødt til at køre det som root, men slip derefter root og dermed alle andre privilegier.
Jeg tror, jeg også har brug for secure-keep-caps
, dette er ikke dokumenteret i capsh
, men er i kapaciteten brugervejledning. Jeg fik bitnumrene fra /usr/include/linux/securebits.h
. De ser ud til at være korrekte, da output fra --print
viser, at disse bits er korrekte.
Jeg har rodet i timevis, indtil videre har jeg dette.
sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"
Dog ping
fejl med ping: icmp open socket: Operation not permitted
, dette er hvad der sker, når det ikke har kapacitet. Også --print
viser Current: =p cap_net_raw+i
, dette er ikke nok, vi har brug for e
.
sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"
indstiller evnen til Current: = cap_net_raw+eip
dette er korrekt, men efterlader os som root
.
Edit-1
Jeg har nu prøvet sudo /sbin/capsh --keep=1 --secbits=0x11 --caps=cap_net_raw+epi --print -- -c "touch zz; ./ping -c1 localhost;"
Dette giver:
touch: cannot touch `zz": Permission denied ping: icmp open socket: Operation not permitted
Den første fejl forventes som secure-noroot: yes
Men den anden er ikke Current: = cap_net_raw+eip
Edit-2
Hvis jeg sætter ==
før --print
, er det nu viser Current: = cap_net_raw+i
, så det forklarer den tidligere fejl, men ikke hvorfor vi mister kapaciteten, når vi skifter ud af root, men jeg skal dog have, at secure-keep-caps
ordne det.
Edit-3
Fra det jeg kan se, mister jeg Effektiv (e) og Tilladt (p), når exec kaldes. Dette forventes, men jeg troede, at sikre opbevaringshætter skulle forhindre dem i at gå tabt. Mangler jeg noget.
Edit-4
Jeg har forsket mere og læst vejledningen igen. Det ser ud til, at normalt e
og p
går tabt, når: du skifter fra bruger root
(eller anvend secure-noroot
, hvilket gør root til en normal bruger), dette kan tilsidesættes med secure-keep-caps
; når du ringer til exec
, så vidt jeg kan se, er dette en invariant.
Så vidt jeg kan se, fungerer det i henhold til manualen. Så vidt jeg kan fortælle, er der ingen måde at gøre noget nyttigt med capsh
. Så vidt jeg kan fortælle, skal du bruge kapaciteter for at bruge filfunktioner eller have et program, der er opmærksom på funktioner, der ikke bruger exec
. Derfor ingen privilegeret indpakning.
Så nu er mit spørgsmål, hvad jeg mangler, hvad er capsh
til.
Edit-5
Jeg har tilføjet et svar til omgivelsesfunktioner. Måske kan capsh
også bruges med nedarvede funktioner, men for at være nyttige skal disse indstilles på den eksekverbare fil. Jeg kan ikke se, hvordan capsh kan gøre noget nyttigt uden omgivende kapaciteter eller tillade nedarvede funktioner.
Versioner:
-
capsh
fra pakkelibcap2-bin
version1:2.22-1.2
- før edit-3 Jeg greb den seneste
capsh
fragit://git.debian.org/collab-maint/libcap2.git
og begyndte at bruge det. -
uname -a
Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
Bruger-land er 32bit.
Kommentarer
- Forsøgte du Lekensteyns eksempel med et senere frigivelse opstrøms ? At få
capsh
fra collab-maint repo ville ikke have givet dig den “seneste”capsh
, Debian-pakken understøtter stadig ikke omgivende kapaciteter. Opstrøms 2.27 gør. - @StephenKitt godt at vide, men det originale spørgsmål er, hvad der er
capsh
, i fravær af omgivende (som det oprindeligt var). Hvad overser jeg. Det skal have en brug.
Svar
Funktioner er egenskaber ved processer. Traditionelt er der tre sæt:
- Tilladte muligheder ( p ): evner, der kan være “aktiveret” i den aktuelle proces.
- Effektiv kapacitet ( e ): funktioner, der i øjeblikket er anvendelige i den nuværende proces.
- Arvelige funktioner ( i ): filfunktioner, der muligvis nedarves.
Programmer, der kører som root, har altid fulde tilladte og effektive kapaciteter, så “tilføjelse” til flere funktioner har ingen mærkbar effekt. (Det arvelige kapacitetssæt er normalt tomt.) Med setcap cap_net_raw+ep ping
aktiverer du disse funktioner som standard for enhver bruger, der kører dette program.
Desværre er disse funktioner bundet til eksekveret fil og bevares ikke efter udførelse af en ny underordnet proces. Linux 4.3 introducerede Omgivelsesfunktioner , som gør det muligt at arve kapaciteter af underordnede processer. (Se også Transformation af kapaciteter under execve () i -funktioner (7) .)
Mens du spiller med kapaciteter, bemærk disse faldgruber:
- Når du skifter bruger fra rod til ikke-rod, ryddes de effektive og tilladte muligheder (se Effekt af ændringer af bruger-ID på kapaciteter i -funktioner (7) ). Du kan bruge indstillingen
--keep=1
tilcapsh
for at undgå at rydde sætene. - Sættet til omgivende funktioner ryddes, når du ændring af bruger- eller gruppe-ider. Løsning: tilføj de omgivende funktioner efter ændring af bruger-idet, men før udførelse af en underordnet proces.
- En kapacitet kan kun føjes til de omgivende muligheder indstilles, hvis det allerede findes i både det tilladte og arvelige kapacitetssæt.
Siden libcap 2.26 fik capsh
-programmet evnen til at ændre omgivende kapaciteter via indstillinger som --addamb
( commit ). Bemærk, at valgordren er vigtig. Eksempel på brug:
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"
Tip: Du kan tilføje --print
mulighed overalt i capsh
kommandolinje og se dens aktuelle kapacitetsstatus.
Bemærk: cap_setpcap
er nødvendig til --addamb
mens der er behov for cap_setuid,cap_setgid
til --user
-muligheden.
Kommentarer
- Hvilket specifikt versionsnummer på libcap har siden capsh –addamb? 2.32 frigivelsesnotater nævnte nye capsh-funktioner, men ordene var vage.
- @ 把 友情 留 在 无 盐 Da svaret oprindeligt blev skrevet, understøttede kun git master det. Siden da er libcap 2.26 blevet frigivet med understøttelse af indstillingen
--addamb
. Jeg har opdateret svaret i overensstemmelse hermed. - Desværre er disse funktioner bundet til den udførte fil og bevares ikke efter udførelse af en ny underordnet proces. – af underordnet proces Jeg tænker normalt på
fork(2)
, som arver funktionerne. Kunexecve(2)
arver ikke ‘ t funktionerne, men det skaber ikke ‘ t et barn behandle. Har jeg forkert? - Citering
man capabiltiies
: Et barn oprettet viafork(2)
arver kopier af sin forælder ‘ s kapacitetssæt.
Svar
Lekensteyns svar virker nøjagtigt og komplet, men jeg vil forsøge at give en anden forklaring fra en anden vinkel, som vil forsøge at understrege det problem, som de omgivende kapaciteter, der er indstillet, løser. “>
Der er to systemopkald af interesse, der får kapaciteter til at blive genberegnet (og potentielt droppet):
-
setuid
: Ifølgeman capabilities
:
SECBIT_KEEP_CAPS Indstilling af dette flag tillader en tråd, der har en eller flere 0 UIDer for at bevare sine kapaciteter, når den skifter alle sine UIDer til en ikke-nul-værdi. Hvis dette flag ikke er indstillet, får en sådan UIDswitch tråden til at miste alle muligheder.
Med andre ord, i vores capsh
-kommando ovenfor skal vi sørge for, at SECBIT_KEEP_CAPS er indstillet under setuid
systemopkald. Ellers går alle evner tabt. Dette gør --keep=1
. Så nu bliver kommandoen sudo capsh --user=<some_user> --keep=1 --
-
execve
: Hvis vi brug indstillingen--keep=1
, alle kapacitetssæt (effektive, tilladte, arvelige) bevares indtilexecve
systemopkald, menexecve
får kapaciteter til at blive genberegnet (for ikke-root-brugere) og også en ikke så indlysende måde.Kort sagt, før tilføjelsen af de omgivende kapaciteter er indstillet , for en mulighed for at være i en tråd “s” tilladt ” indstillet efter etexecve
-opkald, enten:- Filen skal have den mulighed i sit “tilladte” sæt . Dette kan gøres med
setcap cap_net_raw+p /bin/bash
. Hvis du gør dette, bliver hele øvelsen ubrugelig, da trådens kapacitetssæt (bortset fra afgrænsningssættet) ikke længere har nogen effekt. - Både filen og tråden skal have den kapacitet i deres “arvelige” sæt . Du tror måske, at
setcap cap_net_raw+i
ville gøre tricket, men det viser sig, atexecve
får en tråds nedarvelige tilladelser til at blive droppet, når de kaldes af en uprivilegeret bruger (som vi i øjeblikket er takket væresetuid
). Så der er ingen måde at tilfredsstille denne betingelse som en privilegeret bruger.
- Filen skal have den mulighed i sit “tilladte” sæt . Dette kan gøres med
Omgivelsesfunktioner introduceret i Linux 4.3 gør det muligt for en tråd at beholde sine kapaciteter, selv efter en setuid
til en uprivilegeret bruger efterfulgt af en execve
, uden at skulle stole på filfunktioner.
Svar
Der kan være en fejl / funktion i kernen. Der har været diskussion:
- https://bugzilla.altlinux.org/show_bug.cgi?id=16694
- http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-03/5224.html
Jeg aner ikke, om noget har været d en, for at rette det.
Må ikke misforstå mig – den nuværende adfærd er sikker. Men det er så sikkert, at det kommer i vejen for ting, der ser ud til at virke.
Rediger: I henhold til http://man7.org/linux/man-pages/man7/capabilities.7.html der er et nyt kapacitetssæt Ambient (siden Linux 4.3). Det ser ud til, at dette tillader det, der er nødvendigt.
Svar
En let justering af Lekensteyns svar giver en kortere påkaldelse for nylige kerner:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw -- \ -c "./ping -c1 localhost"
Bemærk: Afhængigt af din sudoers-fil kan dette gøre et rod i dit miljø (f.eks. ændre HOME). capsh vil ændre dit uid, men det vil ikke gøre noget for at gendanne sudos miljøændringer.
Så hvad sker der her? Lad os se:
-
sudo /usr/sbin/capsh
: Vi starter som root, som har alle muligheder i dets effektive (kan gøre dette) og tilladt (kan tilføje dette til effektive) sæt, men intet i de andre sæt . Vi dækker de andre sæt på et øjeblik. -
--keep=1
: Af sikkerhedsmæssige årsager (læs: ældre) arver kapaciteter normalt ikke på tværs af root- > ID-switches, der ikke er rod. Dette flag muliggør en funktion, kendt somSECBIT_KEEP_CAPS
, der tillader dette. Værd at bemærke, at det automatisk ryddes ved exec , hvilket er en god idé. -
--user=$USER
: Nu hvor vi ikke mister alle vores evner ved UID-ændring, falder vi ud af root. Takket væreSECBIT_KEEP_CAPS
bevarer vi rodlignende privilegier, hvilket lader os yderligere rodne med vores muligheder. -
--inh=cap_net_raw
: Dette føjer vores målkapacitet til det arvelige sæt, fordi du ikke kan gøre en kapacitet omgivende (se næste punkt), hvis det ikke er arveligt. -
--addamb=cap_net_raw
: Selvom vi “har anmodet omSECBIT_KEEP_CAPS
,execve
af en uprivilegeret (ingen setuid / setgid / setcap) binær vil stadig ryd vores kapaciteter, hvilket resulterer i ingen privilegier. Linux 4.3 tilføjede det omgivende sæt, som føjes tilbage til de effektive og tilladte sæt, når der udføres ikke-privilegerede binære filer. Perfekt! “>
: Efter at have sat alt op, udfører vi bash med disse args. Funktionssættene er ryddet (fordi bash er uprivilegeret), det omgivende sæt tilføjes tilbage, og voila! Vi har den nødvendige tilladelse til at åbne rå stikkontakter.
Du kan kontrollere dette ved hjælp af det specielle ==
argument til capsh, hvilket får det til at udføre sig selv med resten af kommandolinjen:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw == --print Current: = cap_net_raw+eip
Hvilket betyder, at vi har cap_net_raw som effektiv (kan gøre det), arvelig (kan videregive det til underordnede processer) og tilladt (har lov til at få det). Og ingen andre funktioner i nogen af disse.
For mere information om kapaciteter, og hvordan de fungerer, er dit bedste valg mandssiden . Specifikt overskriften Transformation of capabilities during execve()
.
--user
var ikke ‘ t ændret, har du ‘ stadig de nødvendige muligheder senere?