Burlando o sniffer-detect

O sniffer-detect é um modulo para o nmap capaz de descobrir quando uma placa de rede está no modo promíscuo (o que é um forte indício de sniffer). Isso é surpreendente porque os sniffers são, em princípio, totalmente passivos, de sorte que não deveria haver como detectá-los. O sniffer-detect consegue porque há um bug na maneira como as pilhas de rede respondem a certos pacotes de broadcast, que faz com que a máquina responda a um pacote especial se estiver em modo promíscuo. Todavia, como vou mostrar, pelo menos no Linux isso é fácil de consertar, restaurando o caráter "invisível" dos sniffers.

Detectando uma placa em modo promíscuo

Vou começar mostrando um exemplo o funcionamento normal do sniffer-detect: considerando que o host 192.168.1.130 esteja com algum sniffer ligado (Wireshark, TCPDump, Ettercap, etc), para detectar usaríamos:

$ nmap -sV --script=sniffer-detect 192.168.1.130

O resultado será:

Host script results:
|_ sniffer-detect: Likely in promiscuous mode (tests: "11111111")

Driblando a detecção

Para contornar a heurística deste script no Linux, faremos os seguintes passos:

1) Instalar o bridge-utils:

# aptitude install bridge-utils

2) Criar uma interface bridge

# brctl addbr br0

3) Zerar o IP da nossa interface de rede principal

# ifconfig eth0 0

4) Vincular a nossa interface de rede atual a recém criada interface bridge

# brctl addif br0 eth0

5) Atribuir os antigos valores da nossa interface de rede principal

# ifconfig br0 192.168.1.130 netmask 255.255.255.0

6) Adicionar a nossa rota default para o gatway da rede

# route add default gw 192.168.1.1

7) Esperar 45 segundos para que a verificação do STP termine e a conectividade seja reestabelecida

8) Instalar o ebtables

# aptitude install ebtables

9) Adicionar uma regra que permita para pacotes de broadcast (sem ela, requisições ARP comuns seriam negadas)

# ebtables -A INPUT -d FF:FF:FF:FF:FF:FF -j ACCEPT

10) Bloquear pacotes para algumas faixas de MAC específicas

# ebtables -A INPUT -d 01:00:00:00:00:00/FF:00:00:00:00:00 -j DROP
# ebtables -A INPUT -d FF:00:00:00:00:00/FF:00:00:00:00:00 -j DROP

Após isso poderemos executar um sniffer qualquer em nossa interface de rede principal de forma invisível para o sniffer-detect.

Como a detecção funciona

O script utiliza uma técnica descrita num paper de Daiji Sanai publicado em agosto de 2001. Vou aqui fazer uma explicação bem resumida, para detalhes, leia o paper original.

Em modo normal (sem ser o modo promíscuo), a própria placa de rede implementa um filtro que só aceita quadros destinados aos seguintes endereços:

  • Próprio endereço (MAC)
  • Endereço de Broadcast
  • Endereços de Multcast em que a placa esteja escrita.

Em modo promíscuo, uma placa de rede desativa seu filtro passa a aceitar todos os pacotes que chegam e passa a ser responsabilidade exclusiva do sistema operacional descartar pacotes que não sejam destinados para ele próprio. O autor notou que o filtro do sistema operacional opera de forma diferente do filtro de hardware quando os endereços de destino são de broadcast ou multicast, o que permite diferenciar remotamente se a placa está em modo promíscuo o não.

Especificamente, para identificar em qual modo a placa de rede esta operando, o autor sugere que seja criado um pacote com as seguintes características;

  • Seja capaz de ser tratado e respondido pelo Kernel.
  • Seja incapaz de passar o filtro da placa de rede em modo normal, Para conseguir esta característica o autor propôs a utilização de pacotes ARP, que têm uma vantagem adicional: por ser um protocolo de camada 2, não é filtrado por firewalls convencionais. Assim, mesmo se você estiver usando um firewall, a detecção de sniffers ainda funcionará.

