Seguridad de solo permitir algunos comandos verificados usando $ SSH_ORIGINAL_COMMAND

3

Utilizando un comando authorized_keys force con ssh y un script de envoltura como este:

#!/usr/bin/env bash

case "$SSH_ORIGINAL_COMMAND" in
  /var/lib/authorized-scripts/*)
    $SSH_ORIGINAL_COMMAND
    ;;
  *)
    exit 1
    ;;
esac

¿Un usuario malintencionado puede encadenar de alguna manera otro comando después de /usr/bin/authorized-scripts/ y, por lo tanto, superar esta medida de seguridad o es seguro?

Esto sugiere que simplemente podría usar ssh user@host '/var/lib/authorized-scripts/script.sh && cat /etc/passwd' , pero esto no funcionó en mis pruebas.

¿Puedo mejorar la seguridad de este script de alguna manera y al mismo tiempo permitir múltiples comandos con argumentos proporcionados por el usuario para una sola clave ssh?

Soy consciente de que los propios comandos permitidos, por supuesto, no deberían permitir ningún tipo de subshells (por lo tanto, find por ejemplo es un nogo, por ejemplo, debido a su funcionalidad exec ).

    
pregunta Zulakis 27.03.2016 - 13:21
fuente

1 respuesta

8

Tu comando forzado no es seguro. Considera:

ssh -l user your-server /var/lib/authorized-scripts/../../../bin/rm -rf /

El nombre del comando comienza con /var/lib/authorized-scripts/ , por lo que es seguro, ¿verdad? ¡No!

Querrás algo más en este sentido:

#!/bin/sh

set -- $SSH_ORIGINAL_COMMAND
case "$1" in
  /var/lib/authorized-scripts/*)
    ;;
  *)
    exit 1
esac

command="${1#/var/lib/authorized-scripts/}"
shift
case "$command" in
  */*)
    # Simplest is to reject anything with a slash...
    exit 1
  .*)
    # ...and anything starting with dot.
    # If you need to whitelist subdirectories of /var/lib/authorized-scripts
    # then you need much more sophisticated pathname parsing and care.
    exit 1
  *)
    ;;
esac

exec "/var/lib/authorized-scripts/$command" "$@"

En cuanto a la sintaxis de shell como && y ; incrustados en el comando, eso debería ser seguro. Como ya descubrió, el shell en su solución no interpreta tales cosas, sino que se pasa de forma literal al comando.

Sin embargo, los comodines en los argumentos del comando se serán interpretados. Si quieres evitar eso, coloca set -f antes de la línea con set -- $SSH_ORIGINAL_COMMAND .

Asegúrese de que los scripts autorizados interpreten sus argumentos de forma segura. Los argumentos podrían ser opciones que permitan la inyección de shell (como find -exec ), nombres de archivos, incluidos enlaces simbólicos (que apuntan a un archivo en un directorio diferente), etc.

Finalmente: #!/usr/bin/env bash no es necesario. Su script no usa bashismos, ¿por qué no dejar que sea más portátil ejecutando bajo /bin/sh ?

    
respondido por el Celada 27.03.2016 - 17:02
fuente

Lea otras preguntas en las etiquetas