Sicurezza di consentire solo pochi comandi controllati usando $ SSH_ORIGINAL_COMMAND

3

Uso di un comando forzato authorized_keys con ssh e uno script wrapper come questo:

#!/usr/bin/env bash

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

Un utente malintenzionato può in qualche modo incatenare un altro comando dopo /usr/bin/authorized-scripts/ e quindi superare questa misura di sicurezza o è sicuro?

Questo suggerisce che potrei semplicemente usare ssh user@host '/var/lib/authorized-scripts/script.sh && cat /etc/passwd' , ma questo non ha funzionato nei miei test.

Posso migliorare in qualche modo la sicurezza di questo script pur consentendo più comandi con argomenti forniti dall'utente per una singola chiave SSH?

Sono consapevole che i comandi consentiti dovrebbero naturalmente non consentire alcun tipo di sottotitoli (quindi, find ad esempio è un nogo ad esempio a causa della sua funzionalità exec ).

    
posta Zulakis 27.03.2016 - 13:21
fonte

1 risposta

8

Il tuo comando forzato non è sicuro. Prendere in considerazione:

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

Il nome del comando inizia con /var/lib/authorized-scripts/ quindi è sicuro, giusto? No!

Avrai bisogno di qualcosa di più seguendo queste linee:

#!/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" "$@"

Come per la sintassi della shell come && e ; incorporato nel comando, dovrebbe essere sicuro. Come hai già scoperto, queste cose non sono interpretate dalla shell nella tua soluzione ma passate letteralmente al comando.

Tuttavia, i caratteri jolly negli argomenti del comando saranno interpretati. Se vuoi evitarlo, metti set -f prima della riga con set -- $SSH_ORIGINAL_COMMAND .

Assicurati che gli script autorizzati interpretino i loro argomenti in modo sicuro. Gli argomenti possono essere opzioni che consentono l'iniezione della shell (come find -exec fa), i nomi dei file, inclusi i collegamenti simbolici (che puntano a un file in una directory diversa), ecc.

Infine: #!/usr/bin/env bash non è necessario. Il tuo script non usa bashismi, quindi perché non essere più portabile eseguendo sotto /bin/sh ?

    
risposta data 27.03.2016 - 17:02
fonte

Leggi altre domande sui tag