Inwiefern basiert SFTP nicht auf SSH?

9

Ich habe gerade das OverTheWire Bandit-Kriegsspiel Level 18 abgeschlossen .

Das war eine Überraschung. Hier sind die Anweisungen für dieses Level.

Das Passwort für die nächste Ebene wird in einer Datei- Readme- Datei im Homedirectory gespeichert. Leider hat jemand .bashrc geändert , um Sie abzumelden , wenn Sie sich mit SSH anmelden.

Ich dachte über eine Möglichkeit nach, die Shell überspringen zu lassen .bashrc. Bevor ich jedoch eine Lösung fand, war ich versucht, einfach eine SFTP-Verbindung mit dem Server herzustellen. Ich habe nicht erwartet, dass es funktioniert. Aber es tat es. Und ich würde gerne wissen warum. Ich dachte, SFTP läuft über SSH.

Aus Gründen der Klarheit werde ich beim SSH-Zugriff auf den Server wie erwartet rausgeschmissen.


quelle
1
SFTP läuft über SSH. Bash kann auch über SSH laufen. Aber SFTP läuft nicht über Bash. (Beachten Sie, dass ich hier "lose
überfahren

Antworten:

13

Auf Bash im Allgemeinen

Das Design von Bash in Bezug auf Startdateien ist ziemlich eigenartig. Bash-Ladungen .bashrcunter zwei unabhängigen Umständen:

  • Wenn es sich um eine interaktive Shell handelt, außer wenn es sich um eine Anmeldeshell handelt (und außer wenn sie als aufgerufen wird sh). Aus diesem Grund wird .bash_profilenormalerweise geladen.bashrc .
  • Wenn bash weder interaktiv noch eine Login-Shell ist oder als shBefehl aufgerufen wird , mit dem ausgeführt werden soll, -cund SHLVLnicht gesetzt oder kleiner oder gleich 1 ist und eine der folgenden Bedingungen erfüllt ist:

    • Wenn der Standardeingang eine Buchse ist. In der Praxis geschieht dies meistens, wenn bash von aufgerufen wird rshd, dh wenn ausgeführt wird rsh remotehost.example.com somecommand.
    • Wenn zur Kompilierungszeit aktiviert (was bei einigen Distributionen wie Debian und Derivaten der Fall ist), wenn eine der Umgebungsvariablen SSH_CLIENToder SSH2_CLIENTdefiniert ist. In der Praxis bedeutet dies, dass bash von aufgerufen wird sshd, dh ssh remotehost.example.com somecommand.
      Wenn Sie nicht wissen, wie bash kompiliert wurde, können Sie herausfinden, ob diese Option festgelegt wurde, indem Sie überprüfen, ob die Binärdatei die Zeichenfolge enthält SSH_CLIENT:

      strings /bin/bash | grep SSH_CLIENT
      

Auf SSH im Allgemeinen

Wenn Sie einen Befehl über das SSH-Protokoll ausführen, wird der Befehl als Zeichenfolge über die Leitung übertragen. Die Zeichenfolge wird von der Remote-Shell ausgeführt. Wenn Sie ssh example.com somecommanddie Anmeldeshell des Remotebenutzers ausführen , wird /bin/bashder SSH-Server ausgeführt /bin/bash -c somecommand. Es gibt keine Möglichkeit, die Anmeldeshell zu umgehen. Dies ermöglicht eingeschränkte Anmeldeshells, um beispielsweise nur das Kopieren von Dateien und nicht die allgemeine Befehlsausführung zuzulassen .

Es gibt eine Ausnahme: Das SSH-Protokoll ermöglicht es dem Client, ein bestimmtes Subsystem anzufordern. Wenn der Client das sftpSubsystem anfordert , ruft der OpenSSH-Server das Programm standardmäßig /usr/lib/openssh/sftp-serverüber die Anmeldeshell des Benutzers auf (der Speicherort kann variieren). Es kann jedoch auch so konfiguriert werden, dass ein interner SFTP-Server über die Leitung ausgeführt wird

Subsystem sftp internal-sftp

in der sshd_configDatei. Im Fall des internen SFTP-Servers und nur in diesem Fall wird die Anmeldeshell des Benutzers umgangen.

Für diese Herausforderung

Im Fall von OverTheWire Bandit 18 .bashrcenthält

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

Sie können dieses Level also lösen, indem Sie alles tun, was dazu führt, dass Bash nicht interaktiv ist.

Wie Sie festgestellt haben, funktioniert SFTP.
Aber ssh [email protected] cat readmewürde auch funktionieren.
Wie würde echo 'cat readme' | ssh [email protected].
Und das Drücken von Strg + C zum richtigen Zeitpunkt während eines interaktiven Logins würde ebenfalls funktionieren: Es würde das Bash unterbrechen, sodass das .bashrcnicht vollständig ausgeführt würde. Bash benötigt makroskopische Zeit zum Starten. Dies funktioniert zwar nicht zuverlässig, kann aber in der Praxis durchgeführt werden.

Gilles 'SO - hör auf böse zu sein'
quelle
2
Ich glaube nicht , SFTP läuft bash überhaupt , nicht nur nicht interaktiv.
user253751
@immibis Ich glaube, Sie haben Recht damit. Ich habe SFTP verwendet, um Dateien auf einem Benutzerkonto auszutauschen, das mit einer Anwendung als Anmeldeshell und nicht als "echte" Shell konfiguriert wurde.
Kasperd
@immibis SFTP führt keine Bash aus. Sofern der SFTP-Server nicht intern ist, wird sshddie Anmeldeshell des Benutzers ausgeführt, die ausgeführt wird sftp-server. Wenn die Anmeldeshell die Zeichenfolge nicht /usr/lib/openssh/sftp-serverals "Befehl ausführen /usr/lib/openssh/sftp-server" interpretiert , können Sie SFTP nicht verwenden.
Gilles 'SO - hör auf böse zu sein'
5

Das .bashrcwird nur ausgeführt, wenn Sie eine Shell starten.

Der SSH-Server kann so konfiguriert werden, dass keine Shell für das SFTP-Protokoll gestartet wird, indem der Befehl Subsystem internal-sftpin der Serverdatei angegeben sshd_configwird.

Vermutung: Es ist wahrscheinlich, dass das OverTheWire Bandit-Wargame auf diese Weise tatsächlich konfiguriert wird und nicht angepasst wird, .bashrcda ansonsten dieselbe Einschränkung für sshauch den sftpServerbefehl blockieren würde .

Roaima
quelle
2
Durch Ausführen von SFTP wird eine Shell gestartet. Der SSH-Daemon wird dort ausgeführt, /path/to/shell -c /path/to/sftp-serverwo /path/to/shellsich die Anmeldeshell des Benutzers befindet. Wenn die Anmeldeshell des Benutzers bash ist, .bashrckann sie ausgeführt werden, je nachdem, wie bash kompiliert wurde. Es wird immer ausgeführt, wenn bash von ausgeführt wird rshd(ja, selbst für eine nicht interaktive Shell ist der Start von bash seltsam), und eine Option zur Kompilierungszeit erweitert dies auf sshd.
Gilles 'SO - hör auf böse zu sein'
Ich ging und überprüfte. Gute Vermutung, aber tatsächlich ist es nicht so subtil. Das exitIn .bashrcwird nur ausgeführt, wenn bash interaktiv ist.
Gilles 'SO - hör auf böse zu sein'
@ Gilles, mit Subsystem sftp internal-sftpund echo No.; exit 1in meinem .bashrcbekomme ich keinen sshZugriff auf den Server aber sftpfunktioniert trotzdem. (Und dann ist es natürlich möglicherweise möglich, die .bashrcBerechtigungen zu überschreiben oder zu entfernen .) Der sshVerbindungsversuch schlägt fehl, ob interaktiv oder nicht. Auf der anderen Seite, wenn ich Subsystem sftp /usr/lib/openssh/sftp-serverdann habe, schlägt der SFTP-Dienst auch fehl, wenn er .bashrcverstümmelt ist.
Roaima