Quando próximo, finja estar longe; quando longe, finja estar próximo

Imagine que você tem um serviço que fica escutando diretamente para a Internet. Pode ser um micro-serviço rodando em um Container, um Apache, Nginx ou um SSH, não importa, fiz com SSH por que já estava à mão. Logicamente, seu serviço por estar tão exposto, está sujeito a ataques. O que você faz em um caso desses?

[ Hits: 2.709 ]

Por: Carlos Affonso Henriques. em 13/04/2020


Introdução



NOTA: o título do artigo é uma famosa citação de Sun Tze no clássico "A Arte da Guerra".

Em 15 de janeiro de 2020, fui a uma entrevista de emprego em uma empresa próxima à minha casa para o cargo de SecDevOps e, após uma reunião de quase 3 horas com o CEO e o CISO da empresa, chegando à porta do meu prédio o porteiro havia ido ao banheiro e fiquei impossibilitado de entrar.

Para completar, minha mulher estava na academia do prédio e não estava com celular, só restava-me esperar. Como estava com fome, atravessei a rua e fui comer um espetinho e beber uma cerveja numa banca de comida de rua que há em frente à minha casa. Saboreando um churrasquinho com cerveja, fiquei pensando na reunião que havia tido a menos e uma hora e com o fato do porteiro haver me deixado na rua, foi aí que surgiu a ideia para esse artigo. Um porteiro escondido!

Imagine que você tem um serviço que fica escutando diretamente para a Internet. Pode ser um micro-serviço rodando em um Container, um Apache, Nginx ou um SSH, não importa, fiz com SSH por que já estava à mão. Logicamente, seu serviço por estar tão exposto, está sujeito a ataques.

O que você faz em um caso desses? Aplica um filtro de pacotes (Netfliter, PF etc), aumenta o tempo de reposta a requisições SYN, adota um serviço de redirecionamento? É, todas mais ou menos legais, mas ainda assim saberão que seu serviço está rodando nesse Host e naquela porta. Isso já o torna um alvo.

A melhor maneira de não ser um alvo é camuflar-se, esconder-se e melhor ainda, não existir! Quer realmente esconder-se de seus inimigos? Deixe-os acreditando que você está morto.

O script

#!/bin/bash

listenudp()

    {

    while true
        do
        systemctl -q status sshd.service >/dev/null
        # Testa se o serviço sshd está rodando se não estiver levanta o netcat escutando na porta 1500 UDP
        if [ ${?} != 0 ]; then
        # o Netcat escuta durante 6 segundos e depois cessa isso é usado por duas razões a saber:
        # 1ª Por que a opção -k, --keep-open que mantém o Netcat ouvindo uma porta não funciona com o protocolo UDP
        # 2ª Por que o serviço rodando de forma intermitente é indetectável por port-scanners como o Nmap por exemplo.
        timeout 6 nc -ul 1500 | while read line; do echo -e "$line" > keeper.log; done
        greplog
        else
        # Pára (Tá errado pelo novo acordo gramatical eu sei! Mas sou coroa!) o serviço sshd se ele estiver rodando
        systemctl -q stop sshd.service >/dev/null
    fi

    done
    }

# Chamei de greplog por que estava com preguiça de escolher outro nome para a função!
greplog()
    {
    # Verifica se a "senha" que defini como "1234" foi inserida no arquivo keeper.log Só pelo amor de Deus não me vão colocar "1234" em um ambiente de produção.
    grep -oq "1234" keeper.log
    if [ ${?} = 0 ]; then
        #echo
        systemctl -q start sshd.service >/dev/null
        cat /dev/null > keeper.log
        # Aguarda uma conexão ssh durante 20 segundos, se não ocorrer o script pára o serviço sshd e recomeça.
        sleep 20
        else
        :
    fi
    }

listenudp
 

Servidor SSH

Acessando o servidor SSH:

# echo "1234" | nc -u 192.168.122.100 1500

Executando a linha de comando acima, você terá 20 segundos para conectar via SSH. Não se preocupe, pois o serviço não cairá com você conectado (se sua distro estiver usando o SystemD).

Onde:
  • 192.168.122.100 é o IP da máquina virtual que criei.
  • 1500 é a porta UDP.

Agora, uma magia negra! Experimente:

# nmap -sU -p 1500 192.168.122.100

O Nmap vai retornar a porta como "closed", ou seja, nenhum serviço está escutando nessa porta. Lembram dos 6 segundos?

Isso mostra que uma solução de segurança sofisticada não precisa necessariamente ser complexa. Essa é a Escola de Design Russa.

   

Páginas do artigo
   1. Introdução
Outros artigos deste autor

Customizando e atualizando o Slax

Docker - Combatento o COVID-19

Impedindo o compartilhamento de conexão

TrueCrypt Forever

Access Point com cartão Atheros em Slackware 12.0

Leitura recomendada

Alta disponibilidade com IP compartilhado - UCARP

SELinux - Segurança em Servidores GNU/Linux

Configurando um servidor de logs simples

Instalação do Fail2Ban no CentOS 7

Projeto Sharingan

  
Comentários
[1] Comentário enviado por BRVN01 em 15/04/2020 - 07:34h

