CERT.br

Ir para o conteúdo

Núcleo de Informação e Coordenação do Ponto BR

Sugestões para defesa contra ataques de força bruta para SSH

Autor: Nelson Murilo
Versão: 1.3 -- 10/08/2007

Sumário

Descrição do problema

O serviço SSH vem se tornando cada dia mais popular, por conta da sua facilidade de uso, clientes disponíveis para qualquer sistema operacional moderno e, principalmente, pela segurança na autenticação e proteção (criptografia) do tráfego. E é exatamente por conta da maior segurança conseguida com o uso do SSH que muitos administradores têm negligenciado a escolha das senhas.

A despeito do SSH permitir vários métodos de autenticação, o tradicional usuário/senha é, em geral, escolhido pela conveniência na configuração e facilidade de uso por parte do usuário, todavia senhas fracas estão sujeitas a adivinhação e ataques de força bruta, e tem sido este (descobrir senhas fracas) o objetivo dos ataques de dicionário verificados contra servidores SSH.

Considerando que a maior parte do sistemas Unix modernos vem com o serviço SSH habilitado e, mais ainda, vários equipamentos como roteadores e switches também têm o serviço disponível, muitas vezes um serviço pode estar habilitado sem que o administrador se dê conta da sua exposição.

Características do ataque

Cada dia mais são verificadas tentativas de ataques de dicionário contra servidores SSH. Algumas bases de usuário/senha estão disponíveis em sítios na Internet e vários atacantes estão montando suas próprias listas e ferramentas para perpetrar este tipo de ataque. Têm-se observado o uso não somente de dicionários na língua inglesa, mas também em outros idiomas, PORTUGUÊS inclusive.

Um exemplo de um registro de tentativas de ataque pode ser visto abaixo:

 Sep 21 12:02:06 srv sshd[48770]: Failed password for invalid user ricky from 192.0.2.251 port 58987 ssh2
 Sep 21 12:02:08 srv sshd[48772]: Failed password for invalid user ricky from 192.0.2.251 port 59042 ssh2
 Sep 21 12:02:09 srv sshd[48774]: Failed password for invalid user ricky from 192.0.2.251 port 59094 ssh2
 Sep 21 12:02:10 srv sshd[48776]: Failed password for invalid user ricky from 192.0.2.251 port 59131 ssh2
 Sep 21 12:02:11 srv sshd[48778]: Failed password for invalid user ricky from 192.0.2.251 port 59182 ssh2
 Sep 21 12:02:13 srv sshd[48780]: Failed password for invalid user ricky from 192.0.2.251 port 59218 ssh2
 Sep 21 12:02:14 srv sshd[48782]: Failed password for invalid user roy from 192.0.2.251 port 59268 ssh2
 Sep 21 12:02:15 srv sshd[48784]: Failed password for invalid user roy from 192.0.2.251 port 59316 ssh2
 Sep 21 12:02:17 srv sshd[48786]: Failed password for invalid user roy from 192.0.2.251 port 59358 ssh2
 Sep 21 12:02:18 srv sshd[48788]: Failed password for invalid user roy from 192.0.2.251 port 59405 ssh2
 Sep 21 12:02:19 srv sshd[48790]: Failed password for invalid user roy from 192.0.2.251 port 59452 ssh2
 Sep 21 12:02:20 srv sshd[48792]: Failed password for invalid user roy from 192.0.2.251 port 59491 ssh2

Deve-se notar, também, que cada tentativa de conexão faz com que o servidor SSH abra uma nova instância para atender ao possível acesso, fato que pode comprometer seriamente o desempenho do servidor, em função da quantidade de tentativas e freqüência da incidência dos ataques.

Na seção Assinatura para o Snort está disponível uma assinatura para detectar ataques gerados por uma ferramenta que têm sido bastante utilizada para desferir estes ataques.

Sugestões para defesa

As sugestões para defender-se deste tipo de ataque são de vários tipos, que vão desde simples troca de porta do serviço até configurações de novos serviços e regras em firewall. As sugestões podem ser adotadas de forma isolada, mas não existe nenhum impedimento em combiná-las, muito pelo contrário, a adoção de várias delas combinadas é altamente recomendável.


