Hoe gebruik ik capsh: ik probeer een onbevoegde ping uit te voeren, met minimale mogelijkheden
Geplaatst op februari 13, 2021 door adminIk experimenteer met mogelijkheden, op Debian Gnu / Linux.
Ik heb / bin / ping gekopieerd naar mijn huidige werkdirectory. Zoals verwacht werkt het niet, het was oorspronkelijk setuid root.
Ik geef mijn ping dan de minimale mogelijkheden (niet root) door sudo /sbin/setcap cap_net_raw=ep ./ping
te doen, en mijn ping werkt zoals verwacht.
Vervolgens sudo /sbin/setcap -r ./ping
om die mogelijkheid in te trekken. Het werkt nu niet zoals verwacht.
Ik probeer nu ping te laten werken met capsh
.
capsh
heeft geen privileges, dus ik moet het als root draaien, maar dan root en dus alle andere privileges.
Ik denk dat ik ook secure-keep-caps
nodig heb, dit is niet gedocumenteerd in capsh
, maar het is mogelijk handleiding. Ik heb de bitnummers van /usr/include/linux/securebits.h
. Ze lijken correct, aangezien de uitvoer van --print
laat zien dat deze bits correct zijn.
Ik heb uren aan het friemelen, tot nu toe heb ik dit.
sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"
Echter ping
fouten met ping: icmp open socket: Operation not permitted
, dit is wat er gebeurt als het niet de mogelijkheid heeft. Ook de --print
toont Current: =p cap_net_raw+i
, dit is niet genoeg, we hebben e
nodig.
sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"
zal de mogelijkheid instellen op Current: = cap_net_raw+eip
dit is correct, maar laat ons achter als root
.
Edit-1
Ik heb nu geprobeerd sudo /sbin/capsh --keep=1 --secbits=0x11 --caps=cap_net_raw+epi --print -- -c "touch zz; ./ping -c1 localhost;"
Dit levert:
touch: cannot touch `zz": Permission denied ping: icmp open socket: Operation not permitted
De eerste fout wordt verwacht als secure-noroot: yes
Maar de tweede is niet Current: = cap_net_raw+eip
Edit-2
Als ik ==
vóór de --print
plaats, is het nu toont Current: = cap_net_raw+i
, dus dat verklaart de vorige fout, maar niet waarom we capaciteit verliezen bij het uitschakelen van root, ik dacht dat secure-keep-caps
zou moeten repareer dat.
Edit-3
Van wat ik kan zien, verlies ik Effective (e) en Permitted (p) wanneer exec wordt aangeroepen. Dit wordt verwacht, maar ik dacht dat secure-keep-caps zouden moeten voorkomen dat ze verloren gaan. Mis ik iets.
Edit-4
Ik heb meer onderzoek gedaan en de handleiding opnieuw gelezen. Het lijkt erop dat normaal gesproken e
en p
mogelijkheden verloren gaan wanneer: u overschakelt van gebruiker root
(of pas secure-noroot
toe, waardoor root een normale gebruiker wordt), dit kan worden overschreven met secure-keep-caps
; als je exec
aanroept, is dit voor zover ik weet een invariant.
Voor zover ik kan nagaan, werkt het volgens de handleiding. Voor zover ik weet, is er geen manier om iets nuttigs te doen met capsh
. Voor zover ik weet, moet je om mogelijkheden te gebruiken: bestandsmogelijkheden gebruiken of een mogelijkheden bewust programma hebben dat geen exec
gebruikt. Daarom geen geprivilegieerde wrapper.
Dus nu is mijn vraag: wat mis ik, waar is capsh
voor.
Edit-5
Ik heb een antwoord toegevoegd over omgevingsmogelijkheden. Misschien kan capsh
ook worden gebruikt met overgeërfde mogelijkheden, maar om nuttig te zijn, moeten deze worden ingesteld in het uitvoerbare bestand. Ik kan niet zien hoe capsh iets nuttigs kan doen zonder ambient-mogelijkheden, of om overgenomen mogelijkheden toe te staan.
Versies:
-
capsh
uit pakketlibcap2-bin
versie1:2.22-1.2
- voor edit-3 pakte ik de laatste
capsh
vangit://git.debian.org/collab-maint/libcap2.git
en begon het te gebruiken. -
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.
Reacties
Antwoord
Mogelijkheden zijn eigenschappen van processen. Traditioneel zijn er drie sets:
- Toegestane mogelijkheden ( p ): mogelijkheden die mogelijk zijn “geactiveerd” in het huidige proces.
- Effectieve mogelijkheden ( e ): mogelijkheden die momenteel bruikbaar zijn in het huidige proces.
- Overerfbare mogelijkheden ( i ): bestandsmogelijkheden die kunnen worden overgenomen.
Programmas die als root worden uitgevoerd, hebben altijd de volledige toegestane en effectieve mogelijkheden, dus het “toevoegen” van meer mogelijkheden heeft geen merkbaar effect. (De set van overneembare mogelijkheden is normaal gesproken leeg.) Met setcap cap_net_raw+ep ping
schakelt u deze mogelijkheden standaard in voor elke gebruiker die dit programma uitvoert.
Helaas zijn deze mogelijkheden gebonden aan de uitgevoerd bestand en worden niet bewaard na het uitvoeren van een nieuw kindproces. Linux 4.3 introduceerde Ambient-mogelijkheden waarmee mogelijkheden kunnen worden overgenomen door onderliggende processen. (Zie ook Transformatie van mogelijkheden tijdens execve () in mogelijkheden (7) .)
Tijdens het spelen met Houd rekening met deze valkuilen:
- Wanneer u de gebruiker verandert van root naar niet-root, worden de effectieve en toegestane mogelijkheden gewist (zie Effect van gebruikers-ID-wijzigingen op mogelijkheden in mogelijkheden (7) ). U kunt de
--keep=1
-optie vancapsh
gebruiken om te voorkomen dat de sets worden gewist. - De ingestelde omgevingsmogelijkheden worden gewist wanneer het wijzigen van de gebruikers- of groeps-IDs. Oplossing: voeg de ambient-mogelijkheden toe na het wijzigen van de gebruikers-ID, maar voordat een onderliggend proces uitvoert.
- Een mogelijkheid kan alleen worden toegevoegd aan de ambient-mogelijkheden ingesteld als het zich al in zowel de toegestane als de overneembare mogelijkheden bevindt.
Sinds libcap 2.26 heeft het capsh
programma de mogelijkheid gekregen om omgevingsmogelijkheden te wijzigen via opties zoals --addamb
( commit ). Merk op dat de volgorde van opties aanzienlijk is. Voorbeeldgebruik:
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: u kunt de optie --print
overal in de opdrachtregel en bekijk de huidige status van de mogelijkheden.
Opmerking: cap_setpcap
is nodig voor --addamb
terwijl cap_setuid,cap_setgid
nodig zijn voor de --user
optie.
Opmerkingen
- Welk specifiek versienummer van libcap sinds capsh –addamb? 2.32 release notes noemden nieuwe capsh-functies, maar de woorden waren vaag.
- @ 把 友情 留 在 无 盐 Toen het antwoord oorspronkelijk werd geschreven, ondersteunde alleen git master het. Sindsdien is libcap 2.26 uitgebracht met ondersteuning voor de optie
--addamb
. Ik heb het antwoord dienovereenkomstig bijgewerkt. - Helaas zijn deze mogelijkheden gebonden aan het uitgevoerde bestand en blijven ze niet behouden na het uitvoeren van een nieuw kindproces. – door kindproces Ik denk normaal gesproken aan
fork(2)
, die de mogelijkheden erft. Alleenexecve(2)
neemt ‘ de mogelijkheden niet over, maar ‘ maakt geen kind werkwijze. Heb ik het mis? -
man capabiltiies
citeren: Een kind gemaakt viafork(2)
erft kopieën van zijn bovenliggende ‘ s mogelijkheden sets.
Antwoord
Het antwoord van Lekensteyn lijkt accuraat en compleet, maar ik zal proberen een andere uitleg te geven vanuit een andere invalshoek die zal proberen het probleem te benadrukken dat de omgevingsmogelijkheden oplost.
Wanneer je Er zijn 2 interessante systeemoproepen die ervoor zorgen dat de mogelijkheden opnieuw worden berekend (en mogelijk wegvallen):
-
setuid
: volgensman capabilities
:
SECBIT_KEEP_CAPS Door deze vlag in te stellen, kan een thread een of meer 0 UIDs hebben om zijn mogelijkheden te behouden wanneer het al zijn UIDs naar een niet-nulwaarde schakelt. Als deze vlag niet is ingesteld, zorgt zon UID-schakelaar ervoor dat de thread alle mogelijkheden verliest.
Met andere woorden, in ons capsh
commando hierboven, moeten we ervoor zorgen dat SECBIT_KEEP_CAPS is ingesteld tijdens de setuid
systeemoproep. Anders gaan alle mogelijkheden verloren. Dit is wat de --keep=1
doet. Dus nu wordt het commando sudo capsh --user=<some_user> --keep=1 --
-
execve
: Als we gebruik de--keep=1
optie, alle mogelijkheden sets (effectief, toegestaan, erfelijk) worden behouden tot deexecve
systeemaanroep, maarexecve
zorgt ervoor dat mogelijkheden ook opnieuw worden berekend (voor niet-rootgebruikers), en in een niet zo voor de hand liggende manier.Kortom, voorafgaand aan de toevoeging van de omgevingsmogelijkheden ingesteld , voor een mogelijkheid om in een thread “s” toegestaan “te zijn ingesteld na eenexecve
aanroep, ofwel:- Het bestand moet die mogelijkheid hebben in zijn “toegestane” set . kan worden gedaan met
setcap cap_net_raw+p /bin/bash
. Dit maakt de hele oefening onbruikbaar omdat de capaciteitssets van de thread (anders dan de begrenzingsset) geen enkel effect meer hebben. - Zowel het bestand als de thread moeten die mogelijkheid hebben in hun “overerbare” sets . Je denkt misschien dat
setcap cap_net_raw+i
de juiste oplossing zou zijn, maar het blijkt datexecve
ervoor zorgt dat de erfelijke machtigingen van een thread worden verwijderd wanneer deze wordt aangeroepen door een onbevoegde gebruiker (wat we momenteel te danken zijn aansetuid
). Er is dus geen manier om aan deze voorwaarde als onbevoegde gebruiker te voldoen.
- Het bestand moet die mogelijkheid hebben in zijn “toegestane” set . kan worden gedaan met
Ambient-mogelijkheden die in Linux 4.3 zijn geïntroduceerd, maken het mogelijk dat een thread zijn mogelijkheden behoudt, zelfs na een setuid
naar een onbevoegde gebruiker gevolgd door een execve
, zonder afhankelijk te zijn van bestandsmogelijkheden.
Antwoord
Mogelijk zit er een bug / feature in de kernel. Er is enige discussie geweest:
- https://bugzilla.altlinux.org/show_bug.cgi?id=16694
- http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-03/5224.html
Ik heb geen idee of er iets is d een, om het op te lossen.
Begrijp me niet verkeerd – het huidige gedrag is veilig. Maar het is zo veilig dat het dingen in de weg staat die zouden moeten werken.
Bewerken: volgens http://man7.org/linux/man-pages/man7/capabilities.7.html er is een nieuwe mogelijkheden set Ambient (sinds Linux 4.3). Het lijkt erop dat dit toestaat wat nodig is.
Answer
Een kleine aanpassing van het antwoord van Lekensteyn levert een kortere aanroep op voor recente kernels:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw -- \ -c "./ping -c1 localhost"
Opmerking: afhankelijk van je sudoers-bestand, kan dit een puinhoop van je omgeving maken (bijvoorbeeld het veranderen van HOME). capsh zal je uid veranderen, maar het zal niets doen om de veranderingen in de omgeving van sudo ongedaan te maken.
Dus wat is hier aan de hand? Laten we eens kijken:
-
sudo /usr/sbin/capsh
: we beginnen als root, die alle mogelijkheden heeft in zijn effectieve (kan dit) en toegestane (kan dit toevoegen aan effectieve) sets, maar niets in de andere sets . We zullen die andere sets in een oogwenk behandelen. -
--keep=1
: om veiligheidsredenen (lees: legacy), erven capaciteiten normaal gesproken niet over root- > niet-root-ID-schakelaars. Deze vlag schakelt een functie in, bekend alsSECBIT_KEEP_CAPS
, die dit mogelijk maakt. Het is vermeldenswaard dat deze automatisch wordt gewist bij exec , wat een goed idee is. -
--user=$USER
: Nu we “niet al onze mogelijkheden op UID-wijziging kwijtraken, vallen we uit de root. DankzijSECBIT_KEEP_CAPS
behouden we root-achtige privileges, waardoor we verder kunnen knoeien met onze mogelijkheden. -
--inh=cap_net_raw
: Dit voegt onze doelmogelijkheid toe aan de overneembare set, omdat je “een mogelijkheid niet ambient kunt maken (zie volgend item) als deze niet kan worden overgenomen. -
--addamb=cap_net_raw
: Ook al hebben we “SECBIT_KEEP_CAPS
aangevraagd,execve
van een niet-bevoorrecht (geen setuid / setgid / setcap) binair bestand nog steeds maak onze mogelijkheden leeg, wat resulteert in geen privileges. Linux 4.3 heeft de ambient set toegevoegd, die weer wordt toegevoegd aan de effectieve en toegestane sets bij het uitvoeren van unprivileged binaries. Perfect! -
-- -c ...
: Nadat we alles hebben ingesteld, voeren we bash uit met deze args. De vaardigheidssets worden gewist (omdat bash geen privileges heeft), de ambient set wordt weer toegevoegd, en voila! We hebben de nodige toestemming om open raw te doen sockets.
U kunt dit controleren met de speciale ==
argument naar capsh, wat ervoor zorgt dat het zichzelf uitvoert met de rest van de commandoregel:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw == --print Current: = cap_net_raw+eip
Wat betekent dat we cap_net_raw als effectief (kan het), erfelijk (kan het doorgeven aan onderliggende processen) en toegestaan (mag het krijgen). En geen andere mogelijkheden in een van deze.
Voor meer informatie over mogelijkheden en hoe ze werken, kun je het beste de mogelijkheden (7) man-pagina . Specifiek de kop Transformation of capabilities during execve()
.
Reacties
- Wat bedoel je met Dit is gedaan vroeg omdat het een aantal extra mogelijkheden vereist die ‘ niet kunnen worden verwijderd totdat ‘ klaar is. ?In jouw geval voer je uit als ” root “, dus zelfs dan
--user
wasn ‘ Als u niet bent gewijzigd, ‘ d beschikt u later nog over de nodige mogelijkheden? - Bedankt dat u erop wijst! Een eerdere versie van deze commandoregel liet expliciet privs vallen, dus het was nodig om setuid daarvoor te gebruiken. Nu privs impliciet worden verwijderd als onderdeel van exec, is het ‘ niet nodig.
capsh
uit de collab-maint-repo haalt, zou u niet de “nieuwste”capsh
hebben opgeleverd, het Debian-pakket ondersteunt nog steeds niet ambient mogelijkheden. Upstream 2.27 doet dat wel.capsh
, bij afwezigheid van ambient (zoals het oorspronkelijk was). Wat mis ik. Het moet een gebruik hebben.