Como são destinados a broadcast, os pacotes ARP são capazes de passar os filtros da placa de rede, onde a mesma irá repassa-los ao kernel, que é quem decidirá se responde ou se descarta o pacote em questão. Para tomar esta decisão o kernel basicamente verifica se tem o endereço IP solicitado, respondendo então direto para o endereço MAC do solicitante, caso contrário o pacote será descartado. Reparem que em nenhum momento o kernel verifica para qual endereço MAC o pacote ARP foi enviado, ele simplesmente entende que isso já foi devidamente tratado pelo filtro da placa de rede. Isso já garante a primeira parte do plano "Seja capaz de ser tratado e respondido pelo Kernel".

Para conseguir a segunda parte, o pacote ARP precisa sofrer uma pequena modificação. Ao invés de enviar-lo para broadcast, ele será enviado para alguns endereços de multcast, onde uma placa de rede em modo normal provavelmente descartaria estes pacotes. E assim conseguimos a segunda parte "Seja incapaz de passar o filtro da placa de rede em modo normal".

Com esse pacote criado a detecção se torna simples, o script envia esses pacotes para um alvo, caso sejam respondidos o script subentende que esse alvo esta em modo promiscuo, caso contrario ele pressupõe que o filtro da placa de rede esta habilitado, e que por isso a placa esta operando de forma normal.

Caso haja uma maquina inscrita em um grupo de multcast para o qual o pacote ARP foi enviado, isso poderia gerar um falso positivo. Para diminuir as chances desse tipo de problema ocorrer, o script em questão envia oito pacotes para oito endereços de multcast diferentes.

Como a anti-detecção funciona

Sabendo que os pacotes de detecção enviados pelo script são da camada de enlace, basta apenas bloquearmos os pacotes destinados a estes endereços. Para executar essa tarefa, faz-se necessário utilização de um firewall na camada de enlace. No exemplo supracitado utilizamos o ebtables como firewall de camada dois (enlace).

O ebtables só irá funcionar em interfaces que estejam operando em camada dois, para isso criamos uma interface bridge virtual, e vinculamos a ela a nossa interface de rede principal. Com essa interface devidamente configurada, utilizamos o ebtables para bloquear os pacotes destinados a endereços de multcast, e com isso conseguimos contornar o sniffer-detect.

Agradecimentos a Marco "Kiko" Carnut por me ajudar a entender os detalhes da técnica de detecção e pela sugestão de usar o ebtables.

Comentários
Aceita-se formatação à la TWiki. HTML e scripts são filtrados. Máximo 15KiB.

 
Enviando... por favor aguarde...
Comentário enviado com suceso -- obrigado.
Ele aparecerá quando os moderadores o aprovarem.
Houve uma falha no envio do formulário!
Deixei uma nota para os admins verificarem o problema.
Perdoe-nos o transtorno. Por favor tente novamente mais tarde.
The Illuminati | 2011-06-19 15:01:09 | permalink | topo

BOA PERGUNTA, PEQUENO GAFANHOTO

Tímido Visitante Anônimo | 2010-09-13 20:33:07 | permalink | topo

Olha no windows você instala o VMware e levanta uma VM contendo uma distribuição Linux, sendo assim você segue os passos descritos no post.

Abraços.

Tímido Visitante Anônimo | 2010-09-02 22:16:16 | permalink | topo

Alô!

E no Windows, como consertar?

Joao Lins | 2010-09-02 09:51:33 | permalink | topo

Frank,

Muito legal. Ficou show seu post, está bem instrutivo.

[]'s

Marco Carnut | 2010-09-01 15:54:47 | permalink | topo

Frank,

Uma sugestão adicional: podemos alterar as regras do ebtables para além de negar os pacotes-sonda do sniffer-detect, registrá-los também:

ebtables -A INPUT -d FF:00:00:00:00:00/FF:00:00:00:00:00 \
    --log --log-level=6 --log-prefix='ALERT SNIFFER-DETECT ' -j DROP
ebtables -A INPUT -d 01:00:00:00:00:00/FF:00:00:00:00:00 \
    --log --log-level=6 --log-prefix='ALERT SNIFFER-DETECT ' -j DROP

Isso é legal porque se o alerta aparecer, você não só permanece indetectável, mas também fica sabendo que tem algum espertinho na rede. :)

Ademais, parabéns pelo post, ficou ótimo! E obrigado pelos créditos.

-K.