Чем SFTP не основан на SSH?

9

Я только что закончил Wargame OverTheWire Bandit, уровень 18 .

Это был сюрприз. Вот инструкции для этого уровня.

Пароль для следующего уровня хранится в файле readme в домашнем каталоге. К сожалению, кто-то изменил .bashrc для выхода из системы, когда вы входите по SSH.

Я думал о способе пропустить поиск оболочки .bashrc. Но прежде чем я нашел решение, у меня возник соблазн просто запустить SFTP-соединение с сервером. Я не ожидал, что это сработает. Но это так. И я хотел бы знать почему. Я думал, что SFTP работает через SSH.

Для ясности, когда я SSH в сервер, меня выгнали, как и ожидалось.


источник
1
SFTP работает через SSH. Bash также может работать через SSH. Но SFTP не работает через Bash. (обратите внимание, что я использую здесь "свободно")
user253751

Ответы:

13

На баш вообще

Дизайн Bash по отношению к файлам запуска довольно своеобразен. Bash загружается .bashrcв двух несвязанных обстоятельствах:

  • Когда это интерактивная оболочка, кроме случаев, когда это оболочка входа в систему (и кроме случаев, когда она вызывается как sh). Вот почему .bash_profileобычно загружается.bashrc .
  • Когда bash не является интерактивным, ни оболочка входа в систему, ни вызывается как, shно с заданной командой для выполнения -cи SHLVLне установлена ​​или меньше или равна 1, и выполняется одно из следующих действий:

    • Если стандартный ввод - это сокет. На практике это в основном происходит, когда bash вызывается rshd, т.е. когда выполняется rsh remotehost.example.com somecommand.
    • Если активирован во время компиляции (что имеет место в некоторых дистрибутивах, таких как Debian и производные), если одна из переменных среды SSH_CLIENTили SSH2_CLIENTопределена. На практике это означает , что Баш вызывается sshd, т.е. ssh remotehost.example.com somecommand.
      Если вы не знаете, как был скомпилирован bash, вы можете узнать, была ли установлена ​​эта опция, проверив, содержит ли двоичный файл строку SSH_CLIENT:

      strings /bin/bash | grep SSH_CLIENT
      

По SSH вообще

Когда вы выполняете команду через протокол SSH, команда передается по проводам в виде строки. Строка выполняется удаленной оболочкой. Когда вы запускаете ssh example.com somecommand, если оболочка входа удаленного пользователя работает /bin/bash, сервер SSH работает /bin/bash -c somecommand. Нет способа обойти оболочку входа в систему. Это разрешает ограниченные оболочки входа в систему, например, разрешает только копирование файлов, а не общее выполнение команд.

Есть одно исключение: протокол SSH позволяет клиенту запрашивать определенную подсистему. Если клиент запрашивает sftpподсистему, то по умолчанию сервер OpenSSH вызывает программу /usr/lib/openssh/sftp-server(местоположение может отличаться) через оболочку входа пользователя. Но он также может быть настроен для запуска внутреннего сервера SFTP через линию

Subsystem sftp internal-sftp

в sshd_configфайле. В случае внутреннего SFTP-сервера и только в этом случае оболочка входа пользователя в систему обходится.

Для этого вызова

В случае OverTheWire Bandit 18, .bashrcсодержит

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

Таким образом, вы можете решить этот уровень, делая все, чтобы bash не был интерактивным.

Как вы обнаружили, SFTP работает.
Но ssh bandit18@bandit.labs.overthewire.org cat readmeтакже будет работать.
Как бы echo 'cat readme' | ssh bandit18@bandit.labs.overthewire.org.
И нажатие Ctrl + C в нужное время во время интерактивного входа в систему также будет работать: это приведет к прерыванию bash, поэтому выполнение .bashrcне будет полностью выполнено. Для запуска Bash требуется макроскопическое время, поэтому, хотя это не работает надежно, это можно сделать на практике.

Жиль "ТАК - прекрати быть злым"
источник
2
Я не думаю , что работает SFTP колотить вообще , а не только не интерактивно.
user253751
@immibis Я верю, что ты прав насчет этого. Я использовал SFTP для обмена файлами в учетной записи пользователя, которая была настроена с некоторым приложением в качестве оболочки входа в систему, а не «настоящей» оболочки.
Касперд
@immibis SFTP не запускает bash. Но если SFTP-сервер не является внутренним, sshdзапускается оболочка входа пользователя sftp-server. Следовательно, если оболочка входа не интерпретирует строку /usr/lib/openssh/sftp-serverкак «запустить команду /usr/lib/openssh/sftp-server», вы не можете использовать SFTP.
Жиль "ТАК - перестань быть злым"
5

Выполняется .bashrcтолько при запуске оболочки.

Сервер SSH можно настроить так, чтобы он не запускал оболочку для протокола SFTP, указав команду Subsystem internal-sftpв sshd_configфайле сервера .

Предположение: вполне вероятно, что именно так настроена варгейм OverTheWire Bandit, а не настройка, .bashrcпотому что в противном случае то же ограничение для sshтакже заблокирует команду sftpсервера.

roaima
источник
2
Запуск SFTP делает запустить оболочку. Демон SSH запускается /path/to/shell -c /path/to/sftp-serverтам, где /path/to/shellнаходится оболочка входа пользователя. Если оболочкой входа пользователя является bash, то она .bashrcможет быть выполнена в зависимости от того, как был скомпилирован bash. Это всегда выполняется, когда bash выполняется rshd(да, даже для неинтерактивной оболочки, запуск bash странный), и опция времени компиляции расширяет это до sshd.
Жиль "ТАК - перестань быть злым"
Я пошел и проверил. Хорошая догадка, но на самом деле это не так тонко. exitВ .bashrcвыполняется только если Баш является интерактивным.
Жиль "ТАК - перестань быть злым"
@ Жиль, с Subsystem sftp internal-sftpи echo No.; exit 1по моему .bashrcя не получаю sshдоступ к серверу, но sftpвсе еще работает. (И тогда, конечно, потенциально возможно перезаписать или удалить .bashrc. Разрешения, несмотря на это.) sshПопытка подключения терпит неудачу, интерактивная или нет. С другой стороны, если у меня есть, Subsystem sftp /usr/lib/openssh/sftp-serverто служба SFTP также не работает, когда .bashrcискажается.
roaima