Skip to content

Instantly share code, notes, and snippets.

@dualbus
Last active December 28, 2015 05:59
Show Gist options
  • Save dualbus/7454006 to your computer and use it in GitHub Desktop.
Save dualbus/7454006 to your computer and use it in GitHub Desktop.
Cómo ejecutar un shell script como root de forma segura
1) Linux no permite scripts suid; y si se pudiera, hacerlo sería
*demasiado* estúpido. ¿La razón? cualquier usuario del sistema ahora
puede reiniciar tu servicio. Si te comprometen el FTP, y obtienen un
shell como ftp, boom, adios.
2) El esquema con dos usuarios, www-data y root, con www-data en
sudoers. Claro que puedes utilizar las facilidades de «sudo» para
limitar qué comandos puede ejecutar www-data. De esta forma, puedes
tener una entrada como:
www-data ALL = NOPASSWD: /etc/init.d/servicio
Sin embargo, se presenta el siguiente caso: La aplicación web fue
vulnerada, el atacante ahora puede ejecutar comandos como www-data.
¿Cómo? No importa, ya pasó. ¿Cual es tu siguiente capa de defensa? El
script del servicio. Si el script del servicio tiene algún error de
programación, y el atacante puede manipular algunas de las entradas
que recibe el script, es posible que pueda hacer más destrozos o
incluso escalar privilegios. Entonces, tu siguiente barrera de
seguridad es un script que hace muchas cosas para asegurar que se
inicia un servicio. Entre más cosas hagas como root y más entradas
aceptes del atacante, hay mayores probabilidades de que se haya hecho
algo mal.
3) El esquema con tres usuarios, www-data, www-cmd, y root. Este
esquema es similar al anterior, pero se agrega un intermediario, que
es www-cmd. En este caso el intermediario tiene la *única*
responsabilidad de aceptar una entrada del usuario www-data y
convertirla a un comando para manipular al servicio. Supongamos que
tienes:
www-cmd ALL = NOPASSWD: /etc/init.d/servicio
www-data ALL = NOPASSWD: /home/www-cmd/ctl-servicio
Y /home/www-cmd/ctl-servicio es un script que tiene lo siguiente:
#!/bin/sh
case $1 in
start|stop|restart) _=_;;
*) exit 1;;
esac
env -i sudo /etc/init.d/servicio "$1"
De esta forma, limpias las variables de entorno, y te aseguras de que
el usuario www-data solo pueda enviar tres entradas y controlar lo
relacionado a eso, y no más. Aún si comprometen a www-data por otro
vector, no les serviría tu comando de ctl-servicio mas que para hacer
lo que www-data ya estaba autorizado a hacer.
P.S.: La propuesta del ln es solo seguridad por oscuridad, y eso no
sirve de nada, mas que para esconderte de ser blanco fácil en Github.
Eso no incrementa para nada la seguridad de tu sistema, y muchas
herramientas automatizadas ya prueban cosas como shell code
injection.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment