Como faço para usar capsh: Estou tentando executar um ping sem privilégios, com recursos mínimos
On Fevereiro 13, 2021 by adminEstou experimentando recursos, no Debian Gnu / Linux.
Copiei / bin / ping para meu diretório de trabalho atual. Como esperado, não funciona, ele foi originalmente setuid root.
Eu, então, dou ao meu ping os recursos mínimos (não root) fazendo sudo /sbin/setcap cap_net_raw=ep ./ping
e meu ping funciona, conforme o esperado.
Em seguida, sudo /sbin/setcap -r ./ping
para revogar esse recurso. Agora não está funcionando como esperado.
Agora tento fazer o ping funcionar usando capsh
.
capsh
não tem privilégios, então preciso executá-lo como root, mas, em seguida, elimine o root e assim todos os outros privilégios.
Acho que também preciso de secure-keep-caps
, isso não está documentado em capsh
, mas está na capacidade manual. Peguei os números dos bits de /usr/include/linux/securebits.h
. Eles parecem corretos, já que a saída de --print
mostra que esses bits estão corretos.
Estou mexendo há horas, até agora tenho isso.
sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"
No entanto, ping
erros com ping: icmp open socket: Operation not permitted
, isso é o que acontece quando ele não tem essa capacidade. Além disso, --print
mostra Current: =p cap_net_raw+i
, isso não é suficiente, precisamos de e
.
sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"
definirá a capacidade para Current: = cap_net_raw+eip
isso está correto, mas nos deixa como root
.
Edit-1
Agora tentei sudo /sbin/capsh --keep=1 --secbits=0x11 --caps=cap_net_raw+epi --print -- -c "touch zz; ./ping -c1 localhost;"
Isso produz:
touch: cannot touch `zz": Permission denied ping: icmp open socket: Operation not permitted
O primeiro erro é esperado como secure-noroot: yes
Mas o segundo não é Current: = cap_net_raw+eip
Edit-2
Se eu colocar ==
antes de --print
, agora mostra Current: = cap_net_raw+i
, então isso explica o erro anterior, mas não por que estamos perdendo capacidade ao sair da raiz, eu pensei que secure-keep-caps
deveria conserte isso.
Edit-3
Pelo que posso ver, estou perdendo Efetivo (e) e Permitido (p), quando exec é chamado. Isso é esperado, mas eu pensei que manter as tampas seguras deveria evitar que elas se perdessem. Estou perdendo alguma coisa.
Edit-4
Tenho feito mais pesquisas e lido o manual novamente. Parece que normalmente as capacidades e
e p
são perdidas quando: você muda de usuário root
(ou aplique secure-noroot
, tornando root um usuário normal), isso pode ser sobrescrito com secure-keep-caps
; quando você chama exec
, pelo que eu posso dizer, isso é uma invariante.
Até onde eu posso dizer, está funcionando de acordo com o manual. Pelo que eu posso dizer, não há como fazer nada útil com capsh
. Pelo que eu posso dizer, para usar os recursos, você precisa: usar recursos de arquivo ou ter um programa que reconheça recursos, que não use exec
. Portanto, nenhum wrapper privilegiado.
Então agora minha pergunta é o que estou perdendo, o que capsh
para.
Edit-5
Eu adicionei uma resposta sobre recursos ambientais. Talvez capsh
também possa ser usado com recursos herdados, mas para serem úteis, eles precisariam ser definidos no arquivo executável. Não consigo ver como o capsh pode fazer algo útil sem recursos de ambiente ou permitir recursos herdados.
Versões:
-
capsh
do pacotelibcap2-bin
versão1:2.22-1.2
- antes de edit-3 peguei o
capsh
degit://git.debian.org/collab-maint/libcap2.git
e começou a usá-lo. -
uname -a
Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
O terreno do usuário é de 32 bits.
Comentários
Resposta
Capacidades são propriedades de processos. Tradicionalmente, existem três conjuntos:
- Capacidades permitidas ( p ): capacidades que podem ser “ativado” no processo atual.
- Recursos eficazes ( e ): recursos que podem ser usados no momento no processo atual.
- Capacidades herdáveis ( i ): capacidades de arquivo que podem ser herdadas.
Os programas executados como root sempre têm todos os recursos permitidos e eficazes, portanto, “adicionar” mais recursos não tem efeito perceptível. (O conjunto de recursos herdáveis normalmente está vazio.) Com setcap cap_net_raw+ep ping
, você habilita esses recursos por padrão para qualquer usuário que execute este programa.
Infelizmente, esses recursos estão vinculados ao arquivo executado e não são retidos após a execução de um novo processo filho. O Linux 4.3 introduziu Recursos ambientais que permitem que os recursos sejam herdados por processos filho. (Veja também Transformação de capacidades durante execve () em capacidades (7) .)
Ao jogar com recursos, observe estas armadilhas:
- Ao alterar o usuário de root para não-root, os recursos efetivos e permitidos são eliminados (consulte Efeito das alterações de ID do usuário nos recursos em recursos (7) ). Você pode usar a opção
--keep=1
decapsh
para evitar limpar os conjuntos. - O conjunto de recursos ambientais é limpo quando alterar os IDs de usuário ou grupo. Solução: adicione os recursos de ambiente após alterar a ID do usuário, mas antes de executar um processo filho.
- Um recurso só pode ser adicionado aos recursos de ambiente definido se já estiver no conjunto de recursos permitidos e herdáveis.
Desde a libcap 2.26, o programa capsh
ganhou a capacidade de modificar os recursos do ambiente por meio de opções como --addamb
( commit ). Observe que a ordem das opções é significativa. Exemplo de uso:
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"
Dica: você pode adicionar a opção --print
em qualquer lugar no capsh
linha de comando e ver seu estado de recursos atual.
Observação: cap_setpcap
é necessário para --addamb
enquanto cap_setuid,cap_setgid
são necessários para a opção --user
.
Comentários
- Qual número de versão específico de libcap desde que tem capsh –addamb? 2.32 notas de lançamento mencionavam novos recursos do capsh, mas as palavras eram vagas.
- @ 把 友情 留 在 无 盐 Quando a resposta foi escrita originalmente, apenas git master a suportava. Desde então, a libcap 2.26 foi lançada com suporte para a opção
--addamb
. Eu atualizei a resposta de acordo. - Infelizmente, esses recursos são vinculados ao arquivo executado e não são retidos após a execução de um novo processo filho. – por processo filho Eu normalmente penso em
fork(2)
, que herda os recursos. Apenasexecve(2)
não ‘ não herda os recursos, mas não ‘ cria um filho processar. Estou errado? - Citando
man capabiltiies
: Uma criança criada por meio defork(2)
herda cópias de seu pai ‘ conjuntos de capacidade.
Resposta
A resposta de Lekensteyn parece precisa e completa, mas tentarei fornecer outra explicação de um ângulo diferente que tentará enfatizar o problema que o conjunto de recursos ambientais resolve.
Quando você executa sudo capsh --user=<some_user> --
Existem 2 chamadas de interesse do sistema que fazem com que os recursos sejam recalculados (e potencialmente descartados):
-
setuid
: De acordo comman capabilities
:
SECBIT_KEEP_CAPS Definir este sinalizador permite um thread que tem um ou mais 0 UIDs para reter seus recursos ao alternar todos os seus UIDs para um valor diferente de zero. Se este sinalizador não for definido, esse UIDswitch fará com que o thread perca todos os recursos.
Em outras palavras, em nosso capsh
comando acima, precisamos ter certeza de que SECBIT_KEEP_CAPS está definido durante o setuid
chamada do sistema. Caso contrário, todos os recursos serão perdidos. Isso é o que --keep=1
faz. Então agora o comando se torna sudo capsh --user=<some_user> --keep=1 --
-
execve
: Se nós use a opção--keep=1
, todos os conjuntos de recursos (efetivos, permitidos, herdáveis) são preservados até aexecve
chamada do sistema, no entantoexecve
faz com que os recursos sejam recalculados (para usuários não root) também, e em uma forma não tão óbvia.Em suma, antes da adição do conjunto de recursos de ambiente , para um recurso de estar em um segmento “s” permitido ” definido após uma chamadaexecve
:- O arquivo deve ter esse recurso em seu conjunto “permitido” . pode ser feito com
setcap cap_net_raw+p /bin/bash
. Fazer isso torna todo o exercício inútil, uma vez que os conjuntos de recursos do thread (exceto o conjunto delimitador) não têm mais efeito. - Tanto o arquivo quanto o thread devem ter esse recurso em seus conjuntos “herdáveis” . Você pode pensar que
setcap cap_net_raw+i
resolveria o problema, mas acontece queexecve
faz com que as permissões herdáveis de um thread sejam eliminadas quando chamadas por um usuário sem privilégios (o que atualmente agradecemos asetuid
). Portanto, não há como satisfazer essa condição como um usuário sem privilégios.
- O arquivo deve ter esse recurso em seu conjunto “permitido” . pode ser feito com
Os recursos de ambiente introduzidos no Linux 4.3 possibilitam que um thread retenha seus recursos mesmo após um setuid
para um usuário sem privilégios seguido por um execve
, sem ter que depender dos recursos do arquivo.
Resposta
Pode haver um bug / recurso no kernel. Houve alguma discussão:
- https://bugzilla.altlinux.org/show_bug.cgi?id=16694
- http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-03/5224.html
Não tenho ideia, se algo foi d um, para consertá-lo.
Não me entenda mal – o comportamento atual é seguro. Mas é tão seguro que atrapalha coisas que parecem funcionar.
Editar: de acordo com http://man7.org/linux/man-pages/man7/capabilities.7.html há um novo conjunto de recursos Ambient (desde o Linux 4.3). Parece que isso permitirá o que for necessário.
Resposta
Um ligeiro ajuste da resposta de Lekensteyn “produz uma chamada mais curta para kernels recentes:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw -- \ -c "./ping -c1 localhost"
Nota: Dependendo do seu arquivo sudoers, isso pode bagunçar o seu ambiente (por exemplo, mudar o HOME). capsh mudará seu uid, mas não fará nada para reverter as mudanças de ambiente do sudo.
Então, o que está acontecendo aqui? Vamos dar uma olhada:
-
sudo /usr/sbin/capsh
: Começamos como root, que tem todos os recursos em seus conjuntos efetivos (pode fazer isso) e permitidos (pode adicionar isso a efetivos), mas nada nos outros conjuntos . Cobriremos esses outros conjuntos em um momento. -
--keep=1
: Por motivos de segurança (leia-se: legado), os recursos normalmente não são herdados entre root- > switches de ID não raiz. Este sinalizador ativa um recurso, conhecido comoSECBIT_KEEP_CAPS
, que permite isso. Vale a pena observar que é apagado automaticamente no exec , o que é uma boa ideia. -
--user=$USER
: Agora que não perderemos todos os nossos recursos na mudança de UID, saímos da raiz. Graças aSECBIT_KEEP_CAPS
, mantemos privilégios de root, o que nos permite bagunçar ainda mais nossos recursos. -
--inh=cap_net_raw
: Isso adiciona nossa capacidade de destino ao conjunto herdável, porque você não pode “criar um ambiente de capacidade (consulte o próximo item) se não for herdável. -
--addamb=cap_net_raw
: Embora tenhamos solicitadoSECBIT_KEEP_CAPS
,execve
de um binário sem privilégios (sem setuid / setgid / setcap) ainda limpar nossas capacidades, resultando em nenhum privilégio. Linux 4.3 adicionou o conjunto de ambiente, que é adicionado de volta aos conjuntos efetivos e permitidos ao executar binários sem privilégios. Perfeito! -
-- -c ...
: Depois de configurar tudo, executamos o bash com esses argumentos. Os conjuntos de recursos são limpos (porque o bash não tem privilégios), o conjunto de ambiente é adicionado de volta e pronto! Temos a permissão necessária para abrir raw sockets.
Você pode verificar isso usando o argumento para capsh, o que faz com que ele seja executado com o resto da linha de comando:
sudo /usr/sbin/capsh --keep=1 --user=$USER \ --inh=cap_net_raw --addamb=cap_net_raw == --print Current: = cap_net_raw+eip
O que significa que temos cap_net_raw como eficaz (pode fazer isso), herdável (pode passá-lo para processos filho) e permitido (tem permissão para obtê-lo). E nenhum outro recurso em nenhum desses.
Para obter mais informações sobre os recursos e como eles funcionam, sua melhor aposta é a página do manual resources (7) . Especificamente o título Transformation of capabilities during execve()
.
Comentários
- O que você quer dizer com Isso está feito cedo porque requer uma série de recursos adicionais que podem ‘ cair até depois de ‘ terminar. ?No seu caso, você está executando como ” root “, portanto,
--user
não era ‘ T mudou, você ‘ d ainda tem os recursos necessários mais tarde? - Obrigado por apontar isso! Uma versão anterior desta linha de comando eliminou explicitamente privs, então foi necessário setuid antes disso. Agora que privs foram eliminados implicitamente como parte de exec, ‘ não é necessário.
capsh
do repositório collab-maint não teria dado a você o mais recentecapsh
, o pacote Debian ainda não oferece suporte capacidades ambientais. O Upstream 2.27 sim.capsh
, na ausência de ambiente (como era originalmente). O que estou perdendo. Deve ter um uso.