Come uso capsh: sto cercando di eseguire un ping senza privilegi, con funzionalità minime


13

Sto sperimentando le capacità su Debian Gnu / Linux.

Ho copiato / bin / ping nella mia directory di lavoro corrente. Come previsto, non funziona, originariamente era root setuid.

Dò quindi al mio ping le capacità minime (non root) facendo sudo /sbin/setcap cap_net_raw=ep ./ping, e il mio ping funziona, come previsto.

Quindi sudo /sbin/setcap -r ./pingrevocare tale capacità. Ora non funziona come previsto.

Ora provo a far funzionare il ping usando 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-capsquesto, non è documentato capsh, ma è nel manuale delle funzionalità. Ho ricevuto i numeri di bit da /usr/include/linux/securebits.h. Sembrano corretti, poiché l'output di --printmostra 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 , pingcon errori ping: icmp open socket: Operation not permitted, questo è ciò che accade quando non ha la capacità. Anche gli --printspettacoli Current: =p cap_net_raw+i, questo non è abbastanza di cui abbiamo bisogno e.

sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"imposterà la capacità su Current: = cap_net_raw+eipquesto è corretto, ma ci lascia come root.

Edit-1

Ora ci 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, secure-noroot: yes ma il secondo noCurrent: = cap_net_raw+eip

Edit-2

Se lo metto ==prima di --print, ora mostra Current: = cap_net_raw+i, quindi ciò spiega l'errore precedente, ma non il motivo per cui stiamo perdendo capacità quando si passa da root, ho pensato che secure-keep-capsdovrebbe risolverlo.

Edit-3

Da quello che posso vedere, sto perdendo Effettivo (e) e Consentito (p), quando viene chiamato exec. Questo è previsto, ma ho pensato che Secure-Keep-Caps, dovrebbe impedire loro di perdersi. Mi sto perdendo qualcosa.

Edit-4

Ho fatto ulteriori ricerche e ho letto di nuovo il manuale. Sembra che normalmente ee le pcapacità vengano perse quando: si passa da un utente root(o si applica secure-noroot, facendo di root un utente normale), questo può essere ignorato secure-keep-caps; quando chiami exec, per quanto posso dire questo è un invariante.

Per quanto ne so, funziona secondo il manuale. Per quanto ne so, non c'è modo di fare nulla di utile capsh. Per quanto ne so, per usare le capacità è necessario: usare le capacità dei file o avere un programma consapevole delle capacità, che non usa exec. Pertanto nessun wrapper privilegiato.

Quindi ora la mia domanda è cosa mi sto perdendo, a cosa serve capsh.

Edit-5

Ho aggiunto una risposta alle capacità ambientali. Forse capshpuò anche essere usato 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 capacità ereditate.


versioni:

  • capshdalla libcap2-binversione del pacchetto1:2.22-1.2
  • prima di edit-3 ho afferrato l'ultimo capshda git://git.debian.org/collab-maint/libcap2.gite iniziato a usarlo.
  • uname -a Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux L'utente-land è a 32 bit.

1
Hai provato l'esempio di Lekensteyn con una versione successiva a monte ? Ottenere capshdal repository collab-maint non ti avrebbe dato il "più recente" capsh, il pacchetto Debian non supporta ancora le funzionalità ambientali. A monte 2.27 lo fa.
Stephen Kitt,

1
@StephenKitt è buono a sapersi, ma la domanda originale è: a che serve capsh, in assenza di ambiente (com'era in origine). Cosa mi sto perdendo. Deve avere un uso.
ctrl-alt-delor,

Risposte:


11

Le capacità sono proprietà dei processi. Tradizionalmente ci sono tre set:

  • Funzionalità consentite ( p ): funzionalità che possono essere "attivate" nel processo corrente.
  • Capacità effettive ( e ): capacità attualmente utilizzabili nel processo corrente.
  • Capacità ereditarie ( i ): capacità di file che possono essere ereditate.

I programmi eseguiti come root hanno sempre tutte le funzionalità consentite ed efficaci, quindi "l'aggiunta" di più funzionalità non ha alcun effetto evidente. (Il set di funzionalità ereditabili è normalmente vuoto.) setcap cap_net_raw+ep pingAbilitando queste funzionalità per impostazione predefinita per qualsiasi utente che esegue questo programma.

Sfortunatamente queste capacità sono legate al file eseguito e non vengono mantenute dopo aver eseguito un nuovo processo figlio. Linux 4.3 ha introdotto le funzionalità Ambient che consentono alle funzionalità di essere ereditate dai processi figlio. (Vedi anche Trasformazione delle capacità durante execve () in capacità (7) .)

Mentre giochi con le capacità, nota queste insidie:

  • Quando si cambia l'utente da root a non root, le funzionalità effettive e consentite vengono cancellate (vedere Effetto delle modifiche dell'ID utente sulle funzionalità nelle funzionalità (7) ). È possibile utilizzare l' --keep=1opzione di capshper evitare di cancellare i set.
  • Le capacità ambientali impostate vengono cancellate quando si modificano gli ID utente o gruppo. Soluzione: aggiungere le funzionalità ambientali dopo aver modificato l'ID utente, ma prima di eseguire un processo figlio.
  • Una capacità può essere aggiunta al set di funzionalità ambientali solo se è già presente nel set di funzionalità sia consentito che ereditabile.

