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.672 ]

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

Docker: Uma abordagem didática para tempos obscuros

O que é ForceCommand

Rodando contêineres e aplicações Linux x86 no Raspberry Pi

Obtendo TimeStamps da Blockchain com OpenTimestamps

Sistema de arquivos criptografado

Leitura recomendada

Procurando rootkits no seu sistema

Como saber se houve uma invasão

Configurando proxy no shell

Instalando o PFSense em uma máquina virtual

Resumo da Norma ISO/IEC 13335-3

  
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