Redução no número de equipamentos com serviço aberto para Internet

Esta sugestão se baseia no simples fato de que quanto menos máquinas expostas, menor será o risco. Isso torna mais fácil o monitoramento, dada a menor quantidade de equipamentos a serem vigiados. A implantação desta sugestão não evita a varredura e ataques aos equipamentos que ainda permanecerem expostos.


Filtragem de origem

Vários servidores SSH não têm a real necessidade de manter o serviço exposto para qualquer origem, em geral um número limitado de redes/usuários deveriam acessar, remotamente, um determinado servidor, mas estes costumam ser deixados sem limites por conta da conveniência. Uma vez definidas de quais redes que o administrador efetivamente necessitaria ter acesso remoto, os filtros podem ser implementados de mais de uma maneira, pode ser um bloqueio no roteador ou firewall de borda.

Outra possibilidade é a seleção das origens permitidas por serviço, usando recursos como tcpwrappers.


Limitação de recursos

Outra sugestão interessante é a de limitar a utilização dos recursos do serviço, no caso do OpenSSH isso pode ser feito através de cláusulas como MaxStartups e MaxAuthTries, que definem, respectivamente, a quantidade de instâncias não autenticadas simultâneas (por padrão são 10), e quantas tentativas sem sucesso são permitidas por usuário (por padrão são 6).


Mover o serviço para uma porta não padrão

De simples implementação, no caso do OpenSSH basta editar o arquivo sshd_config e substituir, na cláusula Port, a porta 22 por outro valor. Note que este artifício é considerado "segurança por obscuridade", ou seja, não é exatamente uma medida corretiva, apenas um paliativo, visto que os ataques, por uma questão de conveniência, tendem a buscar somente a porta padrão (22/tcp).

Outra questão é sobre a necessidade de substituir rotinas automatizadas como cópias de segurança remotas, retreinamento do usuário e uma coisa a mais para lembrar (documentar) quando da atualização do pacote, ou instalação de um novo servidor.

Por fim é preciso lembrar que alguns firewalls de empresas bloqueiam portas de serviços que não são utilizadas, o que pode ser um problema para um acesso remoto emergencial, visto que um administrador pode não conseguir alcançar sua rede, por conta de um bloqueio feito na rede onde ele está no momento que foi avisado de algum problema.


Acesso somente via chaves públicas

De fácil configuração, bastando (no OpenSSH) mudar para "no" as cláusulas PasswordAuthentication e UsePAM, além de gerar o par de chaves para os usuários e equipamentos envolvidos na autenticação (clientes e servidores).

Os principais inconvenientes ficam por conta da dificuldade de conexão via equipamento de terceiros e o treinamento dos usuários. Vale lembrar que este recurso pode não ser de uso simples em alguns clientes SSH e que outros sequer possuem esta funcionalidade.


Limitar início de conexão (SYN)

Algumas ferramentas de ataque, para ganhar eficiência, disparam várias cópias de si mesmas, sendo deste modo interessante configurar no firewall alguns limitadores. Por exemplo, usando o firewall padrão do FreeBSD, é possível criar uma regra com a cláusula "limit" associada, para informar quantas conexões simultâneas são permitidas para aquela regra, por exemplo:

 ipfw add allow tcp from any to 200.XX.XX.6 22 limit src-addr 1

Quando utilizado o IPFilter (FreeBSD/NetBSD/Sun/Solaris/HP-UX), um exemplo de uso seria:

 pass in quick proto tcp from any to 200.XX.XX.6 port = 22 keep limit 1
No caso do PF (OpenBSD), o exemplo abaixo poderia ser usado:
 pass in quick proto tcp from any to 200.XX.XX.6 port 22 flags S/SA \
 keep state (max-src-states 1)

Existe uma extensão disponível para netfilter (chamada ipt_recent) que permite configurar um período de tempo no qual uma determinada conexão pode ocorrer, por exemplo a cada 120 segundos:

 iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
 iptables -A INPUT -p tcp --dport ssh -m recent --update --seconds 120 -j DROP
 iptables -A INPUT -p tcp --dport ssh --tcp-flags syn,ack,rst syn -m recent --set -j ACCEPT

