Come si usa capsh: Sto cercando di eseguire un ping senza privilegi, con capacità minime
Su Febbraio 13, 2021 da adminSto sperimentando funzionalità, su Debian Gnu / Linux.
Ho copiato / bin / ping nella mia directory di lavoro corrente. Come previsto, non funziona, originariamente era setuid root.
Quindi do al mio ping le capacità minime (non root) eseguendo sudo /sbin/setcap cap_net_raw=ep ./ping
e il mio ping funziona, come previsto.
Quindi sudo /sbin/setcap -r ./ping
per revocare tale capacità. Ora non funziona come previsto.
Ora provo a far funzionare il ping utilizzando capsh
.
capsh
non ha privilegi, quindi devo eseguirlo come root, ma poi rilasciare root e quindi tutti gli altri privilegi.
Penso di aver bisogno anche di secure-keep-caps
, questo non è documentato in capsh
, ma è nella capacità Manuale. Ho ottenuto i numeri di bit da /usr/include/linux/securebits.h
. Sembrano corretti, poiché loutput di --print
mostra che questi bit sono corretti.
Ho giocherellato per ore, finora ho questo.
sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"
Tuttavia ping
errori con ping: icmp open socket: Operation not permitted
, questo è ciò che accade quando non ha la capacità. Inoltre --print
mostra Current: =p cap_net_raw+i
, non è sufficiente, abbiamo bisogno di e
.
sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"
imposterà la capacità su Current: = cap_net_raw+eip
è corretto, ma ci lascia come root
.
Modifica-1
Ora ho provato sudo /sbin/capsh --keep=1 --secbits=0x11 --caps=cap_net_raw+epi --print -- -c "touch zz; ./ping -c1 localhost;"
Questo produce:
touch: cannot touch `zz": Permission denied ping: icmp open socket: Operation not permitted
Il primo errore è previsto come secure-noroot: yes
Ma il secondo non è Current: = cap_net_raw+eip
Modifica-2
Se metto ==
prima di --print
, ora mostra Current: = cap_net_raw+i
, quindi questo spiega lerrore precedente, ma non perché stiamo perdendo capacità quando si esce da root, pensavo che secure-keep-caps
dovrebbe risolverlo.
Edit-3
Da quello che posso vedere, sto perdendo Effective (e) e Permitted (p), quando viene chiamato exec. Questo è previsto, ma ho pensato che secure-keep-caps dovrebbe impedire che vadano persi. Mi manca qualcosa?
Modifica-4
Ho fatto più ricerche e ho letto di nuovo il manuale. Sembra che normalmente le funzionalità e
e p
vadano perse quando: si passa dallutente root
(o applica secure-noroot
, rendendo così root un utente normale), questo può essere sovrascritto con secure-keep-caps
; quando chiami exec
, per quanto posso dire questo è un invariante.
Per quanto posso dire, funziona secondo il manuale. Per quanto ne so non cè modo di fare qualcosa di utile con capsh
. Per quanto ne so, per usare le capacità devi: usare le capacità dei file o avere un programma che ne sappia le capacità, che non usi exec
. Quindi nessun wrapper privilegiato.
Quindi ora la mia domanda è cosa mi manca, a cosa serve capsh
.
Modifica-5
Ho aggiunto una risposta sulle capacità ambientali. Forse capsh
può essere utilizzato anche con funzionalità ereditate, ma per essere utili queste dovrebbero essere impostate sul file eseguibile. Non riesco a vedere come capsh possa fare qualcosa di utile senza capacità ambientali o per consentire funzionalità ereditate.
Versioni:
-
capsh
dal pacchettolibcap2-bin
versione1:2.22-1.2
- prima di modificare-3 ho preso lultimo
capsh
dagit://git.debian.org/collab-maint/libcap2.git
e ho iniziato a utilizzarlo. -
uname -a
Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
User-land è a 32 bit.
Commenti
Risposta
Le capacità sono proprietà dei processi. Tradizionalmente ci sono tre set:
- Capacità consentite ( p ): capacità che possono essere “attivato” nel processo corrente.
- Funzionalità effettive ( e ): funzionalità attualmente utilizzabili nel processo corrente.
- Capacità ereditabili ( i ): capacità di file che possono essere ereditate.
I programmi eseguiti come root hanno sempre piena capacità consentite ed effettive, quindi “aggiungere” più capacità non ha alcun effetto evidente. (Il set di capacità ereditabili è normalmente vuoto.) Con setcap cap_net_raw+ep ping
abiliti queste funzionalità per impostazione predefinita per qualsiasi utente che esegue questo programma.
Sfortunatamente queste capacità sono vincolate al file eseguito e non vengono conservati dopo aver eseguito un nuovo processo figlio. Linux 4.3 ha introdotto le funzionalità Ambient che consentono di ereditare le capacità dai processi figli. (Vedi anche Trasformazione di capacità durante execve () in capacità (7) .)
Mentre giochi con capacità, nota queste insidie:
- Quando si cambia lutente da root a non root, le funzionalità effettive e consentite vengono cancellate (vedere Effetto delle modifiche dellID utente sulle capacità nelle funzionalità (7) ). Puoi utilizzare lopzione
--keep=1
dicapsh
per evitare di cancellare i set. - Il set di funzionalità ambientali viene cancellato quando modificare gli ID utente o gruppo. Soluzione: aggiungi le funzionalità ambientali dopo la modifica dellID utente, ma prima di eseguire un processo figlio.
- Una funzionalità può essere aggiunta solo alle funzionalità ambientali impostato se è già presente sia nel set di funzionalità consentite che ereditabili.
A partire da libcap 2.26, il programma capsh
ha acquisito la capacità di modificare le capacità ambientali tramite opzioni come --addamb
( commit ). Notare che lordine delle opzioni è significativo. Esempio di utilizzo:
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"
Suggerimento: puoi aggiungere lopzione --print
ovunque in capsh
riga di comando e vedere lo stato delle sue capacità attuali.
Nota: cap_setpcap
è necessario per --addamb
mentre cap_setuid,cap_setgid
sono necessari per lopzione --user
.
Commenti
- Quale numero di versione specifico di libcap da allora ha capsh –addamb? Le note di rilascio 2.32 menzionavano nuove funzionalità di capsh, ma le parole erano vaghe.
- @ 把 友情 留 在 无 盐 Quando la risposta fu scritta originariamente, solo git master la supportava. Da allora, libcap 2.26 è stato rilasciato con il supporto per lopzione
--addamb
. Ho aggiornato la risposta di conseguenza. - Sfortunatamente queste funzionalità sono legate al file eseguito e non vengono conservate dopo lesecuzione di un nuovo processo figlio. – da processo figlio Normalmente penso a
fork(2)
, che eredita le funzionalità. Soloexecve(2)
‘ non eredita le funzionalità, ma ‘ non crea un figlio processi. Mi sbaglio? - Citando
man capabiltiies
: Un bambino creato tramitefork(2)
eredita copie del suo genitore ‘ set di capacità.
Risposta
La risposta di Lekensteyn sembra accurata e completa, ma cercherò di fornire unaltra spiegazione da una diversa angolazione che tenterà di enfatizzare il problema risolto dalle funzionalità ambientali impostate.
Quando esegui sudo capsh --user=<some_user> --
Sono presenti 2 chiamate di sistema di interesse che causano il ricalcolo delle funzionalità (e potenzialmente leliminazione):
-
setuid
: secondoman capabilities
:
SECBIT_KEEP_CAPS Limpostazione di questo flag consente un thread che ha uno o più 0 UID per mantenere le sue capacità quando cambia tutti i suoi UID su un valore diverso da zero. Se questo flag non è impostato, un tale interruttore UID fa perdere al thread tutte le capacità.
In altre parole, nel nostro comando capsh
sopra, dobbiamo assicurarci che SECBIT_KEEP_CAPS sia impostato durante setuid
chiamata di sistema. Altrimenti si perdono tutte le capacità. Questo è ciò che fa --keep=1
. Quindi ora il comando diventa sudo capsh --user=<some_user> --keep=1 --
-
execve
: Se noi utilizza lopzione--keep=1
, tutti i set di capacità (effettivi, consentiti, ereditabili) vengono conservati fino al la chiamata di sistemaexecve
, tuttaviaexecve
fa sì che le funzionalità vengano ricalcolate (per utenti non root) e in un modo non così ovvio.In breve, prima dellaggiunta delle funzionalità ambientali impostate , per una capacità di essere in un thread “consentito” impostato dopo una chiamataexecve
:- Il file deve avere quella capacità nel suo insieme “consentito” . può essere fatto con
setcap cap_net_raw+p /bin/bash
. Fare questo rende lintero esercizio inutile poiché gli insiemi di capacità del thread (diversi dallinsieme di delimitazione) non hanno più alcun effetto. - Sia il file che il thread devono avere quella capacità nei loro insiemi “ereditabili” . Potresti pensare che
setcap cap_net_raw+i
farebbe il trucco, ma risulta cheexecve
fa sì che le autorizzazioni ereditabili di un thread vengano eliminate quando viene chiamato un utente non privilegiato (cosa che al momento siamo grazie asetuid
). Quindi non cè modo di soddisfare questa condizione come utente non privilegiato.
- Il file deve avere quella capacità nel suo insieme “consentito” . può essere fatto con
Le capacità ambientali introdotte in Linux 4.3 consentono a un thread di mantenere le proprie capacità anche dopo un setuid
a un utente non privilegiato seguito da un execve
, senza dover fare affidamento sulle funzionalità dei file.
Risposta
Potrebbe esserci un bug / una funzionalità nel kernel. Ci sono state discussioni:
- https://bugzilla.altlinux.org/show_bug.cgi?id=16694
- http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-03/5224.html
Non ho idea, se qualcosa è stato d uno, per risolverlo.
Non fraintendermi: il comportamento corrente è sicuro. Ma è così sicuro che intralcia cose che dovrebbero sembrare funzionare.
Modifica: secondo http://man7.org/linux/man-pages/man7/capabilities.7.html cè un nuovo set di funzionalità Ambient (a partire da Linux 4.3). Sembra che questo consentirà ciò che è necessario.
Risposta
Un leggero aggiustamento della risposta di Lekensteyn produce una chiamata più breve per i kernel recenti:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw -- \ -c "./ping -c1 localhost"
Nota: a seconda del tuo file sudoers, questo potrebbe creare confusione nel tuo ambiente (es. cambiare HOME). capsh cambierà il tuo uid, ma non farà nulla per annullare le modifiche allambiente di sudo.
Allora cosa sta succedendo qui? Diamo unocchiata:
-
sudo /usr/sbin/capsh
: iniziamo come root, che ha tutte le capacità nei suoi set effettivi (può farlo) e consentiti (può aggiungerlo a quelli effettivi), ma niente negli altri set . Tratteremo questi altri set tra un momento. -
--keep=1
: per motivi di sicurezza (leggi: legacy), le funzionalità normalmente non ereditano attraverso root- > switch ID non root. Questo flag abilita una funzione, nota comeSECBIT_KEEP_CAPS
, che lo consente. Vale la pena notare che viene cancellato automaticamente su exec , che è una buona idea. -
--user=$USER
: Ora che non perderemo tutte le nostre capacità alla modifica dellUID, abbandoniamo root. Grazie aSECBIT_KEEP_CAPS
, conserviamo privilegi simili a quelli di root, il che ci consente di pasticciare ulteriormente con le nostre capacità. -
--inh=cap_net_raw
: Questo aggiunge la nostra capacità di destinazione allinsieme ereditabile, perché non puoi “creare un ambiente di capacità (vedi elemento successivo) se non è ereditabile. -
--addamb=cap_net_raw
: Anche se abbiamo richiestoSECBIT_KEEP_CAPS
,execve
di un binario non privilegiato (nessun setuid / setgid / setcap) sarà ancora cancella le nostre capacità, senza ottenere privilegi. Linux 4.3 ha aggiunto il set di ambienti, che viene aggiunto di nuovo ai set effettivi e consentiti durante lesecuzione di binari non privilegiati. Perfetto! -
-- -c ...
: Dopo aver impostato tutto, eseguiamo bash con questi argomenti. I set di capacità sono cancellati (perché bash non è privilegiato), il set ambientale viene aggiunto di nuovo e voilà! Abbiamo il permesso necessario per aprire raw socket.
Puoi verificarlo utilizzando lo speciale ==
argomento per capsh, che lo fa eseguire da solo con il resto della riga di comando:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw == --print Current: = cap_net_raw+eip
Il che significa che abbiamo cap_net_raw come efficace (può farlo), ereditabile (può passarlo a processi figli) e consentito (è consentito ottenerlo). E nessunaltra capacità in nessuna di queste.
Per ulteriori informazioni sulle capacità e su come funzionano, la soluzione migliore è la pagina man delle capacità (7) . In particolare lintestazione Transformation of capabilities during execve()
.
Commenti
- Cosa intendi con Questo è fatto presto perché richiede una serie di funzionalità aggiuntive che possono ‘ t cadere fino a quando ‘ non sarà terminato. ?Nel tuo caso, stai eseguendo come ” root “, quindi anche così
--user
non era ‘ t cambiato, ‘ avresti ancora le capacità necessarie in seguito? - Grazie per averlo sottolineato! Una versione precedente di questa riga di comando eliminava esplicitamente privs, quindi prima era necessario setuid. Ora che i priv vengono eliminati implicitamente come parte di exec, ‘ non è necessario.
capsh
dal repository collab-maint non ti avrebbe dato l “ultimo”capsh
, il pacchetto Debian ancora non supporta capacità ambientali. Upstream 2.27 sì.capsh
, in assenza di ambient (comera originariamente). Cosa mi manca. Deve avere un uso.