Bom dia, Carlos!
Muito bom o script, técnica muito boa, nunca vi nada assim, obrigado por compartilhar esse tipo de informação.
Tomei a liberdade de implementar algumas coisas no script, como um arquivo de log para saber quem esta tentando abrir a porta, um arquivo chamado HASHS.txt contendo os usuários e senhas que poderão abrir a porta, assim saberemos no arquivo de log quem tentou abrir.

------------------------------------------------------------------------------------------------------------
Arquivo HASHS.TXT (exemplo):

user=teste&pass=1234
user=teste123&pass=zdfg
user=tux&pass=olatux

------------------------------------------------------------------------------------------------------------
Lembrando que o arquivo HASHS é totalmente customizável por quem for utilizar!

------------------------------------------------------------------------------------------------------------
SCRIPT que fica mostrando se a porta esta UP ou não:

#!/bin/bash

while true; do
data=$(date +%d-%m-%y_%H-%M-%S)
var=$(nmap -PnsU -p 22 192.168.0.11 | grep "22\/tcp")
echo "$data---$var"
sleep 1
done
------------------------------------------------------------------------------------------------------------
Exemplo de como funciona o script acima:

15-04-20_06-32-21---22/tcp closed ssh
15-04-20_06-32-23---22/tcp closed ssh
15-04-20_06-32-24---22/tcp closed ssh
15-04-20_06-32-26---22/tcp open ssh
15-04-20_06-32-27---22/tcp open ssh
15-04-20_06-32-28---22/tcp open ssh
15-04-20_06-32-30---22/tcp open ssh
15-04-20_06-32-31---22/tcp open ssh
15-04-20_06-32-33---22/tcp open ssh
15-04-20_06-32-34---22/tcp open ssh
15-04-20_06-32-36---22/tcp closed ssh
15-04-20_06-32-37---22/tcp closed ssh

------------------------------------------------------------------------------------------------------------
Script em sí:

#!/bin/bash

data=$(date +%d-%m-%y_%H-%M-%S) # Pega a data + hora

listenudp()

{

while true; do
systemctl -q status sshd.service >/dev/null

# Testa se o serviço sshd está rodando se não estiver levanta o netcat escutando na porta 1500 UDP
if [ ${?} != 0 ]; then

# o Netcat escuta durante 6 segundos e depois cessa isso é usado por duas razões a saber:

# 1ª Por que a opção -k, --keep-open que mantém o Netcat ouvindo uma porta não funciona com o protocolo UDP
# 2ª Por que o serviço rodando de forma intermitente é indetectável por port-scanners como o Nmap por exemplo.
# '&& echo "$data--$line" >> access.log;' é um "sistema" de log, assim saberemos quem tentou abrir a porta
timeout 6 nc -ul 22 | while read line; do echo -e "$line" > keeper.log && echo "$data--$line" >> access.log; done

greplog

else
# Para o serviço sshd, se ele estiver rodando
systemctl -q stop sshd.service >/dev/null
fi

done
}

greplog()
{
# Verifica se a "senha" que defini como "1234" foi inserida no arquivo keeper.log Só pelo amor de Deus não me vão colocar "1234" em um ambiente de produção.

for hash in $(cat hashs.txt);do # Começa a leitura dos "HASHS" para verificar as permissões da abertura da pora

if [ $(egrep $hash keeper.log) ]; then # Verifica se o comando dentro do IF retorna True ou False (0 ou diferente de 0)
systemctl -q start sshd.service >/dev/null
echo "" > keeper.log # zara o arquivo

# Aguarda uma conexão ssh durante 20 segundos, se não ocorrer o script pára o serviço sshd e recomeça.
sleep 10

else
continue # Retorna para o inicio do loop
fi
done
}

listenudp

[2] Comentário enviado por cizordj em 15/04/2020 - 18:52h

Parabéns, que baita artigo!
________________________________________________
O programador tem a mania de achar que tudo é objeto

[3] Comentário enviado por CapitainKurn em 18/04/2020 - 23:43h


[2] Comentário enviado por Cizordj em 15/04/2020 - 18:52h

Parabéns, que baita artigo!
________________________________________________
O programador tem a mania de achar que tudo é objeto


Que bom que gostou! Obrigado!

[4] Comentário enviado por gpxlnx em 27/04/2020 - 09:14h

Muito boa ideia, só uma cerveja para inspirar uma ideia como essa kkkk. Parabéns por mais esse excelente artigo e obrigado por compartilhar.

[5] Comentário enviado por CapitainKurn em 01/05/2020 - 13:05h


[4] Comentário enviado por gpxlnx em 27/04/2020 - 09:14h

Muito boa ideia, só uma cerveja para inspirar uma ideia como essa kkkk. Parabéns por mais esse excelente artigo e obrigado por compartilhar.


Uma canabis também ajuda bastante! Rssss

[6] Comentário enviado por Tecnolobo em 23/07/2022 - 12:52h

Abordagem interessante. Eu pessoalmente prefiro usar o iptables e criar um "port knocker" (batida secreta) pra abrir a porta em momentos específicos e por tempo limitado. E usar o limit junto pra dificultar ataques de força Bruta.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts