Use com segurança o find com sudo

10

Em um servidor Linux, preciso remover privilégios de root de um grupo de usuários. Mas esses usuários têm motivos legítimos para poder usar o utilitário "find" para procurar arquivos com base em nomes de arquivos, datas de modificação e outros metadados.

No servidor, os nomes dos arquivos não são sensíveis, mas o conteúdo do arquivo pode ser.

Eu gostaria de usar o sudo para permitir que os usuários pesquisem arquivos em qualquer lugar do servidor. O utilitário "find" é ótimo, mas permite todos os tipos de efeitos colaterais, como o uso de "-exec" para gerar comandos arbitrários.

Posso findtrabalhar com minhas restrições?

Troels Arvin
fonte
14
Normalmente, você não deseja que os resultados da pesquisa de padrões de nome de arquivo contenham arquivos que você não pode acessar de fato. Nesse sentido, sua exigência é um pouco estranha.
HBruijn
2
Ninguém o força a se envolver na questão. Eu acho que um dos objetivos da falha do servidor é servir como um fórum para situações estranhas.
Troels Arvin
2
Falha no servidor não é um fórum, e as tentativas de psicologia reversa não alteram a validade da observação de HBruijn (que, tenho certeza, foi colocada na tentativa de ajudá-lo).
Lightness Races in Orbit

Respostas:

19

Que tal localizar ?

localize lê um ou mais bancos de dados preparados por updatedb (8) e grava nomes de arquivos correspondentes a pelo menos um dos PADRÕES na saída padrão, um por linha. Se --regex não for especificado, PATTERNs podem conter caracteres brilhantes. Se algum PADRÃO não contiver caracteres brilhantes, localize-se como se o padrão fosse PADRÃO .

Por padrão, o localizador não verifica se os arquivos encontrados no banco de dados ainda existem. O localizador nunca pode relatar arquivos criados após a atualização mais recente do banco de dados relevante.

Ou talvez até incline :

A Localização segura fornece uma maneira segura de indexar e pesquisar rapidamente arquivos no seu sistema. Ele usa codificação incremental, assim como a localização do GNU, para compactar seu banco de dados para acelerar a pesquisa, mas também armazena permissões e propriedade de arquivos, para que os usuários não vejam arquivos aos quais não têm acesso.

Esta página de manual documenta a versão GNU do slocate. slocate Permite que os usuários do sistema pesquisem sistemas de arquivos inteiros sem exibir arquivos não autorizados.

Lenniey
fonte
Boa ideia. Não sei por que não pensei nisso. Mas receio que o parâmetro "-d" possa ser usado para ler arquivos arbitrários, se as regras do sudo permitirem ao usuário executar qualquer comando "localizar"?
Troels Arvin
2
@TroelsArvin: locatenão precisa sudo; somente seu updatedbtrabalho requer privilégios especiais. Seus usuários, portanto, nunca devem estar em execução ou poder executar sudo locate.
Jwodder #
1
@jwodder: Em um servidor RHEL 7: digamos que o usuário u não tenha acesso a / data / foo. Em / data / foo, há um arquivo "somefile.csv". Agora, quando você executa "localize algum arquivo.csv", a saída de "localize" não inclui /data/foo/somefile.csv - a menos que o usuário u execute "localize" via sudo. (Usar o argumento "--nofollow" não ajuda.) #
Troels Arvin
1
@TroelsArvin, mas o -dsinalizador define apenas o caminho do banco de dados? Talvez eu tenha entendido mal você.
Lenniey 4/17
21

De acordo com man 7 capabilities

   CAP_DAC_READ_SEARCH
          * Bypass file read permission checks and directory read and execute permission checks;
          * Invoke open_by_handle_at(2).

Isso funcionou para mim. (as linhas que começam com '#' são raiz e aquelas com '$' não são raiz). Nesse caso, o usuário não raiz está no wheelgrupo.

# cp /usr/bin/find /usr/bin/sudofind
# chmod 710 /usr/bin/sudofind
# chown root:wheel /usr/bin/sudofind
# setcap cap_dac_read_search+ep /usr/bin/sudofind
# exit
$ find /root 
find: ‘/root’: Permission denied
$ sudofind /root
/root /root 
/root/Testbed 
...
... 
$ sudofind /root -exec cat {} \;
cat: /root: Permission denied 
cat: /root/Testbed: Permission denied
$ sudofind /root -printf "%u %g %m %c %p\n"
root root 644 Mon Apr 20 09:20:48.0457518493 2015 /root
root root 755 Fri Dec  4 02:34:03.0016294644 2015 /root/Testbed
...
...
$ # Capability inheritance test..
$ sudofind /root -exec /bin/sleep 10 \; &
[1] 17017
$ getpcaps $(pgrep find)
Capabilities for `17017': = cap_dac_read_search+ep
$ getpcaps $(pgrep sleep)
Capabilities for `17019': =

Dado o que a capacidade concede, ela se encaixa exatamente no que você deseja. Eu não verifiquei exaustivamente se findhá um recurso que permite ler bytes dentro de arquivos, mas coisas óbvias como LD_PRELOADataques de calibração de bibliotecas não devem funcionar devido à natureza das verificações de setuid no Linux, e os bits de capacidade não são herdado pelos processos filhos (ao contrário do setuid bruto), então esse é outro bônus.

Lembre-se de que o que você deseja fazer suscita possíveis preocupações com a privacidade em relação à criação ou acesso temporário a arquivos, e o programa pode ser usado como base para montar uma tentativa de escalação de condição / privilégio de corrida (contra programas que criam nomes de arquivos conhecidos mas não faça as verificações de segurança corretas).

Além disso, alguns aplicativos mal escritos podem contar com metadados de arquivo ou estrutura de árvore como uma maneira de transmitir significado ou ocultar dados. Isso pode causar a liberação de informações restritas ou revelar documentos privilegiados desconhecidos (segurança pela obscuridade, eu sei, mas isso é algo que os fornecedores de código fechado, em particular, gostam de fazer, infelizmente).

Portanto, tome cuidado e tenha cuidado ao fazê-lo e entenda que ainda há riscos associados a isso, mesmo que as coisas óbvias não funcionem.

Ah, e eu ficaria interessado em ver se alguém tem uma prova de ataque de conceito que usa esse mecanismo como base para a escalada de privilégios nos comentários!

Matthew Ife
fonte
5
Isso realmente parece bastante interessante!
Sven
Como isso? Bem, sem PoC, mas interessante, no entanto: forums.grsecurity.net/…
Lenniey 3/17
Eu gosto dessa idéia, mas tem uma desvantagem significativa: o sudofind agora é um binário que não faz parte de nenhum pacote de software (por exemplo, RPM) no sistema. Portanto, se a distribuição enviar um patch para "find", o sudofind não será atualizado.
Troels Arvin
2
@TroelsArvin Isso não é necessariamente uma coisa ruim. Se você estiver adicionando recursos do tipo setuid a um utilitário existente que não foi projetado para esses recursos, não desejará nenhuma atualização no utilitário subjacente antes de verificar se o utilitário atualizado pode ser usado com segurança com o seu padrão não. capacidades. Imagine, neste caso, se uma atualização permitir finda execução direta de algum código fornecido pelo usuário, semelhante ao que awkpode ser feito.
Andrew Henle
4
O maior problema que vejo com isso é que os diretórios graváveis ​​em todo o mundo que estão embaixo de diretórios não pesquisáveis ​​podem ser gravados repentinamente.
Tavian Barnes
2

Eu daria aos usuários permissões adequadas.

Por padrão, se o umask for 022, os diretórios serão criados para que todos possam listar e estatisticamente os arquivos neles. Caso contrário, você pode alterar manualmente a permissão do diretório para o bit a bit ou de suas permissões antigas e 0555:

chmod +0555 foo

E se esses usuários não tiverem permissão de execução em todos os pais desse diretório (por exemplo, o diretório inicial de outro usuário), provavelmente significa que você deve colocar o primeiro diretório em outro lugar.

Se você deseja permitir que apenas alguns usuários leiam e executem esse diretório, é possível alterar seu modo para 0750, colocar esses usuários em um grupo e alterar o proprietário do grupo para esse grupo:

groupadd can_read_foo
chmod 0750 foo
chgrp can_read_foo foo
gpasswd -a alice can_read_foo
gpasswd -a bob can_read_foo
yt7b97q-
fonte