Il capshprogramma da libcap 2.25 non ha ancora la possibilità di modificare le capacità ambientali, ma le versioni successive aggiungono nuove opzioni. Si noti che l'ordine 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: è possibile aggiungere l' --printopzione in qualsiasi punto della capshriga di comando e vedere lo stato delle funzionalità correnti.

Nota: cap_setpcapè necessario per il --addambtempo cap_setuid,cap_setgidnecessario per l' --useropzione.


6

La risposta di Lekensteyn sembra accurata e completa, ma proverò a fornire un'altra spiegazione da un'angolazione diversa che proverà a enfatizzare il problema risolto dalle capacità ambientali.

Quando si esegue sudo capsh --user=<some_user> --Ci sono 2 chiamate di sistema di interesse che causano il ricalcolo (e potenzialmente l'eliminazione) delle funzionalità:

  1. setuid: Secondo man capabilities:

SECBIT_KEEP_CAPS L'impostazione di questo flag consente a un thread con uno o più 0 UID di conservare le proprie capacità quando cambia tutti i suoi UID su un valore diverso da zero. Se questo flag non è impostato, un tale UIDswitch fa perdere tutte le funzionalità al thread.

In altre parole, nel nostro capshcomando sopra, dobbiamo assicurarci che SECBIT_KEEP_CAPS sia impostato durante la setuidchiamata di sistema. Altrimenti si perdono tutte le capacità. Questo è ciò che --keep=1fa. Quindi ora il comando diventasudo capsh --user=<some_user> --keep=1 --

  1. execve: Se utilizziamo l' --keep=1opzione, tutti i set di funzionalità (effettivi, consentiti, ereditabili) vengono conservati fino alla execvechiamata di sistema, tuttavia execvecausano il ricalcolo delle funzionalità (anche per utenti non root) e in un modo non così ovvio. In breve, prima dell'aggiunta del set di capacità ambientali , per una capacità di essere nel set "consentito" di un thread dopo una execvechiamata, o:

    • Il file deve avere tale capacità nel suo set "consentito" . Questo può essere fatto con setcap cap_net_raw+p /bin/bash. Questo rende inutile l'intero esercizio poiché i set di capacità del thread (diversi dal set di limiti) non hanno più alcun effetto.
    • Sia il file che il thread devono avere questa capacità nei loro set "ereditabili" . Potresti pensare che setcap cap_net_raw+ifarebbe il trucco, ma si scopre che execvefa cadere le autorizzazioni ereditabili di un thread quando viene chiamato da utenti non privilegiati (che attualmente siamo grazie setuid). Quindi non c'è modo di soddisfare questa condizione come utente non privilegiato.

Le funzionalità ambientali introdotte in Linux 4.3 consentono a un thread di conservare le proprie capacità anche dopo un setuidutente non privilegiato seguito da un execve, senza dover fare affidamento sulle capacità dei file.


2

Potrebbe esserci un bug / funzionalità nel kernel. C'è stata qualche discussione:

Non ho idea, se è stato fatto qualcosa, di ripararlo.

Non fraintendetemi: il comportamento attuale è sicuro. Ma è così sicuro che ostacola le cose che sembrano funzionare.

Modifica: Secondo http://man7.org/linux/man-pages/man7/capabilities.7.html c'è un nuovo set di funzionalità Ambient (dal Linux 4.3). Sembra che questo consentirà ciò che è necessario.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.