Hur använder jag capsh: Jag försöker köra en okontrollerad ping, med minimala funktioner
On februari 13, 2021 by adminJag experimenterar med funktioner på Debian Gnu / Linux.
Jag har kopierat / bin / ping till min nuvarande arbetskatalog. Som förväntat fungerar det inte, det var ursprungligen setuid root.
Jag ger sedan min ping minimala möjligheter (inte root) genom att göra sudo /sbin/setcap cap_net_raw=ep ./ping
och mitt ping fungerar som förväntat.
Då sudo /sbin/setcap -r ./ping
för att återkalla den möjligheten. Det fungerar nu inte som förväntat.
Jag försöker nu få ping till att fungera med capsh
.
capsh
har inga behörigheter, så jag måste köra det som root, men sedan släppa root och därmed alla andra behörigheter.
Jag tror att jag också behöver secure-keep-caps
, detta är inte dokumenterat i capsh
, men har kapacitet manuell. Jag fick bitnumren från /usr/include/linux/securebits.h
. De verkar vara korrekta, eftersom utdata från --print
visar att dessa bitar är korrekta.
Jag har lurat i timmar, hittills har jag det här.
sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"
Men ping
fel med ping: icmp open socket: Operation not permitted
, detta är vad som händer när det inte har kapacitet. Även --print
visar Current: =p cap_net_raw+i
, detta räcker inte, vi behöver e
.
sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"
ställer in kapaciteten till Current: = cap_net_raw+eip
detta är korrekt, men lämnar oss som root
.
Edit-1
Jag har nu försökt sudo /sbin/capsh --keep=1 --secbits=0x11 --caps=cap_net_raw+epi --print -- -c "touch zz; ./ping -c1 localhost;"
Detta ger:
touch: cannot touch `zz": Permission denied ping: icmp open socket: Operation not permitted
Det första felet förväntas som secure-noroot: yes
Men det andra är inte Current: = cap_net_raw+eip
Edit-2
Om jag lägger ==
före --print
är det nu visar Current: = cap_net_raw+i
, så det förklarar det föregående felet, men inte varför vi tappar förmågan när vi byter från roten, men jag secure-keep-caps
fixa det.
Edit-3
Från vad jag kan se förlorar jag Effektiv (e) och Tillåtet (p) när exec kallas. Detta förväntas, men jag trodde att säker-hålla-kepsar borde hindra dem att gå förlorade. Saknar jag något.
Edit-4
Jag har forskat mer och läst igenom manualen. Det verkar som om e
och p
förloras när: du byter från användare root
(eller använd secure-noroot
, vilket gör root till en normal användare), detta kan åsidosättas med secure-keep-caps
; när du ringer till exec
, så vitt jag kan säga är detta en invariant.
Såvitt jag kan se fungerar det enligt manualen. Såvitt jag kan säga finns det inget sätt att göra något användbart med capsh
. Såvitt jag kan säga, för att kunna använda funktioner måste du: använda filfunktioner eller ha ett program som är medveten om funktioner, som inte använder exec
. Därför inget privilegierat omslag.
Så nu är min fråga vad jag saknar, vad är capsh
för.
Edit-5
Jag har lagt till ett svar om omgivande funktioner. Kanske capsh
kan också användas med ärvda funktioner, men för att vara användbart måste dessa ställas in i den körbara filen. Jag kan inte se hur capsh kan göra något användbart utan omgivande funktioner eller tillåta ärvda funktioner.
Versioner:
-
capsh
från paketlibcap2-bin
version1:2.22-1.2
- före redigering-3 Jag tog tag i det senaste
capsh
frångit://git.debian.org/collab-maint/libcap2.git
och började använda den. -
uname -a
Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
User-land is 32bit.
Kommentarer
Svar
Funktioner är egenskaper hos processer. Traditionellt finns det tre uppsättningar:
- Tillåtna funktioner ( p ): funktioner som kan vara ”aktiverad” i den aktuella processen.
- Effektiva funktioner ( e ): funktioner som för närvarande är användbara i den nuvarande processen.
- Ärvliga funktioner ( i ): filfunktioner som kan ärvas.
Program som root har alltid fullt tillåtna och effektiva funktioner, så att ”lägga till” fler funktioner har ingen märkbar effekt. (Den ärftliga kapacitetsuppsättningen är normalt tom.) Med setcap cap_net_raw+ep ping
aktiverar du dessa funktioner som standard för alla användare som kör detta program.
Tyvärr är dessa funktioner bundna till exekverad fil och sparas inte efter att en ny underordnad process har utförts. Linux 4.3 introducerade Omgivningskapaciteter som gör att funktioner kan ärvas av barnprocesser. (Se även Omvandling av funktioner under execve () i -funktioner (7) .)
Medan du spelar med funktioner, notera dessa fallgropar:
- När du ändrar användaren från root till non-root raderas de effektiva och tillåtna funktionerna (se Effekt av ändringar av användar-ID på funktioner i -funktioner (7) ). Du kan använda alternativet
--keep=1
förcapsh
för att undvika att rensa uppsättningarna. - Uppsättningen för omgivande funktioner rensas när ändra användar- eller grupp-ID: n. Lösning: lägg till omgivande funktioner efter ändring av användar-ID, men innan körning av en underprocess.
- En funktion kan bara läggas till omgivande funktioner ställa in om det redan finns i både den tillåtna och ärftliga kapacitetsuppsättningen.
Sedan libcap 2.26 fick programmet capsh
förmågan att ändra omgivningsfunktioner via alternativ som --addamb
( commit ). Observera att alternativordningen är viktig. Exempel på användning:
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"
Tips: Du kan lägga till --print
alternativet var som helst i capsh
kommandorad och se dess nuvarande kapacitetstillstånd.
Obs: cap_setpcap
behövs för --addamb
medan cap_setuid,cap_setgid
behövs för alternativet --user
.
Kommentarer
- Vilket specifikt versionsnummer för libcap har sedan capsh –addamb? 2.32 utgivningsanteckningar nämnde nya capsh-funktioner, men orden var vaga.
- @ 把 友情 留 在 无 盐 När svaret ursprungligen skrevs, stödde bara git master det. Sedan dess har libcap 2.26 släppts med stöd för alternativet
--addamb
. Jag har uppdaterat svaret i enlighet med detta. - Tyvärr är dessa funktioner bundna till den körda filen och behålls inte efter att en ny underordnad process har körts. – av underordnad process Jag tänker normalt på
fork(2)
, som ärver funktionerna. Endastexecve(2)
ärver inte ’ t, men det skapar inte ’ t ett barn bearbeta. Har jag fel? - Citera
man capabiltiies
: Ett barn som skapats viafork(2)
ärver kopior av sin förälder ’ s kapacitetsuppsättningar.
Svar
Lekensteyns svar verkar korrekt och fullständigt men jag kommer att försöka ge en annan förklaring från en annan vinkel som försöker betona problemet som den omgivande kapacitetsuppsättningen löser.
När du kör sudo capsh --user=<some_user> --
Det finns två systemanrop av intresse som gör att kapaciteter beräknas om (och eventuellt tappas):
-
setuid
: Enligtman capabilities
:
SECBIT_KEEP_CAPS Att ställa in denna flagga tillåter en tråd som har en eller flera 0 UID för att behålla sina funktioner när den byter alla sina UID: er till ett icke-nollvärde. Om den här flaggan inte är inställd, orsakar en sådan UIDswitch att tråden tappar alla funktioner.
Med andra ord, i vårt capsh
-kommando ovan måste vi se till att SECBIT_KEEP_CAPS är inställt under setuid
systemanrop. Annars går alla funktioner förlorade. Detta är vad --keep=1
gör. Så nu blir kommandot sudo capsh --user=<some_user> --keep=1 --
-
execve
: Om vi använd alternativet--keep=1
, alla kapacitetsuppsättningar (effektiva, tillåtna, ärftliga) bevaras fram till systemanropetexecve
, menexecve
gör att kapaciteter också beräknas om (för icke-rotanvändare) och i ett inte så uppenbart sätt.Kort sagt, före tillägget av de omgivande kapaciteterna , för en förmåga att vara i en tråd ”s” tillåten ” inställt efter ettexecve
-anrop, antingen:- Filen måste ha den kapaciteten i sin ”tillåtna” uppsättning . kan göras med
setcap cap_net_raw+p /bin/bash
. Om du gör detta gör hela övningen värdelös eftersom trådens kapacitetsuppsättningar (förutom avgränsningssatsen) inte längre har någon effekt. - Både filen och tråden måste ha den förmågan i sina ”ärftliga” uppsättningar . Du kanske tror att
setcap cap_net_raw+i
skulle göra tricket men det visar sig attexecve
orsakar att en tråds nedarvningsbara behörigheter släpps när de anropas av en ogynnsam användare (vilket vi för närvarande är tack varesetuid
). Det finns alltså inget sätt att uppfylla detta villkor som en obehörig användare.
- Filen måste ha den kapaciteten i sin ”tillåtna” uppsättning . kan göras med
Ambientfunktioner som introducerades i Linux 4.3 gör det möjligt för en tråd att behålla sina funktioner även efter en setuid
till en oprivierad användare följt av en execve
, utan att behöva förlita sig på filfunktioner.
Svar
Det kan finnas en bugg / funktion i kärnan. Det har diskuterats:
- https://bugzilla.altlinux.org/show_bug.cgi?id=16694
- http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-03/5224.html
Jag har ingen aning om något har varit d en, för att fixa det.
Missförstå mig inte – nuvarande beteende är säkert. Men det är så säkert att det kommer i vägen för saker som verkar fungera.
Redigera: Enligt http://man7.org/linux/man-pages/man7/capabilities.7.html det finns en ny kapacitetsuppsättning Ambient (sedan Linux 4.3). Det ser ut som att detta kommer att tillåta vad som behövs.
Svar
En liten justering av Lekensteyns svar ger en kortare anrop för senaste kärnor:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw -- \ -c "./ping -c1 localhost"
Obs: Beroende på din sudoers-fil kan det göra en röra av din miljö (t.ex. att ändra HEM). capsh kommer att ändra din uid, men den kommer inte att göra någonting för att återställa sudos miljöförändringar.
Så vad händer här? Låt oss titta:
-
sudo /usr/sbin/capsh
: Vi börjar som root, som har alla funktioner i sina effektiva (kan göra detta) och tillåtna (kan lägga till detta till effektiva) uppsättningar, men ingenting i de andra uppsättningarna . Vi kommer att täcka de andra uppsättningarna på ett ögonblick. -
--keep=1
: Av säkerhetsskäl (läs: äldre) skäl ärver normalt inte funktioner över root- > ID-växlar utan root. Denna flagga möjliggör en funktion, känd somSECBIT_KEEP_CAPS
, som tillåter detta. Värt att notera att den rensas automatiskt vid exec , vilket är en bra idé. -
--user=$USER
: Nu när vi inte tappar alla våra möjligheter vid UID-ändring faller vi ur roten. Tack vareSECBIT_KEEP_CAPS
behåller vi root-liknande privilegier, vilket gör att vi kan röra oss ytterligare med våra möjligheter. -
--inh=cap_net_raw
: Detta lägger till vår målförmåga till den ärftliga uppsättningen, eftersom du inte kan göra en kapacitetsmiljö (se nästa artikel) om den inte är ärvbar. -
--addamb=cap_net_raw
: Även om vi ”har begärtSECBIT_KEEP_CAPS
,execve
av en okontrollerad (ingen setuid / setgid / setcap) binär kommer fortfarande rensa våra möjligheter, vilket resulterar i inga behörigheter. Linux 4.3 har lagt till den omgivande uppsättningen, som läggs tillbaka till de effektiva och tillåtna uppsättningarna när du kör okända binärer. Perfekt! -
-- -c ...
: När vi har ställt in allt, kör vi bash med dessa args. Kapacitetsuppsättningarna är rensade (eftersom bash är privilegierad), den omgivande uppsättningen läggs till och voila! Vi har nödvändig behörighet att göra open raw uttag.
Du kan kontrollera detta med hjälp av den speciella ==
argument till capsh, vilket får det att köra sig själv med resten av kommandoraden:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw == --print Current: = cap_net_raw+eip
Vilket betyder att vi har cap_net_raw som effektivt (kan göra det), ärftligt (kan skicka det till barnprocesser) och tillåtet (får få det). Och inga andra funktioner i någon av dessa.
För mer information om funktioner och hur de fungerar, är din bästa satsning -funktionerna (7) man . Specifikt rubriken Transformation of capabilities during execve()
.
Kommentarer
- Vad menar du med Detta görs tidigt eftersom det kräver ett antal ytterligare funktioner som kan ’ t släppa förrän efter att det ’ är klart. ?I ditt fall kör du som ” root ”, så även så
--user
var inte ’ t ändrats, du ’ har du fortfarande de nödvändiga funktionerna senare? - Tack för att du påpekade det! En tidigare version av denna kommandorad tappade uttryckligen privs, så det var nödvändigt att ställa in innan det. Nu när privs släpps implicit som en del av exec är det ’ inte nödvändigt.
capsh
från collab-maint repo skulle inte ha gett dig det ”senaste”capsh
, Debian-paketet stöder fortfarande inte omgivande kapacitet. Uppströms 2.27 gör det.capsh
, i frånvaro av omgivande (som det ursprungligen var). Vad saknar jag? Det måste ha en användning.