De que maneira o SFTP não é baseado no SSH?

9

Acabei de completar o jogo de guerra OverTheWire Bandit, nível 18 .

Isso foi uma surpresa. Aqui estão as instruções para este nível.

A senha do próximo nível é armazenada em um arquivo leia-me no diretório doméstico. Infelizmente, alguém modificou .bashrc para desconectá-lo quando você faz login com SSH.

Eu estava pensando em uma maneira de fazer o shell pular a fonte .bashrc. Mas antes de descobrir uma solução, fiquei tentado a simplesmente iniciar uma conexão SFTP com o servidor. Eu não esperava que funcionasse. Mas sim. E eu gostaria de saber o porquê. Eu pensei que o SFTP atropela o SSH.

Para maior clareza, quando eu SSH no servidor, sou expulso, como esperado.


fonte
1
O SFTP é executado sobre SSH. O bash também pode atropelar o SSH. Mas o SFTP não é executado no bash. (observe que eu estou usando "atropelar" vagamente aqui))
user253751 01/10/16

Respostas:

13

Na festança em geral

O design do Bash em relação aos arquivos de inicialização é bastante peculiar. O Bash é carregado .bashrcem duas circunstâncias não relacionadas:

  • Quando é um shell interativo, exceto quando é um shell de logon (e exceto quando é chamado como sh). É por isso que .bash_profilenormalmente carrega.bashrc .
  • Quando o bash não é interativo, nem um shell de login, nem invocado, shmas recebe um comando para executar com -ce SHLVLé desabilitado ou menor ou igual a 1, e uma das seguintes opções é verdadeira:

    • Se a entrada padrão for um soquete. Na prática, isso acontece principalmente quando o bash é invocado por rshd, ou seja, durante a execução rsh remotehost.example.com somecommand.
    • Se ativado em tempo de compilação (que é o caso de algumas distribuições, como Debian e derivativos), se uma das variáveis ​​de ambiente SSH_CLIENTou SSH2_CLIENTestiver definida. Na prática, isso significa que o bash é invocado por sshd, ie ssh remotehost.example.com somecommand.
      Se você não souber como o bash foi compilado, poderá descobrir se essa opção foi configurada verificando se o binário contém a sequência SSH_CLIENT:

      strings /bin/bash | grep SSH_CLIENT
      

No SSH em geral

Quando você executa um comando através do protocolo SSH, o comando é passado pela conexão como uma sequência. A cadeia é executada pelo shell remoto. Quando você executa ssh example.com somecommand, se o shell de logon do usuário remoto estiver /bin/bash, o servidor SSH será executado /bin/bash -c somecommand. Não há como ignorar o shell de login. Isso permite shells de login restritos, por exemplo, para permitir apenas a cópia de arquivos e não a execução geral de comandos.

Há uma exceção: o protocolo SSH permite que o cliente solicite um subsistema específico. Se o cliente solicitar o sftpsubsistema, por padrão, o servidor OpenSSH chama o programa /usr/lib/openssh/sftp-server(a localização pode variar) por meio do shell de login do usuário. Mas também pode ser configurado para executar um servidor SFTP interno através da linha

Subsystem sftp internal-sftp

no sshd_configarquivo No caso do servidor SFTP interno, e somente nesse caso, o shell de logon do usuário é ignorado.

Para este desafio

No caso do OverTheWire Bandit 18, .bashrccontém

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

Assim, você pode resolver esse nível fazendo qualquer coisa que faça com que o bash não seja interativo.

Como você descobriu, o SFTP funciona.
Mas ssh [email protected] cat readmetambém funcionaria.
Como seria echo 'cat readme' | ssh [email protected].
E pressionar Ctrl + C no momento certo durante um login interativo também funcionaria: ele interromperia o bash, para .bashrcque não fosse completamente executado. O Bash leva um tempo macroscópico para iniciar, portanto, embora isso não funcione de maneira confiável, pode ser feito na prática.

Gilles 'SO- parar de ser mau'
fonte
2
Eu não acho que SFTP execuções bater em tudo , não apenas não interativa.
precisa saber é o seguinte
@immibis Eu acredito que você está certo sobre isso. Eu usei o SFTP para trocar arquivos em uma conta de usuário que foi configurada com algum aplicativo como o shell de login em vez de um shell "real".
kasperd
@immibis SFTP não executa bash. Mas, a menos que o servidor SFTP seja interno, sshdexecute o shell de login do usuário que é executado sftp-server. Portanto, se o shell de login não interpretar a string /usr/lib/openssh/sftp-servercomo "execute o comando /usr/lib/openssh/sftp-server", você não poderá usar o SFTP.
Gilles 'SO- stop be evil' em
5

O .bashrcé executado apenas quando você inicia um shell.

O servidor SSH pode ser configurado para não iniciar um shell para o protocolo SFTP, fornecendo o comando Subsystem internal-sftpno sshd_configarquivo do servidor .

Conjectura: é provável que seja assim que o jogo de guerra do OverTheWire Bandit esteja realmente configurado, e não um ajuste, .bashrcporque, caso contrário, a mesma restrição para sshtambém bloquearia o sftpcomando do servidor.

roaima
fonte
2
Correndo SFTP faz iniciar uma shell. O daemon SSH é executado /path/to/shell -c /path/to/sftp-serveronde /path/to/shellestá o shell de login do usuário. Se o shell de login do usuário for bash, ele .bashrcpoderá ser executado dependendo de como o bash foi compilado. É sempre executado quando o bash é executado por rshd(sim, mesmo para um shell não interativo, a inicialização do bash é estranha) e uma opção em tempo de compilação estende isso para sshd.
Gilles 'SO- stop be evil
Eu fui e verifiquei. Bom palpite, mas na verdade não é tão sutil. O exitin .bashrcsó é executado se o bash for interativo.
Gilles 'SO- stop being evil' em
@Gilles, com Subsystem sftp internal-sftpe echo No.; exit 1no meu .bashrceu não tenho sshacesso ao servidor, mas sftpainda funciona. (E, é claro, é potencialmente possível substituir ou remover as .bashrcpermissões. Não obstante.) A sshtentativa de conexão falha, seja interativa ou não. Por outro lado, se eu tiver Subsystem sftp /usr/lib/openssh/sftp-server, o serviço SFTP também falhará quando .bashrcfor mutilado.
roaima