Olá pessoal. Estamos participando ativamente do trabalho e, em janeiro, estamos preparando muitos lançamentos poderosos. Entre outros, um conjunto foi anunciado para um novo fluxo do curso Linux Administrator que todos adoram. Antecipando o lançamento, tradicionalmente compartilhamos a tradução de material útil.
As permissões de arquivo oferecem uma alternativa segura aos executáveis ​​do SUID, mas podem parecer um pouco confusas no inĂcio.
Todos sabemos que os binários
SUID sĂŁo uma
solução de segurança ruim . Felizmente, se o seu aplicativo exigir alguns privilégios limitados, existe uma maneira mais eficiente chamada de
permissões de arquivo .
Economizarei seu tempo se você quiser evitar uma leitura detalhada do artigo acima: em essência, as permissões de arquivo permitem processos que são executados como root e, portanto, têm o direito de fazer algo, para salvar determinados recursos limitados por
esta lista quando redefinir privilĂ©gios e executar como um usuário sem privilĂ©gios. Isso significa que, se um invasor conseguir comprometer um processo excedendo um buffer ou outra exploração, ele nĂŁo poderá tirar proveito de nada alĂ©m de certos privilĂ©gios mĂnimos de que o processo realmente precisa.
As permissões são ótimas para serviços que geralmente sempre são executados como raiz, mas e os utilitários de linha de comando? Felizmente, isso também é suportado, desde que você tenha os utilitários corretos instalados. Se você usa o Ubuntu, por exemplo, precisará do pacote
libcap2-bin
. Você também precisará executar um kernel não-arcaico (a partir da versão
2.6.24 ).
Essas funções permitem associar permissões a arquivos executáveis ​​de maneira semelhante Ă configuração do bit SUID, mas apenas para um conjunto especĂfico de permissões. O utilitário
setcap
usado para adicionar e remover permissões de um arquivo.
O primeiro passo é selecionar as permissões necessárias. Para este artigo, presumo que exista uma ferramenta de diagnóstico de rede chamada
tracewalk
que deve poder usar
soquetes brutos . Isso geralmente requer que o aplicativo seja executado como raiz, mas ao exibir a
lista, verifica-se que apenas a permissĂŁo
CAP_NET_RAW
Ă©
CAP_NET_RAW
.
Supondo que você esteja no diretório em que o binário do
tracewalk
está localizado, você pode adicionar esta permissão da seguinte maneira:
sudo setcap cap_net_raw=eip tracewalk
Por enquanto, ignore o sufixo
=eip
para obter permissĂŁo.
=eip
sobre isso em alguns segundos. Observe que o nome da permissão está em minúsculas. Agora você pode verificar se você configurou as permissões corretamente com:
setcap -v cap_new_raw=eip tracewalk
Ou você pode listar todas as permissões definidas para este arquivo executável:
getcap tracewalk
Para referência, você também pode remover todas as permissões do executável usando:
setcap -r tracewalk
Nesse ponto, você deve poder executar o executável como um usuário sem privilégios, e ele deve poder trabalhar com soquetes brutos, mas não deve ter outros privilégios que o usuário root tenha.
EntĂŁo, o que esse sufixo estranho
=eip
? Isso exigirá um pouco de compreensão da natureza das permissões. Cada processo possui três conjuntos de permissões -
efetivas, herdáveis ​​e permitidas (efetivas, herdáveis ​​e permitidas) :
- Permissões efetivas são aquelas que determinam o que um processo pode realmente fazer. Por exemplo, ele não pode lidar com soquetes brutos se
CAP_NET_RAW
nĂŁo CAP_NET_RAW
em um conjunto eficiente. - Permissões permitidas sĂŁo aquelas que um processo tem permissĂŁo para solicitá-las por meio de uma chamada apropriada. Eles nĂŁo permitem que um processo realmente faça algo, a menos que tenha sido especificamente escrito para solicitar a permissĂŁo especificada. Isso permite que vocĂŞ escreva processos para adicionar permissões crĂticas ao conjunto efetivo apenas para o perĂodo em que elas sĂŁo realmente necessárias.
- Permissões herdáveis sĂŁo aquelas que podem ser herdadas na coleção disponĂvel do processo filho. Durante a operação
fork()
ou clone()
, o processo filho sempre recebe uma cópia das permissões do processo pai, porque nesse momento ele ainda está executando o mesmo arquivo executável. Um conjunto herdado é usado quando exec()
(ou equivalente) Ă© chamado para substituir o executável por outro. Nesse ponto, o conjunto de processos disponĂveis Ă© mascarado pelo conjunto herdado para obter o conjunto disponĂvel que será usado para o novo processo.
Assim, o utilitário
setcap
nos permite adicionar permissões desses três conjuntos independentemente para um determinado arquivo executável. Observe que o significado de grupos é interpretado de maneira um pouco diferente para as permissões de arquivo:
- Permissões de arquivo disponĂveis sĂŁo aquelas que estĂŁo sempre disponĂveis para o executável, mesmo que o processo pai que a chamou nĂŁo as possua. Eles costumavam ser chamados de permissões "forçadas".
- Permissões de arquivo herdadas definem uma máscara adicional que também pode ser usada para remover permissões do conjunto do processo de chamada. Eles são usados ​​além do conjunto herdado do processo de chamada, portanto, a permissão é herdada apenas se existir nos dois conjuntos.
- As permissões efetivas de arquivo sĂŁo, na verdade, apenas um bit, nĂŁo um conjunto, e se estiver instalado, significa que todo o conjunto disponĂvel tambĂ©m Ă© copiado para o conjunto efetivo do novo processo. Isso pode ser usado para adicionar permissões a processos que nĂŁo foram criados especificamente para solicitá-los. Como esse Ă© um bit, se vocĂŞ o definir para qualquer permissĂŁo, deverá ser definido para todas as permissões. VocĂŞ pode pensar nisso como um bit herdado, porque Ă© usado para permitir permissões para aplicativos que nĂŁo os suportam.
Ao especificar permissões por meio do
setcap
trĂŞs letras
e
,
i
p
referem-se a conjuntos
eficientes, herdados e acessĂveis , respectivamente. Portanto, uma especificação anterior:
sudo setcap cap_net_raw=eip tracewalk
... indica que a permissĂŁo
CAP_NET_RAW
deve ser adicionada aos conjuntos disponĂveis e herdados e que o bit efetivo tambĂ©m deve ser definido. Isso substituirá quaisquer permissões definidas anteriormente no arquivo. Para definir várias permissões de uma sĂł vez, use uma lista separada por vĂrgula:
sudo setcap cap_net_admin,cap_net_raw=eip tracewalk
O guia de permissões discute tudo isso com mais detalhes, mas espero que este post desmistifique um pouco o incidente. Resta mencionar apenas alguns avisos e truques.
Primeiro, os recursos do arquivo não funcionam com links simbólicos - você deve aplicá-los ao próprio binário (ou seja, ao destino do link simbólico).
Em segundo lugar, eles nĂŁo funcionam com scripts interpretados. Por exemplo, se vocĂŞ possui um script Python ao qual deseja atribuir permissĂŁo, deve atribuĂ-lo ao prĂłprio interpretador Python. Obviamente, esse Ă© um problema de segurança em potencial, porque todos os scripts executados com esse intĂ©rprete terĂŁo a permissĂŁo especificada, embora isso ainda seja muito melhor do que executar o SUID. A solução mais comum, aparentemente, Ă© gravar um arquivo executável separado em C ou um analĂłgico que possa executar as operações necessárias e chamá-lo a partir de um script. Isso Ă© semelhante Ă abordagem usada pelo Wireshark, que usa o arquivo binário
/usr/bin/dumpcap
para executar operações privilegiadas:
$ getcap /usr/bin/dumpcap /usr/bin/dumpcap = cap_net_admin,cap_net_raw+eip
Em terceiro lugar, as permissões de arquivo serão desativadas se você usar a
LD_LIBRARY_PATH
ambiente
LD_LIBRARY_PATH
por razões óbvias de segurança
(1) . O mesmo se aplica a
LD_PRELOAD
, tanto quanto eu sei.
1. Como o invasor pode obviamente substituir uma das bibliotecas padrĂŁo e usar LD_LIBRARY_PATH
para forçar sua biblioteca a ser chamada preferencialmente pelo sistema, e, portanto, ter seu próprio código arbitrário executado com os mesmos privilégios do aplicativo de chamada.
Só isso. Detalhes sobre o programa do curso podem ser encontrados no webinar, que será realizado em 24 de janeiro.