¿De qué manera no se basa SFTP en SSH?

9

Acabo de completar el juego de guerra OverTheWire Bandit, nivel 18 .

Eso fue una sorpresa. Aquí están las instrucciones para este nivel.

La contraseña para el siguiente nivel se almacena en un archivo Léame en el directorio principal. Desafortunadamente, alguien ha modificado .bashrc para cerrar sesión cuando inicia sesión con SSH.

Estaba pensando en una manera de hacer que el shell omita el abastecimiento .bashrc. Pero antes de encontrar una solución, me sentí tentado a simplemente iniciar una conexión SFTP con el servidor. No esperaba que funcionara. Pero lo hizo. Y me gustaría saber por qué. Pensé que SFTP se ejecuta sobre SSH.

Para mayor claridad, cuando ingreso SSH al servidor, me expulsan, como se esperaba.


fuente
1
SFTP se ejecuta sobre SSH. bash también puede correr sobre SSH. Pero SFTP no se ejecuta sobre bash. (tenga en cuenta que estoy usando "atropellar" aquí)
user253751

Respuestas:

13

En bash en general

El diseño de Bash con respecto a los archivos de inicio es bastante peculiar. Bash se carga .bashrcen dos circunstancias no relacionadas:

  • Cuando es un shell interactivo, excepto cuando es un shell de inicio de sesión (y excepto cuando se invoca como sh). Es por eso que .bash_profilegeneralmente se carga.bashrc .
  • Cuando bash no es interactivo ni un shell de inicio de sesión ni se invoca como shpero recibe un comando para ejecutar -cy SHLVLestá desarmado o menor o igual a 1, y uno de los siguientes es verdadero:

    • Si la entrada estándar es un zócalo. En la práctica, esto ocurre principalmente cuando se invoca bash rshd, es decir, cuando se ejecuta rsh remotehost.example.com somecommand.
    • Si se activa en tiempo de compilación (que es el caso en algunas distribuciones, como Debian y derivados), si una de las variables de entorno SSH_CLIENTo SSH2_CLIENTestá definida. En la práctica, esto significa que bash es invocado por sshd, es decir ssh remotehost.example.com somecommand.
      Si no sabe cómo se compiló bash, puede averiguar si esta opción se configuró comprobando si el binario contiene la cadena SSH_CLIENT:

      strings /bin/bash | grep SSH_CLIENT
      

Sobre SSH en general

Cuando ejecuta un comando a través del protocolo SSH, el comando se pasa por el cable como una cadena. La cadena es ejecutada por el shell remoto. Cuando ejecuta ssh example.com somecommand, si el shell de inicio de sesión del usuario remoto es /bin/bash, se ejecuta el servidor SSH /bin/bash -c somecommand. No hay forma de evitar el shell de inicio de sesión. Esto permite restringidas shells de entrada, por ejemplo, para permitir solamente la copia de archivos y no la ejecución de comandos en general.

Hay una excepción: el protocolo SSH permite al cliente solicitar un subsistema específico. Si el cliente solicita el sftpsubsistema, entonces, de manera predeterminada, el servidor OpenSSH invoca el programa /usr/lib/openssh/sftp-server(la ubicación puede variar) a través del shell de inicio de sesión del usuario. Pero también se puede configurar para ejecutar un servidor SFTP interno a través de la línea

Subsystem sftp internal-sftp

en el sshd_configarchivo En el caso del servidor SFTP interno, y solo en este caso, se omite el shell de inicio de sesión del usuario.

Para este desafío

En el caso de OverTheWire Bandit 18, .bashrccontiene

…
# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac
…
echo 'Byebye !'
exit 0

Entonces puede resolver este nivel haciendo cualquier cosa que haga que bash no sea interactivo.

Como descubriste, SFTP funciona.
Pero ssh [email protected] cat readmetambién funcionaría.
Como lo haría echo 'cat readme' | ssh [email protected].
Y presionar Ctrl + C en el momento correcto durante un inicio de sesión interactivo también funcionaría: interrumpiría bash, por lo .bashrcque no se ejecutaría por completo. Bash toma tiempo macroscópico para iniciarse, por lo que si bien esto no funciona de manera confiable, se puede hacer en la práctica.

Gilles 'SO- deja de ser malvado'
fuente
2
No creo que SFTP ejecute bash en absoluto , no solo de forma no interactiva.
user253751
@immibis Creo que tienes razón al respecto. He utilizado SFTP para intercambiar archivos en una cuenta de usuario que se configuró con alguna aplicación como shell de inicio de sesión en lugar de un shell "real".
kasperd
@immibis SFTP no ejecuta bash. Pero a menos que el servidor SFTP sea interno, sshdejecuta el shell de inicio de sesión del usuario que se ejecuta sftp-server. Por lo tanto, si el shell de inicio de sesión no interpreta la cadena /usr/lib/openssh/sftp-servercomo "ejecutar el comando /usr/lib/openssh/sftp-server", no puede usar SFTP.
Gilles 'SO- deja de ser malvado'
5

El .bashrcsolo se ejecuta cuando inicia un shell.

El servidor SSH se puede configurar para que no inicie un shell para el protocolo SFTP al proporcionar el comando Subsystem internal-sftpen el sshd_configarchivo del servidor .

Conjetura: es probable que así es como se configura realmente el juego de guerra OverTheWire Bandit en lugar de un ajuste .bashrcporque, de lo contrario, la misma restricción para sshtambién bloquearía el sftpcomando del servidor.

roaima
fuente
2
Correr SFTP hace comenzar una concha. El demonio SSH se ejecuta /path/to/shell -c /path/to/sftp-serverdonde /path/to/shellestá el shell de inicio de sesión del usuario. Si el shell de inicio de sesión del usuario es bash, entonces .bashrcpuede ejecutarse dependiendo de cómo se compiló bash. Siempre se ejecuta cuando bash es ejecutado por rshd(sí, incluso para un shell no interactivo, el inicio de bash es extraño) y una opción de tiempo de compilación se extiende a esto sshd.
Gilles 'SO- deja de ser malvado'
Fui y revisé. Buena suposición, pero de hecho no es tan sutil. El exiten .bashrcsólo se ejecuta si bash es interactivo.
Gilles 'SO- deja de ser malvado'
@Gilles, con Subsystem sftp internal-sftpy echo No.; exit 1en mi no .bashrctengo sshacceso al servidor, pero sftpaún funciona. (Y luego, por supuesto, es posible sobrescribir o eliminar .bashrc. No obstante los permisos). El sshintento de conexión falla, ya sea interactivo o no. Por otro lado, si lo tengo Subsystem sftp /usr/lib/openssh/sftp-server, el servicio SFTP también falla cuando .bashrcse daña.
roaima