Essa abordagem tem um efeito colateral positivo interessante, pois permite bloquear um ataque já no momento da varredura, que normalmente precede o ataque de força bruta do serviço SSH.


Configurar pacote knockd

O programa KNOCKD está disponível atualmente para sistemas Linux, e atua de forma a permitir que, somente após o usuário enviar uma seqüência previamente conhecida de pacotes, o programa ative um serviço pré-determinado, SSH no nosso caso. É composto de um servidor (knockd) e um cliente (knock) responsável por enviar os pacotes da maneira como o knockd espera receber.

No exemplo abaixo foi inventada uma seqüência de pacotes que indicasse, ao knockd, que ele deveria iniciar a execução do serviço SSH. O arquivo de configuração knock.conf foi configurado de maneira que, para iniciar o serviço, o programa deve receber um pacote (SYN) tcp nas portas 100 e 200 e um pacote UDP na porta 300:

 [openSSH]
        sequence    = 100:tcp,200:tcp,300:udp seq_timeout = 5 command
        = /etc/init.d/ssh start tcpflags    = syn

 [closeSSH]
        sequence    = 300:udp,200:tcp,100:tcp seq_timeout = 5 command
        = /etc/init.d/ssh stop tcpflags    = syn

E para finalizá-lo deve receber a seqüência inversa.

Foi então executado:

   # knock sitio.org.br 100:tcp 200:tcp 300:udp

Para fechar o serviço foi executado na ordem inversa:

   # knock sitio.org.br 300:udp 200:tcp 100tcp

Nos logs ficou registrado:

 [2005-09-23 23:47] starting up, listening on eth0
 [2005-09-23 23:47] 10.0.0.1: openSSH: Stage 1
 [2005-09-23 23:47] 10.0.0.1: openSSH: Stage 2
 [2005-09-23 23:47] 10.0.0.1: openSSH: Stage 3
 [2005-09-23 23:47] 10.0.0.1: openSSH: OPEN SESAME
 [2005-09-23 23:47] openSSH: running command: /etc/init.d/ssh start

 [2005-09-24 00:00] 127.0.0.1: closeSSH: Stage 1
 [2005-09-24 00:00] 127.0.0.1: closeSSH: Stage 2
 [2005-09-24 00:00] 127.0.0.1: closeSSH: Stage 3
 [2005-09-24 00:00] 127.0.0.1: closeSSH: OPEN SESAME
 [2005-09-24 00:00] closeSSH: running command: /etc/init.d/ssh stop

Esta solução tem alguns inconvenientes, uma vez que além de tornar mais complexa a ação de login remoto, pois necessita de um passo adicional, o administrador ainda deve escolher com bastante cuidado as portas usadas na sinalização, por conta de possíveis bloqueios quando atrás de firewalls.

Outro dificultador é o fato de que em alguns ambientes o acesso à Internet se dá somente através de proxy, entre outras limitações de protocolos e portas, tornando ainda mais complicado o envio de uma seqüência, de pacotes, para um equipamento remoto.

Assinatura para o Snort

Têm sido observada a utilização, em larga escala, de uma ferramenta para realizar ataques de força bruta de SSH, que gera tráfego com características peculiares. Estas características podem ser identificadas no tráfego de rede através de sistemas de detecção de intrusão (IDS).

A seguir é apresentada uma assinatura para o IDS Snort que identifica ataques na porta 22 gerados por esta ferramenta:


    alert tcp $EXTERNAL_NET any -> $HOME_NET 22 \
    (msg:"Possible SSH brute force attempt"; \
    flow:to_server,established; \
    threshold:type threshold, track by_src, count 5, seconds 60; \
    content:"SSH-2.0-libssh-0.1"; offset: 0; depth: 18;)

Vale ressaltar que o tráfego só é detectado nos casos em que a ferramenta conseguir estabelecer conexões na porta 22/tcp (SSH).

Referências

Agradecimentos

Histórico de Revisões

$Date: 2017/02/13 20:18:06 $