Você está na página 1de 175

Chris Binnie

Novatec
All rights reserved. This translation is published under license with the original publisher John
Wiley & Sons, Inc. Copyright © 2016 by John Wiley & Sons, Inc., Indianapolis, Indiana.
Todos os direitos reservados. Tradução autorizada da edição em inglês intitulada Linux® Server
Security: Hack and Defend, publicada pela John Wiley & Sons, Inc. Copyright © 2016 por John
Wiley & Sons, Inc., Indianapolis, Indiana.
Nenhuma parte deste livro pode ser reproduzida, armazenada ou transmitida em qualquer formato
ou por qualquer meio, eletrônico, físico e etc., sem a autorização por escrito do titular original do
copyright, John Wiley & Sons, Inc. http://www.wiley.com/go/permissions
Todos os direitos reservados e protegidos pela Lei 9.610 de 19/02/1998. É proibida a reprodução
desta obra, mesmo parcial, por qualquer processo, sem prévia autorização, por escrito, do autor e da
Editora.
Editor: Rubens Prates
Tradução: Henrique Cesar Ulbrich
Revisão gramatical: Priscila A. Yoshimatsu
Editoração eletrônica: Carolina Kuwabata
ISBN: 978-85-7522-661-2
Histórico de edições impressas:
Janeiro/2017 Primeira edição
Novatec Editora Ltda.
Rua Luís Antônio dos Santos 110
02460-000 – São Paulo, SP – Brasil
Tel.: +55 11 2959-6529
E-mail: novatec@novatec.com.br
Site: www.novatec.com.br
Twitter: twitter.com/novateceditora
Facebook: facebook.com/novatec
LinkedIn: linkedin.com/in/novatec
Eu era terrível na escola. Reprovei tantas vezes em matemática que não
consigo nem contar.
— Stewart Francis
Sumário

Sobre o autor
Sobre o editor técnico
Como este livro é organizado
Quem deve ler este livro
Resumo
Capítulo 1 ■ Manto de invisibilidade
Contexto
Sondagem de portas
Como confundir um scanner de porta
Instalação do knockd
Pacotes
Alteração dos ajustes default
Alteração dos locais do sistema de arquivos
Algumas opções de configuração
Inicialização do serviço
Alteração da interface de rede default
Tipos de pacotes e temporizações
Teste da instalação
Clientes de port knocking
Como tornar o servidor invisível
Teste do iptables
Gravando as regras do iptables
Outras considerações
Cliente para smartphone
Pesquisa de problemas
Considerações de segurança
Sequências efêmeras
Resumo
Capítulo 2 ■ Coloque impressão digital em seus arquivos
Integridade do sistema de arquivos
Sistema de arquivos como um todo
Rootkits
Configuração
Falso-positivos
Bem projetado
Resumo
Capítulo 3 ■ Netcat no século 21
História
Pacotes de instalação
Para começar
Transferência de arquivos
Exemplo de bate-papo
Encadeamento de comandos
Comunicações seguras
Executáveis
Listas de controle de acesso
Opções diversas
Resumo
Capítulo 4 ■ Negação de serviço
Infraestrutura NTP
Ataques reflexivos NTP
Relatórios de ataques
Prevenção de reflexões SNMP
Resolvedores DNS
Cumplicidade
Uma nação de joelhos
Mapeamento de ataques
Resumo
Capítulo 5 ■ Nping
Funcionalidade
TCP
Intérprete
UDP
ICMP
ARP
Opções de payload
Modo Eco
Outras opções Nping
Resumo
Capítulo 6 ■ Análise de logs
Equívocos no uso de ICMP
tcpdump
Iptables
Regras multipartes
Registro completo para análise forense
Hardening
Resumo
Capítulo 7 ■ O prodigioso NSE do Nmap
Escaneamento de portas básico
Motor de script do Nmap
Modelos de temporização (timing templates)
Categorização de scripts
Fatores de contribuição
Falhas de segurança
Testes de autenticação
Descoberta
Atualização de scripts
Tipos de script
Expressões regulares
Interfaces gráficas de usuário
Zenmap
Resumo
Capítulo 8 ■ Detecção de malware
Para começar
Frequência de atualização das definições
Registro de hashes de malware
Ameaças prevalentes
Funcionalidades LMD
Monitoração de sistemas de arquivos
Instalação
Modos de monitoração
Configuração
Exclusões
Execução a partir da CLI
Relatórios
Quarentena e limpeza
Atualização do LMD
Execução e parada de varreduras
Tarefa cron
Relatórios de malware
Integração com Apache
Resumo
Capítulo 9 ■ Quebra de senhas com Hashcat
História
Compreensão das senhas
Keyspace
Hashes
Uso da Hashcat
Capacidades da Hashcat
Instalação
Identificação por hash
Escolha do modo de ataque
Download de uma wordlist
Tabelas rainbow
Execução da Hashcat
oclHashcat
Hashcat-utils
Resumo
Capítulo 10 ■ Ataques de injeção de SQL
História
SQLi básica
Mitigação de SQLi em PHP
Exploração de falhas SQL
Lançamento de um ataque
Testando a SQLi de forma legal
Resumo
Sobre o autor

Chris Binnie é um consultor técnico que trabalhou com sistemas Linux online
por quase duas décadas. Durante sua carreira, ele instalou muitos
servidores, tanto na nuvem quanto em máquinas físicas, e em bancos e
órgãos governamentais. Além disso, construiu uma rede de sistemas
autônomos em 2005 e um serviço de vídeo em HD para 77 países sobre
uma plataforma de streaming de mídia que ele concebeu e construiu.
Escreveu para a Linux Magazine e para a ADMIN Magazine por muitos
anos. Fora do trabalho, Chris gosta de realizar atividades ao ar livre, assistir
ao time de futebol Liverpool FC e exaltar as virtudes da infalível navalha de
Occam.

Sobre o editor técnico


Rob Shimonski (www.shimonski.com) é um experiente empresário e ativo
participante do mundo dos negócios. Rob é autor e editor best-seller com
mais de vinte anos de experiência em desenvolvimento, produção e
distribuição de mídia impressa na forma de livros, revistas e periódicos. Até
agora, Rob colaborou na criação de cerca de cem livros, ainda em
circulação. Rob trabalhou para inúmeros clientes, incluindo Wiley
Publishing, Pearson Education, CompTIA, Entrepreneur magazine,
Microsoft, McGraw-Hill Education, Cisco e a National Security Agency.
Rob é também um arquiteto altamente especializado com profunda
experiência técnica em captura e análise de protocolos e na engenharia de
sistemas Windows e Unix.
Prefácio

Poucos discutem que o conhecimento necessário a sistemas e redes


efetivamente seguras precisa ser continuamente atualizado. No entanto,
nem todos os profissionais técnicos querem se tornar profissionais de
segurança plenos; em vez disso, eles preferem se concentrar em outras
áreas, apesar de suas atribuições demandarem muitas das habilidades
requeridas.
Constantemente, o noticiário divulga outro ataque sensacional e quem
trabalha na área fica feliz em constatar que seus clientes não foram o alvo.
À medida que cresce nossa dependência em conectividade eficaz e em
softwares bem desenvolvidos, também cresce o valor da recompensa que
um hacker terá ao comprometer um sistema conectado à internet.
A intenção deste livro é oferecer uma visão bastante ampla a respeito das
ameaças aos sistemas e às redes. Em vez de explorar uma faceta específica
da segurança online, meu objetivo é examinar diversas áreas,
proporcionando ao leitor conhecimento suficiente para que busque, com
maior detalhamento, aquilo que lhe interessa. Cada um dos capítulos deste
livro explora aspectos de segurança que achei interessante em minha
jornada de mais de vinte anos como usuário da internet.
Espero que a diversidade dos temas neste livro seja útil para o leitor na
segurança de seus serviços online, além de proporcionar a oportunidade de
experimentar as ferramentas mais comuns utilizadas pelos hackers. A
intenção é beneficiar a todos, ajudando os profissionais técnicos a ganhar
um melhor entendimento de como os invasores identificam e tentam
explorar as vulnerabilidades de um sistema ou de uma rede. Os elementos
do conhecimento contido neste livro podem ser usados para devastar
serviços online, roubar dados e revelar senhas criptografadas. E de uma
forma muito poderosa...
Introdução

Considere por um momento que mesmo os ataques online amplamente


divulgados podem ser de execução simples. Os passos envolvidos no
lançamento de um ataque em um sistema ou rede podem ser altamente
complexos ou assustadoramente simples. Este pode ser o caso quando um
sistema é deixado sem segurança devido à presença de algum software com
uma falha conhecida.
O modus operandi de um invasor com menos experiência pode ser
simplesmente a automação de varredura de portas de forma aparentemente
interminável, abrindo uma conexão e fechando-a imediatamente, ou a
busca incansável de um banner que revela o número de versão do serviço
existente após a porta. Caso alguma versão case com a versão existente em
sua base de dados de vulnerabilidades, um novo alvo é identificado pelo
invasor. Até esse ponto de um ataque, por ser uma abordagem quase
totalmente automatizada, poderíamos dizer que se trata nada mais nada
menos de computadores atacando computadores.
De forma recíproca, os invasores sofisticados usam uma ampla variedade
de abordagens para perturbar ou ganhar acesso a um sistema ou rede. Eles
não são somente experientes e inteligentes, mas também inovadores,
pacientes e astuciosos. Eles empregam engenharia social, desenvolvem
hardware customizado e praticam verdadeiros truques de magia. Durante
um ataque, adaptam suas tecnologias à medida que o defensor revela suas
cartas, resultando na evolução do ataque, às vezes muito rapidamente. A
maior parte do impacto do ataque é resultado do melhor preparo; o
elevado número de vetores de ataque que podem ser testados durante o
reconhecimento inicial é expressivo.
Tornar os serviços online seguros é um pouco como empurrar água morro
acima, e não fico feliz em dizer que, mesmo em um serviço ou sistema
considerado bem seguro, sempre haverá um meio de invadi-lo ou perturbá-
lo. Mesmo com uma afirmação ousada como essa, tenha em mente que,
mesmo em um sistema ou rede hoje considerado invulnerável, há uma
chance excepcionalmente alta de essa invulnerabilidade ser quebrada no
futuro.
Infelizmente, isso significa que, exceto pela destruição da fonte de
alimentação de um servidor ou dispositivo da rede, o simples fato de ligar
qualquer dispositivo eletrônico efetivamente representa um vetor de ataque
que pode ser explorado por alguém. Esta é uma realidade que profissionais
da área técnica enfrentam há muito tempo. A abordagem resultante da
segurança online deve levar em conta quão valioso é para um invasor
explorar com sucesso seu sistema ou rede e o orçamento disponibilizado
para a segurança da infraestrutura. Você pode também tentar reduzir o
valor do “prêmio” a ser conquistado pelo hacker, por exemplo, separando
em máquinas diferentes os servidores de email dos servidores web. Se um
cluster de máquinas é comprometido, felizmente o outro cluster não é
afetado se ele estiver após um firewall diferente e usando um sistema
operacional alternativo.
Felizmente, para afastar os pesadelos do leitor, o número de invasores
altamente sofisticados é realmente muito pequeno, contra os quais suas
defesas falharão de vez em quando (algumas vezes em questão de
minutos). No entanto, à medida que a internet amadurece, há um número
crescente de invasores talentosos que podem fazer uso do “poderio bélico”
de outros sistemas e serviços comprometidos, causando sérias dores de
cabeça em vítimas inocentes.
Além disso, os motivos que levam um agressor a tentar ataques são
variados e, de certa forma, imprevisíveis. Podem incluir, por exemplo, a
possibilidade de receber uma congratulação vinda da comunidade hacker,
superar sozinho e sem ajuda uma vítima, um exercício de treinamento para
novatos aspirantes ou simplesmente um ganho financeiro. E, considerando
a maioria da população envolvida, não se deve esquecer os que buscam
emoções fáceis.
Se o seu serviço é alvo de certos tipos indesejados de atenção, como uma
aplicação web continuamente salpicada por sondagens à procura de falhas
de segurança, o bom senso orienta que você deve se concentrar
primariamente no desenvolvimento de correções das falhas de segurança.
Da mesma forma, se um serviço de email estiver rodando, é necessário
estar absolutamente seguro de que o software empregado em todos os
servidores de email de seu cluster seja constantemente atualizado e passe
por correções frequentes, realizadas imediatamente após a publicação da
correção. Resolvendo primeiro as fragilidades mais óbvias, é possível
limitar a superfície de ataque apresentada a invasores de média categoria e
reduzir as chances de eles fincarem um pé no restante da infraestrutura.
Com a confiança de que o vetor primário de ataques está suficientemente
seguro, podemos nos concentrar nas falhas de segurança menos óbvias.
Pode ser de grande ajuda dirigir suas preocupações de segurança
formulando algumas perguntas simples. Primeiro, o que você está tentando
proteger? Por exemplo, existem informações sigilosas ou sensíveis bem
escondidas dentro de uma base de dados, tendo à frente múltiplos firewalls
e bastion hosts, ou você está protegendo um serviço online que deve
absolutamente estar disponível ao público o tempo todo, todos os dias do
ano? Essa questão é importante porque afeta a forma como as defesas
devem ser reforçadas e altera potencialmente o modo como as escolhemos.
Para manter seus ativos seguros você pode, por exemplo, gastar um valor
bastante alto com um serviço de limpeza de tráfego na rede que o ajude na
proteção contra ataques de negação de serviço, ou empregar esse mesmo
dinheiro na compra de diversos firewalls físicos com hardware de ponta.
A segunda pergunta é: como você pode conter uma violação de segurança?
Se um servidor ou dispositivo de sua rede for violado, isso significa
automaticamente que outros hosts terão a mesma sorte? Se for este o caso,
certamente sua política de segurança tem sérios problemas que devem ser
tratados.
A terceira é: como você pode fazer a recuperação de uma falha de
segurança? Você deve se preocupar também em relação ao que acontece se
um invasor descobrir como sua redundância funciona e em que estágio
seus serviços de contingência devem ser ativados. É de pouca valia
simplesmente reconstruir um servidor primário ou restaurar às cegas o
serviço da rede se você não sabe a tática utilizada pelo invasor para quebrar
sua segurança. Você é capaz de obter um retorno rápido do serviço usando
um equipamento ou software de um fornecedor alternativo? Se sim, é
possível reduzir a possibilidade de que o mesmo ataque afete novamente
sua segurança, permitindo que você restaure alguns serviços, se não todos,
enquanto investiga como o invasor operou.
Como este livro é organizado
Os capítulos contidos neste livro podem ser lidos em qualquer ordem e
constituem uma coletânea de tópicos de segurança que despertaram o
interesse do autor em sua jornada como usuário da internet durante anos.
Os tópicos variam da teoria dos ataques no passado, atuais e no futuro até
técnicas de mitigação e defesa de diversos tipos de ataques online, sempre
capacitando os leitores para que eles próprios realizem ataques maliciosos
(na esperança de que eles aprendam como se defender desses ataques).
Pela separação dos vários tópicos em capítulos, os temas podem ser
referenciados e consultados novamente no futuro para permitir ao leitor
revisar o conteúdo com maior detalhamento. O conteúdo de cada capítulo
é explicado a seguir:
Capítulo 1: Manto de invisibilidade – Se um invasor não pode enxergar o
servidor e não tem conhecimento de sua existência, significa que não há
qualquer vetor de ataque para explorar. É discutido e demonstrado como
continuar utilizando serviços na operação, porém sem a atenção indesejada
de invasores.
Capítulo 2: Coloque impressão digital em seus arquivos – Existem diversas
formas de garantir a integridade do sistema de arquivos de um servidor
para evitar que os invasores ganhem acesso. Neste capítulo são abordados
tanto um método manual quanto uma ferramenta automatizada que
verifica os rootkits.
Capítulo 3: Netcat no século 21 – Com muitas histórias, a versão do Netcat
usada atualmente, graças à sua multiplicidade de recursos avançados,
acabou se tornando a escolha preferencial dos hackers. Aprenda como é
possível descobrir se essa ferramenta está sendo usada contra seus
servidores e, adicionalmente, como utilizar suas incomparáveis
funcionalidades.
Capítulo 4: Negação de serviço – Somente uma minoria entre os maiores
provedores mundiais de infraestrutura de internet pode fazer frente aos
devastadores efeitos de um ataque distribuído de negação de serviço bem
arquitetado e de alta capacidade. Neste capítulo, o assunto é discutido em
detalhes, incluindo comentários acerca de um caso de perda total de
conectividade à internet em todo um país durante três semanas devido a
um ataque desse tipo.
Capítulo 5: Nping – Saber quais serviços estão rodando em um host é
somente a metade da batalha. O alcance da poderosa ferramenta de
segurança Nmap permite que isso seja verificado em qualquer host e
possibilita também criar pacotes customizados com payloads únicos.
Capítulo 6: Análise de logs – Embora certas sondagens vindas de hackers e
realizadas contra seu servidor possam aparentemente representar pouco
perigo, há poucas dúvidas de que conhecer como elas funcionam ajuda a
aumentar a segurança futura do seu servidor. Abordaremos as diversas
facetas exploradas por um agressor em fase de pesquisa a respeito dos
pontos de vulnerabilidade do seu servidor.
Capítulo 7: O prodigioso NSE do Nmap – Muitos usuários já usaram o
Nmap para simples escaneamento de portas, porém poucos sabem que
essa ferramenta de segurança inclui a capacidade de também explorar
máquinas remotas. Neste capítulo são exploradas algumas das muitas
possibilidades existentes, começando com a multiplicidade de scripts que o
Nmap contém por default.
Capítulo 8: Detecção de malware – Uma ameaça totalmente silenciosa que
afeta sistemas Windows há anos vem na forma de software instalado de
forma ilegítima. Os danos que um malware pode causar a um sistema vão
de irritantes janelas pop-up à invasão plena em operações bancárias. Neste
capítulo aprenderemos como implementar uma solução antimalware
sofisticada e frequentemente atualizada para Linux.
Capítulo 9: Quebra de senhas com Hashcat – Os profissionais da área
técnica ficam alarmados quando descobrem que uma ferramenta de quebra
de senhas não apenas possibilita, como praticamente garante, a quebra de
qualquer senha criptografada. Isso significa que, se o acesso à sua senha
criptografada é obtido ilegitimamente, é somente uma questão de tempo
para que um invasor veja sua senha em texto raso. Este capítulo mostra o
processo, passo a passo.
Capítulo 10: Ataques de injeção de SQL – Conforme uma importante
pesquisa, a injeção de SQL foi apontada como a agressão online mais
predominante. Apesar de esse tipo de ataque remontar aos anos 1990,
ainda hoje um número muito assustador deles atinge com sucesso websites
de empresas e serviços online, normalmente por falhas advindas de má
programação. Este capítulo oferece algumas informações históricas úteis e
instruções passo a passo para identificar e invadir serviços online
vulneráveis.

Quem deve ler este livro


Este livro foi escrito para administradores de nível médio, hackers de
software e outros profissionais de TI. No entanto, ele foi elaborado de tal
forma que qualquer pessoa com um mínimo de curiosidade sobre o
assunto possa discernir rapidamente quais seções são proveitosas para os
interessados em segurança, mesmo sem possuir bons conhecimentos sobre
a linha de comando do Linux. Dessa forma, alguns leitores se dedicarão a
explorar um tema específico de um capítulo com maior detalhamento para
aumentar seus conhecimentos naquele material em particular, enquanto
outras áreas serão de menos interesse às suas necessidades e poderão ser
potencialmente usadas para referência em outra ocasião.
Em outras palavras, não há diferença entre os níveis de experiência
necessários para uma abordagem por capítulo, embora os capítulos com
maior foco em linha de comando possam requerer maior esforço por parte
de um novato.

Resumo
A expectativa é que, pelo aumento da compreensão das ferramentas e da
forma de pensar de um hacker e conhecendo os últimos recursos de
segurança, você não fique sujeito a um fato comum hoje em dia: o da
pessoa que não tem mais controle sobre os seus próprios sistemas ou redes,
enquanto outra pessoa lá fora tem.
CAPÍTULO 1
Manto de invisibilidade

Imagine que se possa deixar um servidor invisível para a internet, porém


tendo ainda acesso à largura de banda superior do seu provedor. Sem fazer
qualquer alteração, seria possível usá-lo de forma segura como um
dispositivo de armazenamento de arquivos, entre muitas outras opções.
Seria também possível ter acesso total à linha de comando, de modo a
inicializar ou interromper ou até mesmo instalar quaisquer serviços que se
deseje usar. Haveria liberdade de opção, seja para rodar esses serviços de
forma breve e logo fechá-los, ou deixá-los rodando de forma visível ao
mundo exterior por um determinado período de tempo.
Isso pode ser conseguido usando uma técnica chamada port knocking. O
servidor pode ser camuflado pelo fechamento de todas as portas de rede
para o mundo externo, tornando-o efetivamente invisível. Uma
determinada porta que se deseje abrir arbitrariamente, usando um “door-
knock”1 pré-arranjado, pode ser a do servidor SSH ou de algum outro
serviço. Este capítulo mostra como criar um servidor invisível e mais
algumas opções.

Contexto
Pela simples camuflagem da existência de um servidor na internet,
podemos no mínimo fazer uma máquina rodar em privado e, no pior caso
e mesmo com sua existência conhecida, é possível reduzir a superfície de
ataque explorada por um invasor pela limitação do tempo em que as portas
estejam abertas ou mesmo parcialmente visíveis.

Sondagem de portas
Antes de começar, é oportuno olhar mais atentamente para as portas de
rede de um servidor, assim conseguimos um panorama de referência.
Quem já usou alguma ferramenta de segurança, como a Nmap, deve estar
familiarizado com a premissa inicialmente confusa de que algumas portas
parecem estar fechadas quando de fato não estão. Ao se deparar com uma
porta aparentemente fechada, o Nmap consegue distinguir se ela está
verdadeiramente fechada ou se há um serviço escondido por trás dela.
O Nmap chama de fechadas as portas que não têm um daemon associado
a ela, porém parecem estar abertas ou, pelo menos, potencialmente
disponíveis. Se o Nmap se referir a portas filtradas, pode significar algum
tipo de firewall prevenindo acesso ao endereço IP do agressor que está
escaneando o sistema em questão. Isso tem a ver parcialmente com pacotes
TCP RST2 e também com a existência de três outros estados informados
pelo Nmap: unfiltered (não filtrado), open|filtered (aberto|filtrado) e
closed|filtered (fechado|filtrado). Mais informações acerca das diferenças
entre esses três estados podem ser obtidas em
https://nmap.org/book/man-port-scanning-basics.html.

Como confundir um scanner de porta


Agora que sabemos como as portas podem se apresentar aos scanners de
portas, vamos dar uma olhada em como ofuscar a resposta retornada,
objetivando confundir as técnicas sofisticadas de escaneamento. A
ferramenta mais óbvia a ser escolhida, graças ao seu poderoso conjunto de
funcionalidades, é o firewall embutido no próprio kernel do Linux, o
Netfilter, mais conhecido como iptables.
A ideia é simples. No caso de pacotes TCP, é desejável ter o controle sobre
como uma porta responde a sondagens, e para isso usamos o iptables com
regras do tipo REJECT. No caso de outros protocolos, pode ser desejado
somente aplicar DROP aos pacotes. Desta forma, o Nmap do agressor
descreve essas portas TCP como fechadas e não como filtradas. Com base
na maioria das opiniões coletadas em fóruns na internet (e este parece ser
um argumento controverso, que muda o tempo todo), uma informação de
porta fechada é a melhor resposta que se pode enviar ao Nmap de quem
estiver escaneando nossos sistemas. Fazendo isso, não revelamos
abertamente ao possível invasor o bloqueio, por um firewall, de qualquer
porta, nem que a porta está simplesmente aberta por um daemon rodando
por trás dela.
Para explicar um pouco mais, sob circunstâncias normais uma porta
inatingível emite geralmente uma resposta ICMP de Porta Inacessível
(ICMP Port Unreachable). Porém, não é desejável que esses erros sejam
gerados porque isso poderia indicar a presença de um serviço que estava
rodando nessa porta e, por algum motivo, está inacessível. Em vez disso, é
preferível gerar uma resposta REJECT, aplicada da seguinte forma: --
reject-with tcp-reset. Com isso, a resposta que o Nmap recebe mostra
a porta como não utilizada e fechada (portanto sem um serviço por trás) e
também como não filtrada (portanto não revelando a existência do
firewall).
Basta anexar o seguinte fragmento ao final de cada um dos comandos
iptables:
-j REJECT—reject-with tcp-reset
Usando esta técnica, podemos ficar seguros de que nenhuma informação
desnecessária sobre o sistema está sendo revelada.
Observe que, no exemplo de port knocking que veremos a seguir, aquela
opção do iptables não será usada, pois o servidor físico que roda o SSH não
vai oferecer nenhum outro serviço (portanto não há nada para rejeitar). No
entanto, essas informações básicas ajudarão a entender a forma de
abordagem de um invasor nas portas da máquina e como podemos aplicar
uma opção --reject-with tcp-reset a outros serviços.
Há algum debate sobre o uso de regras DROP versus REJECT no iptables.
Caso haja interesse, informações detalhadas sobre esse tema podem ser
encontradas em www.chiark.greenend.org.uk/~peterb/network/drop-
vs-reject.

Instalação do knockd
Agora que já conhecemos o básico, veremos como instalar um port
knocker no servidor. No decorrer da explicação, devemos considerar quais
serviços desejamos rodar de forma escondida da internet. Pode ser que
precisemos rodar um servidor web ou um servidor de emails em uma porta
não usual por um período de poucas horas, por exemplo.

Pacotes
O serviço que oferece a funcionalidade de port knock chama-se knockd.
Esse pacote é instalado de diferentes formas, dependendo do sistema.
Em derivados de Debian o pacote é instalado da seguinte maneira:
# apt-get install knockd
Em derivados Red Hat a instalação é:
# yum install knockd
Um arquivo de configuração principal controla a maioria das configurações
necessárias para o knockd. Em um servidor Debian Jessie, esse arquivo
reside em /etc/knockd.conf. A Listagem 1.1 mostra meu arquivo config
principal para vermos como o knockd funciona.
Listagem 1.1 – Arquivo de configuração principal. As sequências de portas e
(principalmente) -I INPUT foram alteradas em relação aos defaults.
[options]
UseSyslog
[openSSH]
sequence = 6,1450,8156,22045,23501,24691
seq_timeout = 5
command = /sbin/iptables -I INPUT -s %IP% -p tcp—dport 22 -j ACCEPT
tcpflags = syn
[closeSSH]
sequence = 3011,6145,7298
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp—dport 22 -j ACCEPT
tcpflags = syn

Alteração dos ajustes default


A Listagem 1.1 mostra, na parte superior, uma seção para ajustar as opções
do knockd. As duas outras seções são as ações a serem executadas quando
o knockd abre a porta para o serviço SSH ou quando fecha o acesso a essa
porta. Ambas as seções incluem também a sequência default de port
knocking para a execução dessas ações com a opção sequence. Após a
instalação do knockd, alterei imediatamente estas portas em relação ao
default para evitar a redução de eficácia na segurança do meu servidor. Os
defaults são as portas 7000, 8000 e 9000 para abrir o acesso SSH e as
portas 9000, 8000 e 7000 para fechar o acesso. Como podemos ver,
acrescentei mais portas para abrir o acesso. Assim, reduzimos a
possibilidade de que alguém se depare arbitrariamente com essa
combinação por meio de um scanner de portas.
Após a alteração de qualquer ajuste, basta reiniciar o knockd em sistemas
operacionais baseados em systemd da seguinte forma:
# systemctl restart knockd.service
Após a instalação do knockd, caso deseje mais informações básicas sobre o
pacote, o Debian Jessie fornece um pequeno arquivo README que pode
ser encontrado em /usr/share/doc/knockd/README.
Entre outras coisas, esse arquivo README útil discute como o knockd
funciona. Ele usa uma biblioteca denominada libpcap, que é também
empregada por diversos outros pacotes como o tcpdump, ngrep e o iftop
(que captura pacotes para inspeção). Graças à sua concepção inteligente, o
knockd não precisa sequer se conectar às portas, realizando uma escuta
sigilosa para a monitoração do tráfego bruto.

Alteração dos locais do sistema de arquivos


Eventos do tipo conexões, desconexões ou erros são registrados
diretamente no syslog do seu sistema, que podem ser gravados no arquivo
/var/log/messages ou no arquivo /var/log/syslog. Para que essas
informações não sejam soterradas no meio de outras atividades do system
log, pois é um aborrecimento analisar um arquivo com registros
complicados, podemos criar um arquivo de registros personalizado. Prefiro
fazer dessa forma, o que torna a depuração mais clara, e posso usar uma
ferramenta automatizada ou um shell script que eu mesmo escrevi para me
enviar emails diariamente, o que me permite monitorar eventos suspeitos.
Por manter todos os registros do knockd em um único lugar, fica mais fácil
analisar as informações usando scripts ou outras ferramentas.
[options]
LogFile = /var/log/portknocking.log
A alteração do local dos arquivos de log é uma solução comum, porém
podemos também alterar o local em que o arquivo Process ID é gravado
quando o serviço knockd é iniciado. O local pode ser alterado na seção
[options] do arquivo de configuração:
[options]
PidFile = /var/tmp/run/file
Algumas opções de configuração
Agora que já conhecemos melhor o arquivo de configuração principal,
podemos ajustá-lo para atender às necessidades. Entre diversas outras
tarefas, devemos considerar como as temporizações de certas opções
influem na configuração do servidor.

Inicialização do serviço
Não se assuste ao ver uma mensagem de erro dizendo que o knockd está
desabilitado. Isto é uma precaução: até que se tenha concluído sua
configuração, o knockd não introduzirá alterações indesejadas no iptables.
No Debian Jessie a mensagem de erro sugere definir, no arquivo
/etc/default/knockd, o valor 1 para o parâmetro:
START_KNOCKD = 1
Evidentemente, isso somente deve ser feito após conferir as configurações
no mínimo duas vezes ou assegurando-se que o acesso ao serviço desejado
está funcionando conforme esperado sem o knockd.

Alteração da interface de rede default


Estando a sequência de portas preferida já configurada, talvez desejemos
refinar outros parâmetros. O arquivo de configuração
(/etc/default/knockd) oferece a oportunidade de alterar os valores da
variável KNOCKD_OPTS. No arquivo, a variável está comentada, ou seja,
desabilitada, e mostra um exemplo de como podemos definir a interface de
rede na qual aquele knockd está “escutando”:
KNOCKD_OPTS = "-i eth1"
Essas opções serão acrescentadas ao serviço knockd, que deve ser
reiniciado para efetivar as alterações, conforme mostrado a seguir (em
máquinas systemd):
# systemctl restart knockd

Tipos de pacotes e temporizações


O arquivo /etc/knockd.conf permite a alteração de algumas
configurações para fazer um ajuste fino na forma como os clientes podem
se conectar. Voltando à Listagem 1.1, na seção [openSSH], mais opções
podem ser acrescentadas, conforme mostrado a seguir:
[openSSH]
tcpflags = syn
seq_timeout = 10
cmd_timeout = 15
A opção tcpflags significa que podemos esperar um tipo específico de
pacote TCP sendo enviado ao knockd para que seja aceito. Trata-se de um
“SYN” TCP neste caso. As flags TCP que podem ser usadas são fin, syn,
rst, psh, ack e urg. O knockd simplesmente ignora qualquer pacote
recebido que não traga o tipo especificado de pacote TCP. Devemos estar
cientes de que, geralmente, o knockd não trabalha desta forma.
Normalmente, um pacote incorreto pode interromper o trabalho de uma
sequência completa de knocking, e neste caso o cliente deve reiniciar a
conexão. A separação de múltiplos tipos de pacotes TCP deve ser feita
usando vírgulas; nas versões mais recentes do knockd (desde a 0.5
conforme o changelog) a representação é feita com pontos de exclamação
para negar o tipo de pacote, como, por exemplo, !ack.
Observe que seq_timeout está presente na Listagem 1.1 por default. No
entanto, devido ao acréscimo do número de portas da sequência de
knocking, o valor de seq_timeout foi aumentado de 5 para 10. Isso é
necessário porque, em uma conexão lenta, como a de um smartphone, o
tempo máximo entre cada “knock” pode se esgotar (timeout).
A opção final no exemplo é cmd_timeout, que ajusta o tempo máximo em
que a porta desejada deve ficar aberta depois que o knockd recebeu um
knock com sucesso. A sequência de eventos é mostrada a seguir. Em
primeiro lugar, uma vez que o port knocking foi confirmado como válido,
o knockd roda start_command (Releia a Listagem 1.1 para refrescar a
memória). Se este ajuste estiver presente, e após a execução da opção
start_command, resta somente esperar pelo tempo especificado em
cmd_timeout antes de rodar a ação stop_command.
Essa é a forma preferencial para abrir o servidor SSH para acesso, com seu
fechamento sendo feito logo na sequência, assim que a conexão estiver
estabelecida. O prosseguimento da sessão deve ocorrer sem maiores
problemas, porém qualquer nova conexão deve efetuar outra sequência de
port knocking para que se estabeleça. Essa ação deve ser entendida como o
ato de fechar imediatamente uma porta assim que você entrar. O servidor
se tornará invisível outra vez, e somente o tráfego das conexões já
estabelecidas será visível.

Teste da instalação
Como estamos lidando com a segurança de um servidor, alguns testes
devem ser executados para garantir o funcionamento do knockd conforme
esperado. O ideal é ter acesso a outra máquina cliente, via internet, para
rodar alguns testes a partir dela. Para ter certeza de que o knockd abre e
fecha as portas da forma correta, gosto de fazer o teste me conectando
várias vezes ao serviço, cada vez a partir de um endereço IP público
completamente diferente. Se o acesso a uma conexão com um endereço IP
público diferente do anterior não for possível, a conexão à internet do
cliente que está fazendo o teste contra o knockd deve ser derrubada
periodicamente, fazendo com que um novo IP para teste seja alocado pelo
provedor de serviços. Alguns provedores de banda larga e de internet
móvel fazem isso após uma reinicialização – mas às vezes não; consulte seu
provedor.

Clientes de port knocking


Podem ser usados clientes diferentes para criar uma sequência de knocking
e, com ela, iniciar uma conexão de abertura da porta SSH. Podem ser
usadas até mesmo ferramentas como Nmap, netcat ou Telnet para “bater”
manualmente na sequência de portas que dispara o serviço. A
documentação também menciona que os pacotes hping, sendip e packit
podem ser usados se estiverem disponíveis. Vamos dar uma olhada em um
exemplo do comando knock incluído no pacote knockd.
A sintaxe do comando knock é bem simples:
# knock [options] <host> <port[:proto]> <port[:proto]> <port[:proto]>
Na Listagem 1.1, configuramos uma sequência de portas para abrir uma
seção do openSSH, portanto o comando knock fica assim:
# knock 11.11.11.11 6:tcp 1450:tcp 8156:tcp 22045:tcp 23501:tcp 24691:tcp
O host-alvo tem o endereço IP 11.11.11.11 neste exemplo. Caso deseje,
uma combinação de portas UDP e TCP pode ser colocada na Listagem 1.1;
nesse caso, a sequência de knocking no lado cliente ficaria assim:
# knock 11.11.11.11 6:tcp 1450:udp 8156:udp 22045:tcp 23501:udp 24691:tcp
Um bom atalho é, caso deseje usar somente portas UDP, simplesmente
acrescentar -u no início do comando, em vez de especificá-lo de forma
explícita. Um comando para portas UDP pode rodar de uma forma
parecida com esta:
# knock -u 11 22 33 44 55
Voltemos ao arquivo de configuração do servidor para ver como TCP e
UDP podem ser intercambiados dentro da sequência de knocking válida.
Para misturar os protocolos, basta alterar a linha sequence na seção
openSSH conforme explicado a seguir:
[openSSH]
sequence = 6:tcp 1450:udp 8156:udp 22045:tcp 23501:udp 24691:tcp

Como tornar o servidor invisível


Quando estiver confiante de que a instalação está funcionando da forma
desejada, o servidor deve ser bloqueado para escondê-lo de invasores. Um
invasor pode estar ciente do endereço IP do servidor e, de alguma forma,
conseguir enxergar o tráfego enviado e recebido por meio dele (por
exemplo, o agressor pode trabalhar para o provedor de serviços de
hospedagem). Por isso, o servidor deve estar invisível a usuários da
internet. Se estiver à vista de todos, qualquer um pode fazer experiências
com o seu firewall – incluindo eu. No entanto, para obter o status de porta
fechada no Nmap, adoto a abordagem a seguir.

Teste do iptables
Como disse antes, uso o iptables, que é, na opinião de quase todo mundo,
bastante confiável. O ideal é ter acesso físico ao servidor antes de bloqueá-
lo, pois se o estivermos operando remotamente ficaríamos trancados do
lado de fora caso criemos uma regra errada. Na eventualidade de um
problema, devemos contar com um acesso local, que independa de
conexão com a internet, como o console de uma máquina virtual, uma
interface de rede secundária na qual se possa fazer o login ou um modem
discado (dial-up) acoplado à máquina. É preciso estar ciente de que, salvo
por um teste prévio da configuração em uma máquina de desenvolvimento,
há uma chance muito grande de cometer um erro e arranjar problemas.
Mesmo tendo usado o port knocking antes, ocasionalmente ainda sou pego
de surpresa e fico sem acesso a um servidor.
Com esse alerta em mente, vamos começar olhando os comandos do
iptables. É preciso tomar cuidado ao integrar estas regras com quaisquer
outras regras anteriores. É aconselhável somente sobrescrever as regras
existentes após a realização de um backup. Em primeiro lugar, é preciso
assegurar que o servidor pode conversar com ele próprio pela interface
localhost:
# iptables -A INPUT -s 127.0.0.0/8 -j ACCEPT
É preciso agora estar seguro de que quaisquer conexões existentes são
reconhecidas e podem emitir respostas:
# iptables -A INPUT -m conntrack—ctstate ESTABLISHED,RELATED -j ACCEPT
O conntrack está sendo usado para rastrear as conexões existentes. Uma
vez inicializadas com sucesso, as conexões podem continuar a operar.
Agora, assumindo que somente a porta TCP 22 do servidor SSH vai ser
aberta e que o servidor não oferecerá nenhum outro serviço, podemos
prosseguir. Lembre-se de que, na Listagem 1.1, usamos o seguinte
comando para abrir a porta TCP 22:
command = /sbin/iptables -I INPUT -s %IP% -p tcp—dport 22 -j ACCEPT
Preste atenção a essa linha. Se usarmos a ação “append” do iptables, ou
seja, -A INPUT no comando, seremos trancados para fora, pois a regra será
inserida no final da lista de regras. Um -I de “insert” deve ser digitado para
que a regra seja introduzida na primeira posição da lista e tenha
precedência sobre as demais.
Você deve estar se perguntando o que significa a variável %IP%. O port
knocking tem inteligência suficiente para substituir a variável %IP% pelo
endereço IP da conexão no campo -s.
Agora chegamos ao ponto em que deve ser tomado muito cuidado. Não há
retorno caso as coisas não funcionem como esperado, portanto neste caso
as regras devem ter sido testadas em uma máquina virtual ou o servidor
deve poder ser acessado por caminhos alternativos. O bloqueio de todo o
tráfego entrante no servidor pode ser feito da seguinte maneira:
# iptables -A INPUT -j DROP
O comando a seguir lista todas as regras do iptables. Em condições
normais, não veremos qualquer menção à porta TCP 22 e à sua porta SSH:
# iptables -nvL
No entanto, quando fazemos login via SSH e usando o port knocking, a
regra liberando a porta 22 será vista no iptables (o tempo em que a regra
estará ativa depende do valor usado em cmd_timeout; um valor muito
baixo fará com que a regra apareça muito brevemente na lista) se o login
tiver sido feito com sucesso.
Se houver problemas a esta altura, continue lendo: veremos mais adiante
algumas formas de testar a configuração e aumentar os níveis de logging.
Caso contrário, temos um servidor cujas portas são todas informadas como
não existentes, tornando assim o servidor invisível, conforme mostrado na
Figura 1.1.

Figura 1.1 – O Nmap parece considerar que não existe máquina naquele
endereço IP.

Gravando as regras do iptables


As regras do iptables só existem na memória; não estão gravadas em
nenhum arquivo ainda. Para assegurar que sobrevivam a uma
reinicialização, um pacote denominado iptables-persistent deve ser
instalado em derivados do Debian:
# apt-get install iptables-persistent
As regras podem então ser salvas com o comando:
# /etc/init.d/iptables-persistent save
A configuração salva pode ser recarregada na memória rodando este
comando:
# /etc/init.d/iptables-persistent reload
Em derivados do Red Hat (em máquinas que ainda não têm systemd), este
comando pode ser usado:
# /sbin/service iptables save
E para restaurar as regras, o comando é:
# /sbin/service iptables reload
Para que o exposto anteriormente funcione em derivados do Red Hat que
já tenham systemd, é preciso instalar este pacote primeiro:
# yum install iptables-services

Outras considerações
Há alguns aspectos relacionados ao port knocking que podem ser úteis.
Vamos dar uma olhada neles agora.

Cliente para smartphone


Em meu smartphone Android, meu app SSH preferido é o JuiceSSH
(https://juicessh.com). Ele tem um plugin de terceiros que permite
configurar uma sequência de knocking como parte do handshake SSH. Isso
significa que não há desculpa para não empregar o port knocking, mesmo
se estiver na rua e sem um laptop.

Pesquisa de problemas
O comando tail -f logfile.log permite examinar arquivo de log do
port knocking em tempo real. Com ele, podemos observar diversos
estágios do processo sendo escritos no log, o que inclui o fato de uma porta
válida ter sido acessada e, muito importante, se as portas configuradas
foram “batidas” na sequência correta ou não.
Podemos aumentar os níveis de logging produzidos pelo knockd ativando a
opção de depuração. Abra o arquivo /etc/init.d/knockd (com cuidado
para não modificar nada) e procure pela linha OPTIONS. É possível
acrescentar um caractere D maiúsculo (Shift+d) em quaisquer valores
existentes nesta linha, conforme mostrado a seguir:
OPTIONS = "-d -D"
O logging adicional deve ser desativado depois da realização do
diagnóstico e da solução do problema, para evitar perda desnecessária de
espaço em disco. O -d significa que o knockd roda como um daemon,
caso alguém esteja se perguntando. Ele deve ser deixado como está para
operação normal.
Retornemos ao cliente por um momento. O nível de detalhes na saída
também pode ser aumentado, algo que o cliente “knock” gera pelo
acréscimo de uma opção -v. Em conjunto com a opção de depuração no
servidor, isso deve fornecer informação proveitosa dos dois lados da
conexão.

Considerações de segurança
Quando as informações associadas a um servidor são divulgadas, devemos
ter em mente que é necessário solicitar ao provedor de conexão à internet
para não publicar diretamente seu endereço IP público, seja por DNS
direto, seja por DNS reverso. Seu endereço IP deve aparecer como não
usado ou não alocado, ficando dessa forma invisível.
Mesmo em serviços públicos como HTTP, as versões dos daemons sendo
utilizadas devem ser ofuscadas. A forma corriqueira de fazer isso no
servidor mais popular da web, o Apache, é alterar o ServerTokens para
“Prod” e configurar ServerSignature para “Off”. Estas são alterações de
configuração altamente avançadas, porém podem significar que um ataque
automatizado ignore seu servidor quando um novo ataque de dia zero
(zero-day exploit) é descoberto, pois o número de versão do seu Apache
não estava no banco de dados do agressor.
Outro aspecto a ser considerado é discutido na documentação do knockd.
Ela menciona que se você usar as opções -l ou --lookup para resolver
nomes de máquina em suas entradas de log, pode estar incorrendo em um
risco de segurança. Se isso for feito, há uma chance de vazamento de
informações para um invasor, que pode ter condições de determinar a
primeira porta de uma sequência se conseguir capturar o tráfego DNS do
servidor.

Sequências efêmeras
Que tal usar uma abordagem diferente para as sequências de knocking?
Também é possível usar o port knocking com uma lista predefinida de
sequências de porta que expiram depois que foram usadas apenas uma vez.
Consultando novamente a Listagem 1.1 e o arquivo de configuração
principal, podemos acrescentar, caso assim desejemos, a opção a seguir às
seções open e close para habilitar as sequências de evento único:
[openSSH]
One_Time_Sequences = /usr/local/etc/portknocking_codes
Se a linha sequence for removida da Listagem 1.1 e substituída por esse
código, o knockd então seguirá as sequências conforme o arquivo
especificado no caminho.
O knockd lida com as sequências de tempo único de uma forma não usual.
Ele lê a próxima sequência disponível do arquivo e comenta aquela linha,
seguida de uma conexão realizada com sucesso com um knock válido. Ele
simplesmente acrescenta um caractere # ou hash ao início da linha que
tiver a sequência presente. A próxima conexão aciona a mesma sequência.
A documentação estabelece que deve ser deixado um espaço no início de
cada linha. Caso contrário, quando o caractere # for acrescentado ao início
da linha, pode-se pensar que ele foi sobrescrito de forma não intencional,
significando então a ocorrência de um bloqueio.
No arquivo de sequências, podemos acrescentar uma sequência por linha.
Esse arquivo segue o mesmo formato que na opção sequences dentro do
arquivo de configuração principal.
A documentação também ressalta que podem ser inseridos comentários
colocando na frente deles o caractere #, porém isso pode acarretar
problemas (como ficar com o acesso ao servidor bloqueado) se o arquivo
de sequências for editado enquanto o knockd ainda estiver rodando.
Uma vez compreendidos os recursos básicos do knockd, é uma excelente
hora de experimentá-lo. Durante o teste, podem ser digitados números de
telefone ou alguma outra sequência de números que possa ser memorizada
depois, de modo a garantir que não estamos lidando continuamente com
uma lista insegura. Por exemplo, uma rotatividade entre cinco números
telefônicos pode ser considerada, dividindo-os entre números de porta
válidos.

Resumo
Além de tornar um servidor invisível, expliquei como esse servidor aparece
na internet antes do lançamento de um ataque. Para que um servidor seja
totalmente ofuscado com o uso do port knocking, o uso de informações
públicas, como entradas de DNS reverso, deve ser pensado com muito
cuidado, o que pode levar à desistência de um endereço IP como se ele
estivesse em uso. O uso de NAT para esconder um servidor e fazer a troca
dinâmica periódica do endereço IP pode também ser considerado,
deixando que somente administradores conheçam qual endereço IP está
em uso em um determinado momento por meio de um nome de usuário
secreto, publicado de forma sigilosa em DNS em um Nome de Domínio
não usual.
Há muitas outras maneiras de proteger um servidor. De qualquer modo,
espero ter dado informações suficientes para fazer o leitor considerar que
tipo de informação é vazada publicamente e que possa ser potencialmente
usada em ataques futuros, bem como para esconder um servidor caso seja
necessário fazê-lo.

1 N. do T.: Não traduzimos door-knock por ser considerado jargão técnico, mas, resumidamente,
seria como aquelas senhas que combinamos com os amigos ou familiares para avisar quem está
batendo à porta ou tocando a campainha. Por exemplo, se ouvirmos um toque curto e três longos
na campainha, já sabemos que é o primo trazendo a pizza.
2 N. do T.: O autor considera que o leitor tem uma boa base teórica a respeito dos mecanismos de
roteamento IP, conexão TCP, especialmente o processo de sincronismo inicial (three-way
handshake), e comunicação UDP. Sugerimos ao leitor fazer uma revisão prévia desses conceitos
para melhor entendimento deste capítulo.
CAPÍTULO 2
Coloque impressão digital em seus arquivos

Há diversas boas razões para ficar de olho na segurança de um servidor.


Poucos administradores de sistemas possuem o conhecimento necessário
para manter sua infraestrutura segura; isso demanda entusiasmo e esforços.
Se o leitor for como eu, sabe que para chegar a esse nível teve de passar por
muitos altos e baixos. Na virada do milênio, por exemplo, tinha sob meus
cuidados um servidor afetado por um bug terrível do PHP, e em outra
ocasião enfrentei e repeli dois ataques DDoS relativamente significativos.
Este capítulo aborda outro vetor de ataques, os rootkits, e uma fantástica
peça de software denominada Rootkit Hunter (talvez seja mais conhecido
como rkhunter). Porém, iniciaremos explorando como importantes
arquivos em um sistema de arquivos podem ser monitorados – por
exemplo, seus executáveis.

Integridade do sistema de arquivos


Há muitos anos eu usava o Tripwire
(http://sourceforge.net/projects/tripwire). Hoje ele é conhecido
como Open Source Tripwire, devido à disponibilidade de outros produtos.
O Tripwire rodava de forma periódica (durante a noite, pelo cron) e usava
dispersão criptográfica (mais conhecida como hashing) para a monitoração
de qualquer alteração nos arquivos de um sistema.
Em sua primeira execução, o Tripwire gera e grava os hashes de todos os
arquivos visíveis do sistema. A cada execução subsequente, o Tripwire
podia alertar o administrador caso qualquer um dos hashes apresentasse
diferenças em relação ao que havia sido inicialmente gravado. Se um
arquivo sofresse qualquer tipo de alteração, o hash seria alterado. Era uma
abordagem inteligente e, apesar dos recursos I/O serem intensivamente
usados em hardware mais antigo, inspirou a criação de sucessores
igualmente renomados. Um exemplo é o popular AIDE (Advanced
Intrusion Detection Environment), descrito em
http://aide.sourceforge.net como um “verificador de integridade de
arquivos e diretórios”. Com toda convicção, recomendo uma experiência
com o AIDE ou o Tripwire em uma máquina virtual de desenvolvimento,
caso o leitor tenha essa chance. Porém, é bom frisar que, se houver
negligência com a configuração inicial, haverá um bombardeio de falso-
positivos.
Este tipo de segurança aparece frequentemente sob o guarda-chuva de
sistemas de detecção de intrusão baseados em hosts (host-based intrusion
detection systems – HIDS), e supostamente foi uma das primeiras
abordagens de segurança via software, devido ao fato de, à época, os
mainframes serem sujeitos a poucas interações externas de risco em
operação sobre redes.
Caso não deseje rodar testes noturnos em sistemas de arquivos ou não
esteja em posição de receber relatórios diários do sistema, não há
problema. A opção pode ser a adoção de uma abordagem mais antiga, em
que o sistema de arquivos é escaneado somente uma vez, após a
implantação do servidor, com vistas a coletar informações sobre quais
arquivos estão instalados. Explicarei mais adiante porque isso é útil.
O leitor pode ficar surpreso em saber que uma ferramenta muitas vezes
usada para outra finalidade pode ser facilmente empregada como assistente
de segurança.
Vejamos, por exemplo, o comando md5sum. No passado, ao fazer o
download de arquivos Unix, provavelmente era oferecida a opção de
checar a integridade do download potencial pela verificação das somas
MD5 desses arquivos. Por exemplo, as somas MD5 são geralmente
encontradas no site em que a imagem de arquivo ISO de instalação é
obtida.
Como pode ser visto na Figura 2.1, ao baixar Debian Jessie do espelho
holandês:
http://ftp.nl.debian.org/debian/dists/jessie/main/installer-
amd64/current/images/, deve ser encontrado o seguinte.
Figura 2.1 – O Debian Jessie pode ser baixado do site e a soma MD5 também
pode ser verificada por segurança.
Ao abrir o arquivo MD5SUMS, o conteúdo da Figura 2.1 é mostrado,
contendo os hashes para cada arquivo:
Listagem 2.1 – Uma amostra abreviada do arquivo MD5SUMS
bf0228f479571bfa8758ac9afa1a067f ./hd-media/boot.img.gz
ee6afac0f4b10764483cf8845cacdb1d ./hd-media/gtk/initrd.gz
19fdf4efebb5c5144941b1826d1b3171 ./hd-media/gtk/vmlinuz
4dc2f49e4bb4fe7aee83553c2c77c9da ./hd-media/initrd.gz
19fdf4efebb5c5144941b1826d1b3171 ./hd-media/vmlinuz
2750aec5f0d8d0655839dc81cc3e379f ./netboot/debian-
installer/amd64/boot-screens/adtxt.cfg
aca8674ab5a2176b51d36fa0286a40bb ./netboot/debian-
installer/amd64/boot-screens/exithelp.cfg
2e88361d47a14ead576ea1b13460e101 ./netboot/debian-
installer/amd64/boot-screens/f1.txt
e62b25d4b5c3d05f0c44af3bda503646 ./netboot/debian-
installer/amd64/boot-screens/f10.txt
Na coluna esquerda da Listagem 2.1 pode ser vista a soma MD5 de cada
arquivo, com o nome de arquivo relevante à direita. A finalidade disso é
evitar a colocação sorrateira de outro arquivo no lugar de um legítimo, o
que poderia infectar o sistema operacional, cuja instalação estaria limpa até
este ponto.
O MD5sums primeiro calcula e depois faz a verificação sobre os digests
MD5. Alguém poderia pensar (de modo relativamente sofisticado) que pela
verificação das somas MD5 se estaria efetivamente criando uma impressão
digital de cada arquivo, com a possibilidade de fazer consultas posteriores.
O leitor pode tentar usar o MD5sums (o comando MD5sum é incluído
dentro do pacote coreutils em minha máquina e deve estar facilmente
disponível em quase todas as distribuições). Pode ser tentado um comando
como este:
# md5sum /home/chrisbinnie/debbie-and-ian.pdf
A resposta recebida deve ser algo como:
3f19f37d00f838c8ad16775293e73e76 debbie-and-ian.pdf
Retornemos agora aos arquivos relacionados próximos à distribuição
Linux. O arquivo MD5SUMS deve ser baixado e gravado na mesma pasta do
arquivo principal ISO (ISO é colocado após o sistema de arquivos ISO
9660, caso o leitor esteja se perguntando). Fazendo isso, poupamos o
trabalho de verificar manualmente cada arquivo na mídia de instalação
sendo usada. O motivo disso é que esses arquivos incluem todas as somas
MD5 dos arquivos da pasta. Com as somas MD5 já disponíveis para todos
os arquivos, pode ser feita a verificação de validade deles com o seguinte
comando (-c também significa --check):
# md5sum -c MD5SUMS
A Listagem 2.2 mostra os resultados da execução da opção -c. Podemos
até dizer que as somas MD5 são binárias: o resultado é OK ou não OK.
Listagem 2.2 – Amostra da saída resultante da verificação do meu arquivo MD5SUMS
usando a opção -c
compare.png: OK
config2.png: OK
config3.png: OK
config4.png: OK
works_1.tar: OK
package_inst.jpg: OK
No que se deve prestar atenção caso um arquivo não case com sua soma
MD5 original? A Listagem 2.3 mostra um espalhafatoso aviso FAILED
(falha) e o problema encontrado sendo informado ao final dos resultados.
Listagem 2.3 – Um MD5sum que NÃO casa e se apresenta como “FAILED”
test.sh: FAILED
bootstrap_AWS.pp: OK
hiatus.png: OK
md5sum: WARNING: 1 of 111 computed checksums did NOT match
Nem é preciso dizer que, caso essas verificações não sejam realizadas
quando instalamos um sistema operacional a partir de um ISO que
baixamos da internet ou de um DVD, a integridade dos arquivos será uma
grande incógnita e, portanto, um risco à integridade do sistema recém-
instalado.
Agora que já relembramos como pode ser feita a verificação de possíveis
adulterações nos arquivos que acabamos de baixar, veremos como usar o
poder dos hashes criptográficos para saber se um sistema instalado foi
comprometido.

Sistema de arquivos como um todo


Uma vez satisfeito com a instalação do sistema operacional e tendo
realizado o devido ajuste fino pós-instalação, é hora de fazer a gravação das
somas MD5 dos arquivos-chave do sistema. Isso deve ser feito para que
tenhamos um registro confiável do estado “sadio” do sistema e uma base
de comparação para quando ocorrer um comprometimento suspeito.
Obviamente, não é muito fácil fazer isso com o comando md5sum sem
desenvolver um shell script. O shell script ajuda porque é difícil obter as
árvores de diretórios completas dos arquivos trabalhando interativamente
com o comando md5sum.
Contudo, não tema: alguém muito inteligente resolveu esse problema com
programa pequeno, mas muito eficiente, chamado md5deep
(http://md5deep.sourceforge.net). De acordo com o site, além da
funcionalidade esperada do MD5sum, há ainda outras.
É possível:
• Ignorar determinados arquivos (o que é muito útil quando se deseja
ignorar arquivos temporários e outros tipos).
• Ao fazer a inspeção de um expressivo número de arquivos
(recomendável em uma instalação recente de um sistema operacional), o
md5deep oferece uma funcionalidade muito útil denominada ETD
(Estimated Time of Delivery – Tempo Estimado de Entrega) – em outras
palavras, quanto tempo é necessário para que o comando seja concluído.
• O md5deep pode rodar em modo recursivo para, sem esforço,
identificar os subdiretórios escondidos dentro do sistema de arquivos.
Feito de forma manual, isso seria muito trabalhoso (e mesmo impossível
de fazer de forma precisa).
• Levando em conta a compatibilidade, diferentes tipos de hashes podem
ser importados (por exemplo, os hashes da empresa EnCase, da
National Software Reference Library, do programa ILook Investigator e
do HashKeeper).
Certamente, o leitor concordará que é exatamente o que está procurando.
Tendo completado a montagem de uma nova máquina, basta instalar o
md5deep e fazê-lo rodar em todo o sistema de arquivos (ou pelo menos em
partes dele). Uma ressalva importante é manter a lista hash resultante em
outro local, não no servidor. Isso por razões óbvias: se o servidor for
invadido, fica muito fácil ao atacante sobrescrever a lista MD5sum,
substituindo-a por uma nova lista MD5sums ilegítima e com isso ludibriar
o administrador.
Caso, por alguma razão, não consiga acesso ao md5deep (por exemplo, em
trabalhos em um ambiente fechado), pode ser interessante rodar o
comando md5sum em pastas contendo binários-chave, como as mostradas
na (não exaustiva) lista a seguir:
/bin, /sbin, /usr/bin, /usr/sbin, /etc

Rootkits
Vamos agora para uma abordagem diferente de impressão digital de
arquivos.
Se o interesse for proteger os arquivos contra rootkits (contendo um código
que permita a algum estranho acessar ou controlar as máquinas), deve ser
considerada também uma excelente ferramenta denominada Rootkit
Hunter (também chamada de rkhunter;
http://rkhunter.sourceforge.net).
Por ocasião da instalação, o manual do Rootkit Hunter (caçador de
rootkits) alerta que provavelmente não será possível executá-lo se houver
uma tentativa de rodar o software em um sistema supostamente
comprometido e que não tenha os comandos a seguir (comuns na maioria
dos sistemas): cat, sed, head ou tail.
Ressalto esse fato por uma boa razão: esses comandos podem ser
corrompidos ou perdidos em uma máquina invadida. Se o Rootkit Hunter
foi instalado para caçar arquivos infectados e houver a constatação da
invasão do sistema, é realmente necessário recompor a máquina. Não
assuma que os reparos feitos deste ponto em diante tornarão a máquina
segura o suficiente para utilização posterior. Isso simplesmente não vale a
pena devido ao tempo gasto no futuro em novos reparos na máquina.
Em outras palavras, o software deve ser usado para identificar ataques
bem-sucedidos com exatamente esta finalidade: identificação. Além disso,
devemos considerar sempre a necessidade de reconstruir todo o sistema em
vez de reaproveitar o antigo. Pela minha experiência, rootkits traiçoeiros
grudam como cracas no sistema de arquivos. Logo se descobre (como já
ocorreu comigo no passado) que o tempo gasto correndo atrás do próprio
rabo, tentando limpar o sistema, é superior ao tempo realmente empregado
para instalá-lo do zero.
Deixando o “blábláblá” de lado, vejamos como se usa o Rootkit Hunter.
Para instalar esse software sofisticado, os comandos a seguir podem ser
usados.
Em derivados do Debian:
# apt-get install rkhunter
Em derivados do Red Hat:
# yum install rkhunter
Assumindo que sua instalação não apresenta qualquer erro, alguns poucos
comandos simples podem ser executados para começar. Os comandos a
seguir preenchem o banco de dados das propriedades dos arquivos:
# rkhunter-propupd
Em seguida, para escanear qualquer novo software sendo instalado e para
fazer a ativação após a atualização de software, a opção APT_AUTOGEN deve
ser habilitada com yes no arquivo /etc/default/rkhunter. Verifiquei
isso somente em derivados do Debian com Apt Package Manager; pode
haver uma opção diferente em derivados do Red Hat.
Feitas essas alterações, a primeira execução do Rootkit Hunter pode ser
realizada da seguinte maneira:
# rkhunter—check
Observe que há diferenças sutis entre versões ou distribuições. Caso
ocorram erros, tente adicionar -c ou --checkall.
Periodicamente, a lista de ameaças do rkhunter também pode ser
atualizada com o comando a seguir (uma tarefa cron específica pode ser
criada, se desejar) para manter o registro das últimas ameaças:
# /usr/local/bin/rkhunter—update
A Figura 2.2 mostra uma saída abreviada gerada após a execução desse
comando. A saída detalha os testes iniciais realizados pelo software.
O Rootkit Hunter presta atenção aos diretórios-chave contendo arquivos
executáveis (/usr/sbin neste exemplo). Esses são exatamente os tipos de
arquivos binários (entre muitos outros) que se tornam infectados por um
rootkit.
Por um momento, pense nos gregos e na alegoria do Cavalo de Troia. Além
dos rootkits que infectam binários de forma imediata, um trecho de código
pode permanecer dormente por um determinado período de tempo até ser
executado por um usuário legítimo ou por uma tarefa agendada. Em
decorrência disso, ocorre o comprometimento do sistema.

Figura 2.2 – Tela abreviada da saída resultante da execução de running


rkhunter--checkall.

Configuração
Para configurar o Rootkit Hunter, basta editar seu extenso arquivo de
configuração em /etc/rkhunter.conf.
Para receber relatórios noturnos sobre a integridade da máquina, é
necessário editar apenas dois parâmetros de configuração: o endereço de
email do destinatário e um ajuste caso o comando-padrão mail não
funcione em seu sistema por default.
Dentro do arquivo de configuração, observe as linhas destacadas a seguir,
descomente-as e ajuste conforme suas necessidades:
#MAIL-ON-WARNING=me@mydomain root@mydomain
#MAIL_CMD=mail -s "[rkhunter] Warnings found for ${HOST_NAME}"
A primeira linha, após ser descomentada, especifica para onde os relatórios
devem ser enviados (endereços múltiplos devem ser separados por um
espaço). A segunda linha é referente ao comando mail e a linha de assunto
trata dos relatórios de email enviados a esses destinatários.
Para conferir se essas alterações apresentam um desempenho correto e
verificar a caixa de entrada do seu email, basta rodar novamente o software
com rkhunter—check.
Para inspecionar a tarefa cron que dá suporte ao agendamento quando
esses relatórios forem gerados, o arquivo /etc/cron.daily/rkhunter
pode ser consultado. Por default, cron.daily roda geralmente no período
entre 01:00 e 05:00 da madrugada todos os dias, em muitas distribuições.
Se desejar alterar a forma como os emails são mostrados, as seguintes
linhas devem ser localizadas no arquivo cron.daily:
if [ -s "$OUTFILE" -a -n "$REPORT_EMAIL" ]; then
(
echo "Subject: [rkhunter] $(hostname -f)—Daily report"
echo "To: $REPORT_EMAIL"
Como sempre, a prudência ensina que deve ser criada uma cópia desse
arquivo antes de alterá-lo.
Retornemos aos resultados que gerei com a execução do Rootkit Hunter.
Na Figura 2.3 alguns dos rootkits pesquisados pelo Rootkit Hunter podem
ser visualizados.
Figura 2.3 – Lista parcial de alguns dos rootkits pesquisados pelo Rootkit
Hunter.
Como pode ser visto nas Figuras 2.3 e 2.4, há diversas facetas pesquisadas
pelo Rootkit Hunter; as verificações são bastante abrangentes.

Figura 2.4 – Outro exemplo da pesquisa abrangente do Rootkit Hunter.

Falso-positivos
Caso receba quaisquer falso-positivos, você pode colocá-los na whitelist
dentro do arquivo de configuração /etc/rkhunter.conf.
Caso o volume de alarmes falsos se torne problemático, podemos fazer isso
descomentando uma linha de configuração que case com um diretório
completo dentro do arquivo de configuração principal da seguinte forma:
ALLOWHIDDENDIR = /dev/.initramfs
Se o Rootkit Hunter suspeitar equivocadamente que um dos binários foi
substituído por um script, o aviso pode ser removido com a opção:
SCRIPTWHITELIST = "/usr/sbin/lsof"
Em arquivos individuais o seguinte ajuste de configuração pode também
ser usado:
ALLOWDEVFILE = "/dev/.udev/rules.d/99-root.rules"
Tenha em mente que quaisquer arquivos ou pastas (aqueles com nome
começando com um ponto) são quase sempre suspeitos aos varredores do
sistema de arquivos. A Figura 2.5 mostra outra parte dos resultados da
varredura do Rootkit Hunter referentes a verificações da existência de
quaisquer arquivos maliciosos ocultos.
É evidente que as verificações abrangentes feitas pelo Rootkit Hunter estão
bem consideradas. Além do sistema de arquivos e da tabela de processos,
ele também procura anomalias na rede, como pode ser visto na Figura 2.6.

Figura 2.5 – Parte da varredura do Rootkit Hunter envolve a partição /dev e


os arquivos e pastas ocultas.
Figura 2.6 – O confiável Rootkit Hunter realiza também diversas verificações
na rede.

Bem projetado
Os desenvolvedores do Rootkit Hunter o descrevem como uma ferramenta
“que roda no host, passiva, pós-incidente, orientada a caminhos do sistema
de arquivos”. Caso o leitor esteja curioso, o termo “passiva” significa que o
software pode rodar de forma agendada ou manual. Já “orientada a
caminho” (“path-based”) significa que ele lida somente com arquivos, não
operando heuristicamente como um verificador de vírus.
Há uma seção na parte inferior da documentação incluída com o rkhunter
que gostei muito de ler. É uma cartilha elementar muito bem escrita para
todos os novatos em segurança ou para os usuários com mais experiência
buscando apenas uma revisão de conhecimentos.
Ela primeiro ressalta que, antes de o agressor iniciar um ataque, há sempre
alguma forma de reconhecimento ou pesquisa prévia, portanto devemos
prestar muita atenção ao que aparece nos arquivos de log. Em um dos
meus servidores, lembro de ter preparado um script que detectava
traceroutes e tráfego ICMP.
Repetindo o anteriormente citado, o manual prossegue dizendo que esta
ferramenta não é um substituto para o aumento da segurança
(“hardening”) de uma máquina. Não a considere dessa forma, mas sim
como uma ferramenta auxiliar na identificação de problemas.
É interessante observar que a documentação do Rootkit Hunter também
indica um de seus competidores, a excelente ferramenta chkrootkit, uma
encarnação mais antiga do rkhunter. Conforme o manual sugere, o uso de
somente uma ferramenta do mesmo tipo nem sempre é suficiente para
obter toda a informação desejada. Portanto, para trabalhar de forma mais
completa, é benéfico rodar ambas, chkrootkit e o rkhunter. A dica (rodar
mais de uma ferramenta do mesmo tipo) é importante e deve ser aplicada a
todas as facetas da segurança.
Por fim, o manual discorre sobre o que fazer ao perceber o
comprometimento de uma máquina e você não tiver o conhecimento
necessário para lidar com um ataque bem-sucedido. Além de acessar
www.cert.org, talvez seja interessante ir para
www.linuxsecurity.com.br/info/IDS/intruder_detection_checklist.html
em que há uma lista de passos a serem seguidos para reagir a um ataque
online.
Os profissionais muito experimentados nesses ataques recomendam que se
deve considerar para quais autoridades o ataque deve ser informado e
enviar um relatório assim que possível – em vez de esperar por semanas ou
meses – no caso de que algo possa ser feito para evitar esses
comprometimentos. Como sempre o bom senso deve ser a tônica.

Resumo
Neste ponto, o leitor já tem o conhecimento necessário para colocar
impressões digitais nos objetos do sistema de arquivos. Com isso, é
possível comparar rapidamente as somas MD5 anteriores para ver se os
arquivos foram alterados e também rodar o Rootkit Hunter, todas as noites
ou periodicamente. A parte boa dos verificadores de rootkit é a
tranquilidade que também oferecem pelo fato de a varredura programada
destacar falhas de configuração. A correção pode ser então realizada antes
de causar problemas posteriores de segurança.
De todo o exposto, há duas regras a ter em mente:
• Mantenha sempre as somas MD5 gravadas (ou quaisquer outros hashes)
usando algum recurso de segurança (criptografia e proteção por senha) e
desvinculadas do servidor.
• Não confie em ferramentas rootkit para reduzir seus esforços pós-
evento; use-os apenas para identificar problemas. A partir daí, faça uma
análise para concluir como um comprometimento foi possível antes de
partir para a reconstrução da máquina. Não há sentido em gastar um
bom tempo na reconstrução da máquina para, logo em seguida, ser
invadido através da mesma falha de segurança. A frequência com que
isso ocorre é apavorante.
Quando serviços menos críticos estiverem rodando, geralmente não é
preciso muito planejamento nem muito trabalho para garantir a segurança
de uma máquina conectada à internet, mesmo quando tarefas demoradas
são introduzidas no sistema – como, por exemplo, a geração de relatórios
noturnos listando as alterações no sistema. Se forem tomadas precauções
iniciais já no estágio de construção da máquina, os hackers na internet
podem ser mantidos à distância e os profissionais de TI podem trabalhar
em paz.
CAPÍTULO 3
Netcat no século 21

Um dos primeiros pacotes Linux a me deixar maravilhado pelas suas


funcionalidades foi o poderoso netcat (https://nmap.org/ncat). Houve
algumas poucas versões nesses anos, cada uma com um conjunto de
funcionalidades sutilmente diferentes. Quem não o usou ainda, prepare-se
para uma surpresa. Ele é descrito como a única ferramenta que o
administrador de sistemas sempre vai precisar. Essa afirmação talvez seja
demasiadamente otimista, porém o netcat é realmente excepcional.
Para começar, ele é incrivelmente leve e o espaço ocupado no sistema de
arquivos é diminuto. Além disso, uma versão do netcat é incluída por
default em muitas distribuições. Agora que sabemos um pouco sobre ele,
vamos ver como ele pode ser usado em benefício próprio.

História
Ao longo dos anos houve diversas implementações do netcat. A versão
original para Unix/Linux foi escrita em 1995, e em 1998 uma versão
Windows apareceu devido à sua popularidade. Uma vez li que uma
pesquisa conduzida pela Nmap Project (https://nmap.org) descobriu
que, depois de sua própria ferramenta de segurança, o Nmap, seus
usuários optavam pelo netcat como segunda opção.
A funcionalidade do netcat ajudou também a alavancar sua popularidade
em áreas ilícitas. Assim, além do uso em atividades de white hat bem-
intencionadas, ele é bastante usado em reconhecimento de ataques (e nos
próprios ataques). Em decorrência disso, não se espera encontrar versões
completas (modernas) do netcat na infraestrutura das empresas, atendendo
a preocupações de segurança e devido também a seus pacotes serem
colocados como ameaça em listas negras.
Vou tentar explicar de forma sucinta alguns dos parentescos do netcat. É
fácil fazer confusão porque o netcat original (cujo binário executável é
chamado de nc) foi reformulado pelo Nmap Project, que se refere a ele
como o “Netcat for the 21st Century” (Netcat do século 21). O resultado
da reformulação foi um binário denominado ncat. A página principal do
ncat obedientemente reconhece a versão original com o seguinte
comentário final:
O Netcat original foi escrito por *Hobbit* hobbit@avian.org. Enquanto
o Ncat não foi escrito usando qualquer código do Netcat “tradicional”
(ou qualquer outra implementação), o Ncat é definitivamente baseado
no Netcat, em similaridade e em funcionalidade.
Essa versão do netcat (ncat) alega (modestamente) ser capaz de
“concatenar e redirecionar sockets”, porém esta é uma subavaliação muito
simplista de seu conjunto de funcionalidades.
Há uma versão do ncat disponível no Red Hat Enterprise Linux (RHEL) 7,
por exemplo, e suspeito que, além do netcat original (nc), ele foi
disponibilizado em outros releases em diversas encarnações ao longo dos
anos. Há também uma versão do netcat original (incluída por default nas
compilações Debian Jessie e cujo binário é também chamado de nc),
alegando que suas habilidades são o “canivete suíço TCP/IP”. A página do
RHEL 7 a seguir ressalta algumas das poucas diferenças entre essas duas
encarnações: https://access.redhat.com/documentation/en-
US/Red_Hat_Enterprise_Linux/7/html/Migration_Planning_Guide/sect-
Red_Hat_Enterprise_Linux-Migration_Planning_Guide-
Networking.html#sect-Red_Hat_Enterprise_Linux-
Migration_Planning_Guide-Networking-
New_network_configuration_utility_ncat.
Uma visita a essa página permite ver que diversas opções de linha de
comando sofreram alterações. Algumas foram suprimidas e em outras o
ncat mais recente simplesmente alterou seu significado.
É importante observar também que sem o acesso com privilégios de
usuário de root, a taxa de sucesso entre as versões pode variar, portanto o
leitor não deve ficar muito frustrado se tiver de fazer um certo número de
tentativas para fazer o netcat funcionar da forma esperada. Aqui está um
excelente artigo mostrando o procedimento a adotar quando a versão do
netcat não suporta as opções ?e ou ?c para rodar um shell: https://pen-
testing.sans.org/blog/2013/05/06/netcat-without-e-no-problem.
De volta à página RHEL 7 mencionada antes, ela afirma, de forma um
tanto convicta, que o ncat mais recente não inclui certas funcionalidades
presentes no seu parente, o netcat. O motivo talvez seja o fato de essas
funcionalidades simplesmente não serem assim tão úteis na internet
moderna. O site do Nmap Project na web inclui a seguinte afirmação:
O Ncat acrescenta muitas capacidades não encontradas no nc original
da Hobbit, incluindo suporte SSL, conexões proxy, IPv6 e mediação de
conexões. O nc original continha um único scanner de portas, porém a
omitimos do Ncat porque temos uma ferramenta preferencial para essa
função.
Naturalmente, eles estão se referindo à sua famosa ferramenta de
escaneamento de portas Nmap, sugerindo que ela acompanhe o ncat. Em
minha opinião, elas têm um poder enorme quando operam juntas, e minha
sugestão é explorar o considerável conjunto de funcionalidades incluídas
no Nmap.
Voltemos ao netcat. Agora, com o leitor já devidamente confuso, vou
aumentar ainda mais a confusão dizendo que houve também duas versões
do netcat original (refiro-me ao nc e não ao ncat neste caso). O netcat
verdadeiramente original foi escrito pelos programadores da Avian
Research em 1995, e a última versão foi liberada como versão 1.10 em
1996. Uma versão GNU do netcat foi então liberada
(http://netcat.sourceforge.net), cuja versão mais recente, a 0.7.1, foi
liberada em janeiro de 2004. Vale a pena mencionar os dois netcats “nc”
porque o leitor pode ter dificuldades ao usar as mesmas opções de linha de
comando entre as duas diferentes versões. Caí nesta armadilha no passado,
o que me causou muita complicação quando a documentação não casava
com o comportamento do software.
A própria página netcat do Nmap Project
(http://sectools.org/tool/netcat) revela também que houve ainda
mais derivados, incluindo: socat (www.dest-unreach.org/socat),
Cryptcat (http://cryptcat.sourceforge.net), pnetcat
(http://stromberg.dnsalias.org/~strombrg/pnetcat.html) e sbd (um
site informativo não oficial pode ser encontrado em www.question-
defense.com/2012/04/09/sbd-backtrack-5-maintaining-access-os-
backdoors-sbd).

Pacotes de instalação
Para fins de clareza, o Debian Linux e, portanto, o Ubuntu Linux, usam os
nomes dos pacotes mostrados na Tabela 3.1. Em derivados do Red Hat, o
nome de pacote netcat instala, na verdade, uma versão do nc antigo:
# yum install netcat
Para instalar o ncat do Nmap Project, o pacote correto seria:
# yum install nmap-ncat
Para mim, a instalação de um pacote e a certeza de estar lendo a página
principal correta para aquele pacote (caso duas versões do netcat estejam
instaladas na mesma máquina) são garantias de sucesso.
Tabela 3.1 – Nomes dos pacotes Debian e Ubuntu
Nome do pacote Descrição
Um pacote “dummy” (fictício) para fins de compatibilidade, que pode ser removido
netcat
sem problemas
netcat-
O netcat original em versão OpenBSD com suporte para IPv6, proxies e sockets Unix
openbsd
netcat- Pacote original de Hobbit, que não tem muitas das funcionalidades encontradas no
traditional netcat-openbsd
Uma reformulação do netcat original com suporte IPv6 e suporte aprimorado para
netcat6
UDP
nmap Este é o pacote para quem deseja usar o ncat do projeto Nmap no Debian/Ubuntu
Para evitar confusões, vou me concentrar no ncat (e no comando ncat) em
contraposição ao netcat (e, portanto, no comando nc). De agora em diante,
vou me referir ao ncat e ao netcat de forma intercambiável – ou,
naturalmente, ao ncat de forma específica caso seja necessário esclarecer
melhor.

Para começar
Vamos ver o que o equivalente do século 21 do netcat (estou falando do
ncat, lógico) pode fazer, começando com algumas noções básicas. De
forma ousada, o Netcat alega conter funcionalidades poderosas capazes de
manipular dados (tanto leitura quanto escrita de dados) em uma rede via
linha de comando. Ele tem uma alta confiabilidade e pode operar tanto
com TCP quanto com UDP (também trabalha bem com o IPv6). Pode fazer
coisas impressionantes com conexões SSL (Secure Sockets Layer) e pode
também trabalhar com proxies – variantes “CONNECT” SOCKS4 e
HTTP.
A julgar pelas excelentes práticas de programação envolvidas na ferramenta
de segurança Nmap, a qualidade da programação do ncat deve ser também
muito alta. A documentação ncat do Nmap faz questão de afirmar que usa
não somente um código totalmente reescrito (e não emprestado da versão
original), mas também emprega bibliotecas de rede completamente
testadas em condições reais.
Tendo mencionado proxies HTTP, vou começar usando o netcat como um
navegador web. A digitação do comando seguinte, junto com um site da
web arbitrário que se deseje visitar, possibilita a conexão à porta 80 TCP:
# ncat -C www.chrisbinnie.tld 80
Assim que tiver digitado esse comando e pressionado a tecla Enter, será
necessário digitar o seguinte texto, seguido do pressionamento de Enter
por duas vezes:
GET / HTTP/1.0
É bom avisar que, caso isso não seja feito com rapidez, o comando tem sua
temporização vencida e deve ser feita uma nova tentativa. Caso tenha
havido antes uma consulta HTML pela linha de comando, não será
surpresa se depois disso for apresentado um grande volume de informações
rolando para cima na tela. Caso haja interesse, a opção -C coloca um
Carriage Return e um Line Feed (CRLF) no conjunto para garantir a
compatibilidade com alguns protocolos de rede.
O netcat pode ser usado também como um daemon que “escuta”, ou seja,
age como um servidor e não como um cliente, como no exemplo anterior.
Há diversas formas de invadir servidores, e uma maneira de manter o
acesso aberto para uma visita posterior é deixar o netcat escutando em uma
porta obscura não percebida pelo administrador de sistemas.
Mais adiante discorreremos sobre isso; por enquanto o foco será o HTTP.
A documentação do ncat fornece um excelente exemplo de como converter
um binário netcat em um servidor web básico. Para começar, um arquivo
simples deve ser criado. Porém, a extensão .html não deve ser usada
porque o arquivo não é HTML puro, mas sim a metade de uma
conversação HTTP. O arquivo index.http será utilizado com o conteúdo
mostrado na Listagem 3.1.
Listagem 3.1 – Metade de uma conversação HTTP salva no arquivo index.http
HTTP/1.0 200 OK
<HTML>
<BODY>
Nothing to see here, move along.
</BODY>
</HTML>
Conforme mostrado na Listagem 3.1, o código é basicamente HTML,
porém a linha superior (que não é HTML) serve para que o cliente web
visitante saiba que o nosso servidor improvisado acolheu sua solicitação.
Em seguida, o netcat deve ficar pronto para escutar conexões e apresentar
o arquivo quando solicitado. O comando é:
# ncat -l 127.0.0.1 80 < index.http
A propósito, é possível servir todo tipo de outros conteúdos usando o
netcat. Caso o leitor tenha algum dia digitado manualmente uma
conversação SMTP pela linha de comando, provavelmente não ficará
surpreso em descobrir que a opção <CR><LF> (ou seja, a opção –C) opera
da mesma forma nas conversações de email.

Transferência de arquivos
Vamos pensar por um momento no envio de um arquivo de um host para
outro apenas usando netcat em cada ponta. Para isso, não são necessários
daemons SFTP complexos ou aplicativos que exigem muitos recursos.
Vamos chamar as duas máquinas de exemplo de Lionel e Luis, com um
arquivo sendo passado de Lionel para Luis. Em Luis, o seguinte comando é
executado:
Luis> # ncat -l 1234 > bootstrap.pp
A chave -l simplesmente instrui o netcat para “escutar” o tráfego de
entrada. O tráfego está sendo escutado na porta TCP 12341, e os dados de
entrada estão sendo enviados para um arquivo denominado
bootstrap.pp; esse arquivo é um puppet manifest, cuja ação de copiar e
colar entre hosts não é desejada porque é longa e complexa. Agora, com
Luis pronto e esperando a passagem dos dados, o envio de dados de Lionel
é determinado por:
Lionel> # ncat --send-only Luis 1234 < bootstrap.orig
Quando esse comando já tiver rodado em Lionel, a instância netcat em
Luis é finalizada. Antes que Luis encerre, ocorre a transferência do
conteúdo do arquivo bootstrap.orig em Lionel para o arquivo
bootstrap.pp em Luis — uma ação simples e engenhosa. As únicas
possibilidades de algo dar errado são, primeiro, as versões (use somente o
ncat para simplificar), e segundo, o firewall. Abra com muito cuidado as
portas necessárias no firewall caso tenha problemas.
A documentação ncat mostra também como o comando tar pode ser
usado para mover múltiplos arquivos. Considere este exemplo:
Luis> # ncat -l | tar xzv
Lionel> # tar czv <list of files> | ncat --send-only Luis
Novamente, Lionel envia dados para Luis, dessa vez por meio do comando
tar nas duas pontas. Meu exemplo favorito é usar compressão para
acelerar a transferência (arquivos pesados também podem ser movidos) e,
naturalmente, transferir menos dados. Observe este método usando
compressão:
Luis> # ncat -l | bzip2 -d > massive.file.bz
Lionel> # cat massive.file.orig | bzip2 | ncat --send-only Luis
Nesse exemplo, estamos utilizando o confiável comando bzip2 para a
compressão e duplicando massive.file.orig em Lionel para um arquivo
denominado massive.file.bz em Luis. Observe que está sendo usado o
comando cat para ler massive.file.orig e para conduzi-lo por bzip2;
isso não é um erro de digitação.

Exemplo de bate-papo
Vamos nos divertir um pouco mantendo um bate-papo com um usuário de
outro computador. O leitor deve ter visto o comando wall no passado,
aplicado a todos os usuários logados. O netcat pode ser usado para bate-
papo bidirecional. Capture uma porta na máquina receptora (Luis
novamente) e polidamente peça para que o netcat escute, conforme
explicado a seguir:
Luis> # ncat -l 1234
Depois execute o comando a seguir. Após executado, qualquer coisa que o
leitor digitar em Lionel (pressionando a tecla Enter ao final de cada linha
para enviá-la) será espelhado no console de Lionel e vice-versa.
Lionel> # ncat Luis 1234
No fragmento seguinte, pode ser visto como uma comunicação se parece a
partir da perspectiva de Lionel.
# ncat 127.0.0.1 1234
Quer ouvir minhas duas regras para ter sucesso?
Claro!
Regra número 1: nunca conte às outras pessoas tudo o que sabe.
Certo, e qual a segunda?
Câmbio! Alguém na escuta? Caiu a ligação?
Esse exemplo mostra uma das muitas funcionalidades não esperadas
incluídas no netcat. Vou deixar para o leitor a chance de explorar essa
funcionalidade e continuar examinando algumas das outras opções
disponíveis. O netcat é caracterizado por uma superabundância em seu
conjunto de funcionalidades, tantas que não é possível abordar todas neste
livro.

Encadeamento de comandos
Uma das funcionalidades interessantes incluídas no ncat (porém não no
nc) é a capacidade de encadear múltiplas instâncias em um único
comando. Isso torna o ncat muito versátil – uma saída de comando do
netcat pode ser simplesmente conectada à outra, ao estilo Unix. Vamos ver
um exemplo existente na documentação do netcat. Para a tarefa a seguir,
será introduzida a máquina “Neymar” como terceiro host. Lionel ainda é o
emissor e, neste cenário, Luis é o homem no meio (man in the middle).
Reserve um tempo para analisar estes comandos:
Neymar> # ncat -l 1234 > my_new_big_file.txt
Luis> # ncat -l 1234 | ncat Neymar 1234
Lionel> # ncat --send-only Luis 1234 < lengthy_file.txt
Lionel está transferindo seu longo arquivo para Luis, que por sua vez
encadeia os dois comandos netcat juntos com o objetivo de encaminhar o
arquivo para Neymar. Este triunvirato trabalha bem, especialmente se Luis
não puder falar diretamente com Neymar devido a um firewall ou ao
roteamento.
No entanto, a documentação aponta um problema neste cenário: Neymar
não consegue responder para Lionel. Como estamos falando do poderoso
netcat, há uma alternativa. Quando olho para esse exemplo, penso
imediatamente nos ataques realizados com o objetivo de obter ganhos
indevidos (tenho certeza de que o leitor vai se defrontar com isso em algum
momento). Vejamos agora o seguinte conjunto de comandos:
Neymar> # ncat -l 1234 > newlog.log
Luis> # ncat -l 1234 --sh-exec "ncat Neymar 1234"
Lionel> # ncat --send-only Luis 1234 < logfile.log
No meu entendimento, o assustador nesse exemplo é a opção -sh-exec,
que executa um novo comando shell quando Luis estiver recebendo dados.
Imagine o estrago causado com essa opção quando alguém estiver
habilitado a emitir qualquer comando shell. Nesse exemplo, quando Luis
recebe uma conexão, ele gera uma nova instância netcat e passa a controlar
as entradas e as saídas das comunicações entre Lionel e Neymar. Isso é
muito sofisticado.
Aqui está um exemplo de encaminhamento de portas extraído da
documentação, tratando novamente com HTTP, em que um comando
shell pode ser executado para encaminhamento de tráfego:
# ncat -l locahost 80 --sh-exec "ncat www.chrisbinnie.tld 8100"
Os dados são simplesmente encaminhados para a porta 80 TCP, da
máquina local para outro host na porta 8100 TCP.

Comunicações seguras
Havíamos mencionado o SSL anteriormente e a forma como o netcat pode
interagir até mesmo com tráfego criptografado, mesmo sendo esta uma
possibilidade preocupante a ser considerada. Vou iniciar esta seção com
um exemplo de como o netcat pode criptografar seu próprio tráfego. A
chave -C será usada novamente (o que às vezes é chamado de modo
conexão – connect mode):
# ncat -C --ssl ssl.chrisbinnie.tld 443
Estamos supondo aqui que a máquina confiável, ssl.chrisbinnie.tld,
está rodando um servidor SSL na porta 443 TCP e, portanto, pode ser feita
uma conexão a ela. Surpreendentemente, mesmo para servidores SSL
usando certificados de autenticação, o poderoso netcat pode ser muito útil.
Basta apontar o netcat para um local do certificado PEM e dos arquivos de
chave privada, usando respectivamente as opções --ssl-cert e --ssl-key
dentro do comando. As duas opções podem ser apontadas para o mesmo
arquivo, se desejar.
Um ponto importante na troca de certificados, além de criptografar as
comunicações, é o ato de confirmar (por meio de um selo de aprovação
emitido por um serviço de terceiros) que a identidade do servidor SSL é
válida. O netcat tem capacidade para processar essa requisição pelo uso do
comando:
# ncat -C --ssl-verify ssl.chrisbinnie.tld 443
De acordo com a documentação, o netcat pode verificar os certificados SSL
da seguinte forma:
A verificação é realizada usando o pacote de certificados ca-bundle.crt
incluído no Ncat, além de quaisquer certificados confiáveis que o
sistema operacional possa fornecer. Caso deseje verificar uma conexão a
um servidor cujo certificado não é assinado por uma das autoridades de
certificação default, o leitor deve usar o --ssl-trustfile para nomear
um arquivo contendo certificados confiáveis. O arquivo deve estar no
formato PEM. (https://nmap.org/ncat/guide/ncat-ssl.html)
Os documentos oferecem a sintaxe correta para um comando SSL:
# ncat -C --ssl-verify --ssl-trustfile <custom-certs.pem> <servidor> 443
Agora que podemos confirmar à qual máquina estamos conectados, vamos
ver outra função SSL disponível no netcat. Ela tem muitas aplicações, que
exploraremos mais adiante.
A função é descrita como tendo a capacidade de “desempacotar” SSL. A
documentação sugere que o netcat pode ajudar caso haja a tentativa de
coletar emails de um servidor de email com SSL, porém sem dispor das
capacidades SSL no cliente de email.
Para começar, o cliente de email mencionado é apontado para o localhost,
a máquina local, cujo endereço normalmente é IP 127.0.0.1. Com o netcat
escutando localmente na porta 143 TCP (a porta normalmente usada para
comunicações IMAP não criptografadas), o tráfego pode ser encaminhado
para a porta criptografada no servidor de email, porta 993 TCP, desta
forma:
# ncat -l localhost 143 --sh-exec "ncat --ssl mail.chrisbinnie.tld 993"
Esse método pode ser usado em qualquer protocolo que usa dois hosts,
menos o HTTP, por exemplo, e não terá um bom desempenho quando
múltiplos hosts estiverem envolvidos.
O netcat pode também funcionar como um servidor SSL. É necessário
fornecer um certificado que, ao contrário do exemplo anterior, pode ser
verificado por clientes visitantes.
Se um arquivo de certificação e uma chave privada não forem fornecidos –
e usando as mesmas opções de antes (--ssl-cert e --ssl-key) –, o netcat
gera isso automaticamente para o usuário. O netcat pode ser inicializado
usando a opção -l (ou seu equivalente --listen) desta maneira:
# ncat -v --listen –ssl
Como pode ser visto na Figura 3.1, o flexível netcat gera uma chave
temporária para iniciar com mais facilidade.

Figura 3.1 – O Netcat gera automaticamente um certificado SSL temporário.

Executáveis
Além de lidar com a criptografia, um comando também pode ser
executado no shell quando uma conexão for recebida. É desnecessário
dizer que sempre devem ser consideradas as implicações de segurança com
potencial desastroso ao executar os comandos a seguir. Não devemos
tentar isso em máquinas de produção sem estarmos bem seguros de como
funciona internamente. Em outras palavras, estes comandos devem ser
testados antes em máquinas de desenvolvimento para adquirir
familiaridade com os danos consideráveis que podem ser causados.
O primeiro (e preocupante) exemplo de executável a ser considerado é o
próprio shell Bash. Ele não é difícil de usar, o que é muito preocupante. Já
mencionei que invadir um servidor e deixar uma forma alternativa de obter
acesso posterior é algo possibilitado pelo netcat. Com o ncat não é
necessário sequer possuir direitos root para abrir um shell. Convido o leitor
a tentar.
Em nossa máquina de escuta (Luis), cujo shell será aberto para todo
mundo, o seguinte comando deve ser executado:
Luis> # ncat --exec "/bin/bash" -l 1234 --keep-open
E para se conectar a partir do Lionel, basta executar este comando (que já
deve ser bastante familiar ao leitor neste ponto):
Lionel> # ncat Luis 1234
Na primeira conexão à porta 1234 TCP, pode ocorrer a suspeita que o shell
Bash não foi processado corretamente. Assim, tente digitar qualquer
comando Bash válido, como o de solicitar uma listagem de diretórios:
# ls
O diretório atual de Luis será mostrado, porém no console de Lionel, o que
deverá nos deixar preocupados. Digite os comandos de forma muito
cuidadosa, considerando que os retornos Bash usuais não serão mostrados,
podendo facilmente dar margem a exclusão de arquivos e execução de
comandos.
Há uma ferramenta de segurança chamada Metasploit, muito popular e
poderosa, que assume essa funcionalidade de forma mais evoluída,
tornando a backdoor persistente. Mesmo sem o Metasploit instalado para
que o leitor aprofunde seus conhecimentos, vale a pena consultar a página
a seguir, que trata do uso do netcat em máquinas Windows:
https://www.offensive-security.com/metasploit-
unleashed/persistent-netcat-backdoor/. Essa página mostra a forma
relativamente fácil de fazer alterações no registro do Windows e nas regras
do firewall seguindo as instruções fornecidas.
Seja qual for o sistema operacional em uso, o netcat disponibiliza múltiplas
opções. O leitor deve estar ciente de que, se os devidos cuidados não forem
tomados durante o teste, muitas variáveis do ambiente podem ser
disponibilizadas, causando toda sorte de problemas.

Listas de controle de acesso


No netcat as funcionalidades evoluem constantemente. É possível, por
exemplo, adicionar Listas de Controle de Acesso (Access Control Lists, ou
ACLs) às instâncias do netcat. Em um daemon netcat de escuta, as ACLs
podem ser acrescentadas da forma mostrada nos exemplos a seguir. Um
determinado comando Bash sendo considerado pode ser expandido
bloqueando devidamente a respectiva porta, usando um exemplo extraído
da documentação, como mostrado aqui:
# ncat --exec "/bin/bash" --max-conns 3 --allow 192.168.0.0/24 -l 8081
--keep-open
Podemos ver que somente 254 hosts estão sendo permitidos pela faixa de
endereços IP 192.168.0.0 com a máscara CIDR /24, e as máquinas
podem somente abrir um máximo de três conexões. A combinação dessas
opções acrescenta uma versatilidade muito bem-vinda.
O oposto a esse comando pode ser, usando IPv6, um exemplo --deny
como este:
# ncat -l --deny 1222:cb88::3b
Com isso, todas as outras máquinas têm acesso permitido, e somente esta
tem o acesso negado. Como o leitor deve estar imaginando, isso se aplica
igualmente ao IPv4.
Alternativamente, o método a seguir é muito mais eficiente quando se
estiver habilitando ou desabilitando o acesso para múltiplos hosts. Basta
colocar as entradas em um arquivo. Podem ser usadas as opções --
denyfile e --allowfile desta forma:
# ncat -l --allowfile trusted-hosts.txt

Opções diversas
Ocasionalmente, podemos sair facilmente do comportamento default, que
é usar comunicação TCP, usando as chaves -u ou --udp. Veremos mais
adiante por que isso é útil.
Da mesma forma, para iniciar o uso de SCTP (Stream Control
Transmission Protocol), o netcat pode ser provido da opção --sctp.
Outra dica útil é que também podemos acrescentar até três instâncias da
letra v, com -vvv oferecendo a maior verbosidade quando os resultados de
saída dos comandos forem mostrados.
Da mesma forma como foi utilizado para usar comandos SMTP
anteriormente, o poderoso netcat também é capaz de usar comandos
Telnet. Graças a isso, o netcat também pode ajudar caso o leitor esteja sem
acesso a um cliente Telnet. Há alguns benefícios óbvios em usar o netcat
em vez de Telnet. Para começar, o netcat é mais comedido e não entrega
dados na saída, a não ser os enviados pela máquina à qual o usuário está
conectado. Há também uns poucos caracteres de controle reservados,
significando a perda de certos dados binários se o Telnet estiver sendo
usado. Além disso, o leitor deve ter notado que o Telnet desconecta em
conexões sem atividade (idle) e interrompe o funcionamento, podendo
com isso significar o não recebimento de todos os dados de uma sessão
completa. O comando Telnet também não funciona bem com UDP, mas,
como sabemos, o netcat certamente o faz.

Resumo
Neste capítulo tratei apenas de uma parte muito pequena do potencial do
netcat; na verdade, existe simplesmente um enorme escopo a ser
explorado.
Espero que o leitor tenha assimilado os conhecimentos das funcionalidades
sofisticadas desta ferramenta, de importância crítica pela simples razão de
revelar algo mais sobre a forma como elas podem também ser utilizadas
por um invasor.
Na próxima vez que precisar mover arquivos dentro de uma LAN,
certamente usarei o netcat; é muito fácil confiar em ferramentas de
transferência de dados mais complicadas como as ferramentas SFTP para
esse tipo de tarefas simples. O comando Telnet deve ser evitado na
depuração de portas abertas e conexões; em vez disso, deve ser sempre
usado o netcat.
Em meu caso, preciso me lembrar sempre de não mostrar a certos colegas
como fazer determinadas coisas explicadas neste capítulo, visto que há
uma boa chance de eles causarem danos terríveis e deixarem grandes
brechas de segurança.

1 N. do T.: O autor não deixou explícito, mas se não informarmos uma porta específica, o número
de porta default é 31337, que pode ser lido em “leet speak” como ELEET, significando Elite.
CAPÍTULO 4
Negação de serviço

Não se pode negar que, sem certos serviços críticos operando, a internet
seria paralisada. Muitos usuários sofreriam devido à degradação de
desempenho, enquanto outros poderiam simplesmente ser sujeitos a uma
total indisponibilidade. Além do DNS (Domain Name System – Sistema de
Nomes de Domínio), o NTP (Network Time Protocol – Protocolo de
Horário da Rede) é vital para a operação bem-sucedida da internet. Neste
capítulo, dedicarei algum tempo descrevendo como os agressores podem
tentar evitar a operação correta de serviços críticos.
Infelizmente para os responsáveis por manter a internet funcionando, é
possível realizar ataques em grandes seções da infraestrutura DNS e NTP
usando diversos métodos. Por exemplo, os ataques DDoS (Distributed
Denial of Service – Negação Distribuída de Serviço) realizados no passado
eram primariamente destinados a derrubar um serviço online ou, pelo
menos, atrapalhar seus usuários de uma forma altamente frustrante,
possivelmente para obter uma vantagem competitiva ou receber um
pagamento de resgate. Atualmente, é notório que esses ataques são usados
como cortinas de fumaça para disfarçar outros ataques maliciosos.
Segundo um relatório publicado em 2014 pela Kaspersky Lab, empresas de
médio e pequeno porte teriam gasto em torno de 52 mil dólares em um
ataque DDoS. Esse valor poderia subir a cerca de 444 mil dólares para as
empresas vítimas desses ataques. Quando são considerados fatores como
perda de reputação, má vontade dos clientes no uso de serviços online
lentos (se esses serviços ainda estiverem disponíveis) e falhas nas
transações financeiras (as quais demandam envolvimento manual a ser
realizado após o evento), a proteção contra essas ameaças à infraestrutura é
uma atividade que vale a pena. O mais preocupante: das 3.900 empresas
em 27 países incluídas no levantamento originador do relatório, “mais de
um terço (38%) delas, operando no provimento de serviços financeiros ou
em serviços online públicos, foram alvo de um ataque DDoS entre abril de
2013 e maio de 2014”.
Os métodos usados para causar a negação de acesso em serviços online
críticos adquirem muitas formas. Tendo presenciado um aumento nos
ataques reflexivos (incluindo ataques de amplificação) nos últimos dois
anos, tanto em serviços NTP quanto em serviços SNMP, vou contar alguns
pontos da história por trás deles, o que está envolvido e como mitigar seus
efeitos potencialmente desastrosos.

Infraestrutura NTP
Já me referi ao fato de que os serviços críticos de infraestrutura são alvos
comuns de ataques por apresentarem um prêmio valioso para um atacante.
Como os protocolos DNS e NTP evoluíram ao longo dos anos, a segurança
foi, naturalmente, sendo incorporada aos novos releases. Vamos considerar
o NTP por um momento.
Como podemos esperar, há mecanismos de segurança inerentes dando
suporte a reforços no NTP enquanto serviço. Por exemplo, alguns
servidores NTP estrato 1 de nível superior adotam uma opção “Closed
Account”, e esses servidores não podem ser usados sem consentimento
prévio. Por outro lado, assim que é feita a adesão concordando com as
políticas de uso, os servidores OpenAccess se tornam prontamente
disponíveis para acesso. Esses servidores de acesso restrito podem, às
vezes, ter limitações de acesso devido a fatores como o número máximo de
clientes ou um intervalo mínimo de acesso, sendo ocasionalmente
disponíveis somente em determinados tipos de corporações, como as
instituições acadêmicas.
Outro componente de segurança NTP é o fato de o software cliente ser
escrito de modo a acatar as instruções geradas pelos servidores aos quais
solicita informação de tempo. Se um servidor receptor NTP assim o
preferir, ele pode simplesmente bloquear uma solicitação. De forma similar
a determinadas técnicas de roteamento e de firewall, esses pacotes são
descartados ou colocados no “buraco negro” sem qualquer intervenção.
Em outras palavras, o servidor receptor desses pacotes indesejados não
impõe uma carga extra ao sistema e apenas descarta o tráfego que pensa
não ter utilidade como resposta.
No entanto, uma resposta desse tipo nem sempre é útil, e por vezes é
melhor perguntar polidamente ao cliente se deseja suspender e desistir, em
vez de ignorar unilateralmente as solicitações. Por essa razão, existe um
tipo específico de pacote denominado Kiss-o’-Death (KoD, ou Beijo da
Morte). Caso um pacote KoD indesejado seja enviado a um cliente, este
pode aplicar àquele servidor uma marcação de negação de acesso e
procurar outra forma de atualização de horário, ou pelo menos desistir por
um período predefinido de tempo dentro dos limiares ajustados.
Há outras boas razões para cuidar da segurança geral do NTP. Além das
demandas de endereçamento IP e do impacto no uso da largura de banda
pelas operações bancárias, a infraestrutura NTP da internet deve ser
incluída na lista de serviços prestes a serem afetados pelo crescimento
exponencial e potencialmente explosivo da Internet das Coisas (Internet of
Things – IoT). Como já se sabe, bilhões de dispositivos adicionais logo
precisarão ser sincronizados, como o caso de uma geladeira poder
encomendar mais leite antes de qualquer ação do proprietário, entre outros
exemplos.

Ataques reflexivos NTP


No início de 2014 ocorreu um ataque malicioso ao NTP, causando uma
devastação nos Provedores de Serviço Internet (ISPs) e forçando a
comunidade da internet a agir de forma rápida e efetiva para contê-lo.
Durante um curto período, pelo menos entre as vítimas do ataque, ele
causou uma enorme confusão. O ataque assustadoramente simples, porém
inovador, afetou quase todas as implementações NTP. Este ataque foi
chamado de ataque reflexivo (reflection attack), o qual pela sua própria
essência gera tráfego indesejado e impõe esse tráfego a uma vítima. Isso
geralmente acarreta problemas de capacidade de carga ou de largura de
banda afetando a vítima, a não ser que ela conte com infraestrutura
subjacente adequada. No passado, esses ataques eram chamados de
ataques desafio-resposta (challenge-response attacks); entretanto, em
minha opinião esta descrição não é muito conveniente, porque nem todos
os ataques reflexivos envolvem autenticação, e o desafio-resposta é mais
comumente associado com mecanismos de autenticação.
O ataque NTP de 2014 foi similar aos ataques reflexivos DNS presenciados
frequentemente no passado. Quando é percebido que um serviço crítico
como esse tem um vetor de ataque exploratório ainda não conhecido, a
comunidade técnica se mobiliza em uma verdadeira escalada para proteger
suas infraestruturas. Os técnicos são confrontados com a tomada de
decisões críticas, as quais incluem uma avaliação da desativação imediata
do serviço afetado para permitir a operação de outros serviços durante esse
tempo, antes de possibilitar a realização de uma correção (patch), ou de
realizar alterações de configuração. No final das contas, é possível ajustar
manualmente a hora nos computadores ou, em muitos casos, admitir uma
ligeira imprecisão no relógio do sistema. Muitos serviços conseguem
sobreviver por 24 horas em condições de ausência de atualizações de
sincronismo NTP sem que qualquer efeito indesejado seja percebido.
Nesses tipos de ataque, dois termos são frequentemente citados. O
primeiro é reflexão (reflection), que remete ao redirecionamento do tráfego
sob ataque de forma similar a um espelho. Neste caso, muitos serviços de
terceiros, e não o atacante, geralmente respondem enviando tráfego para
uma vítima (o alvo principal). Isso é obtido forjando ou falsificando os
endereços IP dos atacantes e em seguida enganando a terceira parte sobre
quem solicitou originalmente o tráfego.
A amplificação (amplification), por outro lado, pode ser mais bem ilustrada
como o envio de um pacote de dados contendo uma solicitação, o que
provoca a geração de centenas de pacotes de retorno com a resposta. No
caso de um ataque reflexivo, isso se refere a uma vítima insuspeita
recebendo o payload (parte dos dados úteis de uma mensagem) ou uma
extensa resposta a uma questão ainda não feita.
Imaginemos três máquinas dispostas em um triângulo. A máquina A envia
à máquina C uma série de questões em nome da máquina B. A máquina C
então envia incorretamente todas as respostas para B. A máquina B é
sobrecarregada pelo volume de respostas. A máquina A é invisível para B, e
B nem tem como saber que A está envolvida no ataque. Para os
encarregados da proteção das respectivas infraestruturas, isso leva a
consideráveis desafios de diagnóstico.
Conforme relatos, a razão de amplificação do tráfego DDoS gerado por um
ataque reflexivo DNS padrão é de aproximadamente 70:1. Em outras
palavras, havendo 1 gigabit de largura de banda disponível no link do
agressor, consegue-se aproximadamente 70 gigabits chegando à conexão
da vítima. As razões de reflexão já mencionadas possibilitadas pela
exploração NTP foram relatadas como estando entre 20:1 e 200:1. Basta o
agressor consultar uma lista de servidores NTP públicos, disponível
gratuitamente, para criar um assustador volume de tráfego NTP
alimentando um ataque DDoS.
O ataque NTP ocorreu, como acontece muito, de forma terrivelmente
simples. Ele foi baseado em uma função residente pela qual se permite a
qualquer um solicitar às últimas poucas centenas de servidores a realização
de conexões a um servidor NTP. A função explorada é denominada
monlist; o leitor pode tê-la visto como MON_GETLIST. Um atacante
falsifica o endereço IP, formulando a questão de modo a fazer o servidor
NTP consultado responder à vítima em vez de fazê-lo à máquina que
apresentou a questão. Com a repetição constante do comando, a vítima
logo fica sobrecarregada quando milhares de servidores estiverem enviando
respostas simultâneas. A “amplificação” deste ataque “reflexivo”, no qual a
quantidade de dados envolvida nas respostas é muito maior que a da
questão original, é o que o torna tão devastador. Isto porque basta um
número relativamente pequeno de servidores usados originalmente na
geração dessas questões para derrubar enormes seções de infraestrutura.
A essência de mitigação desse tipo de ataque, em um sistema IPv4 (com a
primeira linha mostrando -4) e em um sistema IPv6 (com a segunda linha
com -6), compreende as linhas seguintes dentro do arquivo de
configuração NTP:
restrict -4 default nomodify nopeer noquery notrap
restrict -6 default nomodify nopeer noquery notrap
Um modelo (template) NTP muito bem-vindo, que pode ser usado para
evitar que um servidor público seja usado como parte desses ataques, está
disponível em www.team-cymru.org/templates.html. Nessa página, um
clique no link Secure NTP Template apresenta uma coleção de templates
para diversas plataformas, incluindo Cisco iOS, Juniper Junos e Unix.
É também incluído um lembrete útil de como configurar o IPtables para
ajudar no bloqueio do NTP, conforme mostrado a seguir:
# iptables -A INPUT -s 0/0 -d 0/0 -p udp --source-port 123:123 -m
state --state ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -s 0/0 -d 0/0 -p udp --destination-port 123:123
-m state --state NEW,ESTABLISHED -j ACCEPT
Além disso, há uma nota interessante acerca das implicações
potencialmente danosas caso o responsável pela infraestrutura entre em
pânico e decida interromper o tráfego NTP na rede bloqueando-o no nível
do roteador. A filtragem da porta UDP 123 para tráfego somente deve ser
feita mediante a compreensão exata do que se está fazendo porque, de
outra forma, os serviços-chave serão inevitavelmente perdidos.

Relatórios de ataques
Quando aquele primeiro ataque NTP ocorreu, o provedor de serviços em
nuvem CloudFlare anunciou o maior ataque DDoS jamais registrado do
gênero. De acordo com a CloudFlare, o ataque chegou a quase 400 Gbit/s
de tráfego e, assustadoramente, apenas 4.529 servidores foram utilizados
para gerar toda aquela saturação de largura de banda de tráfego em 1.298
redes diferentes. Em contraste, um ataque muito divulgado que derrubou o
Spamhaus (o provedor de serviços anti-spam) usou supostamente 30.956
resolvedores DNS abertos para gerar um DDoS a 300 Gbit/s. Como
podemos ver, há uma diferença significativa de impacto quando se toma as
máquinas como base.
Outro protocolo que vem sendo usado de forma crescente em ataques
DDoS foi criado em 1988 pela PSINet, na época um dos maiores (se não o
maior) provedores de serviço internet antes de ser absorvido por diversas
fusões e aquisições.
O protocolo SNMP (Simple Network Management Protocol) está presente
na grande maioria dos dispositivos de rede, como switches e roteadores.
Esse protocolo útil possibilita que qualquer software capaz de recebê-lo
seja alimentado com informações estatísticas, como o uso da largura de
banda. O mais importante, habilitado por default, é um vetor de ataque
baseado em uma string de comunidade denominada “public”. Mesmo
quando senhas são configuradas por default, elas tendem a ser simples,
como “privado”. Isso significa que até mesmo um roteador banda larga
representa um risco potencial e pode participar de um ataque DDoS.
Considere também os dispositivos habilitados para SNMP pertencentes a
empresas ou provedores de serviço internet; pode haver dezenas de
poderosos switches e roteadores em um único segmento de rede com
acesso à largura de banda de alta capacidade. A propósito, até mesmo
impressoras em escritórios geralmente empregam implementações SNMP,
além de workstations e câmeras de vídeo IP.
Foram constatadas atividades conduzidas por atacantes fazendo
experiências com o SNMP em consideráveis ataques reflexivos/de
amplificação. As alarmantes razões de tráfego teriam atingido um valor
próximo a 1.700:1. Evidentemente, a precisão dessas estimativas ainda
precisa ser verificada, assim como o grau de alarmismo associado.
Em maio de 2014, a divisão DDoS da Akamai informou ter identificado 14
ataques SNMP. Cerca da metade deles ocorreu nos EUA, e em torno de
18% na China.

Prevenção de reflexões SNMP


Uma rápida consulta ao conteúdo do arquivo /etc/services permite
visualizar os seguintes detalhes das portas default usadas pelo SNMP:
snmp 161/tcp # Simple Net Mgmt Proto
snmp 161/udp # Simple Net Mgmt Proto
snmptrap 162/tcp # SNMPTRAP
snmptrap 162/udp snmp-trap # Traps for SNMP
Para evitar reflexos de tráfego SNMP originado por uma rede, pode ser
seguida uma prática denominada deny-by-default (negar por default), na
qual os firewalls de perímetro não deixam que o tráfego saia da LAN e
atinja a internet. Naturalmente, isso também se aplica ao tráfego externo
chegando à LAN. Porém, muitas vezes os ajustes default são deixados
inalterados quando o processo de configuração do equipamento é feito às
pressas, passa por atualizações ou é configurado por pessoal com pouca
capacitação, resultando na perda destas medidas preventivas. O mais
preocupante em relação a este tipo de ataque é a enorme quantidade de
roteadores de banda larga espalhados pelo planeta, demandando muito
tempo para que alguns deles sejam corrigidos manualmente (embora
provedores de serviço internet responsáveis possam acrescentar filtros de
entrada e saída em suas redes). Enquanto isso, extensas seções de
infraestrutura passam a enfrentar problemas de desempenho.
O ataque SNMP descrito pela Akamai foi atribuído a uma ferramenta de
ataque especialmente criada. Essa ferramenta automatiza solicitações
“GetBulk” do SNMP e falsifica (spoof) o endereço IP, da mesma forma que
os ataques reflexivos NTP e DNS, para assegurar que a avalanche de
respostas a solicitações espúrias chegue ao endereço IP da vítima.
Felizmente, este ataque em particular se aplica somente a uma versão mais
antiga do SNMP, a versão 2. A versão 3 oferece maior segurança e não está
tão vulnerável a abusos mesmo nas configurações default.
De forma preocupante, a ideia-chave desse ataque foi a geração de um
pesado volume de tráfego a partir de poucas solicitações e provavelmente a
partir de uma única máquina. Os criminosos podem perturbar grandes
seções da infraestrutura online sem precisar investir em tempo e recursos (e
muitas vezes sem precisar do dinheiro necessário para adquirir uma
botnet).

Resolvedores DNS
Quase no final de 2014, outro ataque interessante tornou-se conhecido.
Até hoje é de certa forma questionável se ele realmente pretendia ser um
ataque reflexivo, porém vou discuti-lo aqui para aumentar o conhecimento
do leitor em relação ao assunto. Como parte dos serviços oferecidos, o
Google oferece dois importantes servidores de DNS com endereços IP de
fácil memorização:
8.8.8.8
8.8.4.4
Eles permitem consultas DNS recursivas para qualquer pessoa ou
dispositivo que não tenha acesso a um servidor DNS e respondem a
qualquer consulta realizada, pelo seu cache ou por uma nova consulta caso
a resposta adequada não exista no cache. O OpenDNS oferece serviços
similares, porém filtram todas as solicitações DNS, com o objetivo de
alertar o usuário, por exemplo, caso este tenha tentado visitar um site de
phishing já anteriormente identificado. Os seus endereços IP são também
de fácil memorização, resilientes e confiáveis:
208.67.222.222
208.67.220.220
Esses serviços (geralmente) gratuitos são largamente adotados,
provavelmente por oferecerem a conveniência de não ter o overhead
associado com a execução local de servidores DNS. Entretanto, devido aos
endereços IP de fácil memorização e à excepcional confiabilidade,
infelizmente como muitos serviços populares, esses bem-intencionados
provedores apresentam outro alvo de grande valor que é atrativo para os
atacantes.
Evidentemente, há várias boas razões para prestar muita atenção aos locais
em que esses serviços são utilizados dentro da infraestrutura de produção;
a falta de controle pode torná-los comprometidos. O ataque mais óbvio,
em termos de consulta DNS, pode ser o comprometimento do cache DNS,
em que a máquina solicitante coloca uma resposta falsa e a envia a um
endereço IP ilegítimo, podendo potencialmente infectar o requisitante ou
atacá-lo de alguma outra forma. Entre os muitos ataques de
envenenamento de cache DNS estão os ataques estilo Kaminsky
(Kaminsky-style attacks; http://dankaminsky.com), que não exatamente
envenenam registros DNS individuais, mas em vez disso passam a
controlar, eles próprios, os registros da autoridade de nomes de domínio.
Há algumas informações muito bem escritas acerca dos achados do
pesquisador de segurança Dan Kaminsky em
http://unixwiz.net/techtips/iguide-kaminsky-dns-vuln.html.
Devido aos seus impactos, a relevância dos ataques DNS não deve ser
subestimada. Estima-se que os resolvedores DNS do Google atendam a
cerca de 150 bilhões de consultas por dia.
O ataque de 2014, que na superfície incluiu os endereços IP dos
resolvedores DNS do Google no último trimestre daquele ano, foi
noticiado pelos canais jornalísticos de segurança mais populares da
internet. Por exemplo, o Internet Storm Center (https://isc.sans.edu)
publicou uma matéria com dicas para identificar, no momento de sua
chegada a uma rede, os ataques supostamente vindos dos servidores de
DNS do Google. Com algumas técnicas simples de farejamento de pacotes
(packet sniffing), é possível monitorar esse tipo de ataque e verificar sua
frequência.
Neste caso, usando a ferramenta de captura de rede tcpdump, estamos
simplesmente despejando em um arquivo chamado
/tmp/suspect_traffic qualquer tráfego pertinente identificado como
suspeito. O que ocorre é a categorização daquele tráfego como qualquer
coisa recebida do endereço IP 8.8.8.8 (exatamente um dos resolvedores
DNS do Google) e destinado à porta 161.
# tcpdump -s0 -w /tmp/suspect_traffic dst port 161 and src host 8.8.8.8
Pela captura desse tráfego, pode ser feita a monitoração do seu volume e
verificar a probabilidade das solicitações DNS serem legítimas. Caso um
tráfego indesejado seja descoberto, a forma como os dispositivos afetados
se comunicam com o exterior da rede pode sofrer restrições introduzindo
regras de firewall. A ação de firewall permite que os dispositivos em
questão tenham acesso ao mundo externo.
As discussões entre os hackers do bem (white hats) e outros profissionais
da área de segurança sugeriram que esses ataques, com tráfego
aparentemente originado dos endereços IP do Google, foram na verdade
concebidos (usando os endereços IP pré-configurados como servidores
DNS dos dispositivos) para explorar e subjugar dispositivos com
configuração pobre com outras intenções nocivas, em vez de usá-los para
reflexão de tráfego. Em outras palavras, os atacantes podem
potencialmente reconfigurar esses dispositivos para seus próprios usos
desonestos em vez de negar o serviço.
Como leitura adicional, o leitor pode considerar um vetor de ataque
separado e uma tentativa de driblar os anúncios BGP legítimos (o Border
Gateway Protocol – BGP – é o protocolo de roteamento sofisticado que
integra muitas redes da internet) dos resolvedores DNS do Google; mais
informações sobre isso podem ser obtidas em
http://thehackernews.com/2014/03/google-public-dns-server-
traffic.html.

Cumplicidade
Há um conjunto de recomendações voltadas à limitação do tráfego
falsificado deixando uma rede. Infelizmente, a experiência mostra que, por
incompetência ou por falta de recursos, sempre haverá uma percentagem
de administradores de rede falhando na importância de seguir certas
diretrizes ou simplesmente não estando equipados para prestar atenção a
isso. Sem esquecer, evidentemente, a pequena percentagem desses
administradores deliberadamente deixando brechas de propósito para
atividades criminosas.
Um documento mais antigo foi escrito em 2000 para estimular debates e
dar subsídios aos interessados em manter a internet funcionando.
Chamado de Best Current Practice 38 (BPC 38;
https://tools.ietf.org/html/bcp38), este documento oferece
orientações muito bem-vindas para os administradores de rede. Ele
encoraja empresas e instituições acadêmicas, entre outras organizações, a
reforçar os diferentes aspectos das respectivas infraestruturas de rede, tanto
nos hosts quanto no equipamento de rede, para prevenir o efeito cascata na
internet.
De forma específica, ele dedica um tempo na discussão da importância da
filtragem do tráfego de entrada para proteger as redes externas de sua
própria rede, caso ela seja usada como ferramenta de ataque. Ele cita o
emprego de medidas preventivas simples, o diagnóstico e a mitigação de
um ataque vindo de uma fonte “válida” como sendo bem mais eficientes
que supor de onde vem o tráfego de origem, como foi visto na seção
anterior “Ataques reflexivos NTP”.
Diferentes níveis de filtragem do tráfego de entrada devem possibilitar a
obtenção do objetivo em diversas circunstâncias. Uma das observações
apresentadas é que, pela redução do número e da frequência dos ataques
na internet, mais recursos estarão finalmente disponíveis quando os
ataques ocorrerem. Como resultado, as respostas serão mais efetivas.
Grande parte do conteúdo presente nessas produtivas diretrizes é atribuída
ao venerável NANOG (North American Network Operators’ Group;
https://www.nanog.org), o qual, de forma veemente, discute em detalhes os
problemas das redes em uma lista de discussão por email (mailing list)
muito popular.

Uma nação de joelhos


A ameaça de ataques de múltiplos sistemas geograficamente dispersos
sendo dirigidos a um único sistema – como um sistema em rede ou
autônomo, independentemente de seu tamanho –, levando-o a uma
condição offline, tem sido uma preocupação para empresas, provedores de
serviço internet e até mesmo de nações inteiras. Os ataques DDoS podem
até ter existido desde meados dos anos 1980.
Em 2007 foi amplamente noticiado que o Estado Báltico da Estônia sofreu
repetidos ataques DDoS, os quais, junto com manifestações nas ruas,
quase deixaram o governo de joelhos. Aparentemente, a população era
contrária à remoção de um famoso memorial de guerra pelo parlamento da
Estônia. Junto com um considerável descontentamento social, este foi o
momento crítico definitivo. Os níveis progressivos de aumento do tráfego
de ataque DDoS foram recebidos de forma constante por um prolongado
período de tempo. As agências de notícias ficaram frustradas com a falta de
conectividade, o que significou para o restante do mundo a
impossibilidade de ficar atualizado com os eventos se desdobrando pelo
país.
O DDoS estoniano recrudesceu, e estima-se que em um determinado
momento o tráfego de ataque chegou a envolver quatro milhões de pacotes
por segundo. O ataque foi parcialmente destinado a desconectar da
internet o maior banco do país e, conforme alguns relatórios, isso foi afinal
conseguido. De acordo com as estatísticas nacionais, cerca de 97% da
população realiza operações bancárias online, tendo isso significado uma
falha crítica no sistema bancário do país. E como se o impacto não tivesse
ainda sido suficientemente danoso, a falta de conectividade com a internet
incapacitou a comunicação do banco com os caixas automáticos,
tornando-os impossibilitados de fornecer dinheiro.
De forma preocupante, foi divulgado que a única prisão relacionada com
este incidente extremamente destrutivo, com duração aproximada de três
semanas, resultou em uma multa inferior a 2 mil dólares. O envolvimento
da OTAN na promoção de respostas internacionais efetivas a estes ataques
foi reforçado pelas duras lições aprendidas na Estônia.

Mapeamento de ataques
O excelente livro Firewalls e segurança na internet: repelindo o hacker
ardiloso, escrito por William Cheswick, et al. afirma de forma sucinta na
Introdução:
A Internet é uma grande cidade, não uma série de pequenos vilarejos.
Qualquer um pode usá-la, e de forma quase anônima.
A Internet é uma vizinhança ruim.
A validade dessa citação pode ser confirmada usando a Digital Attack Map,
uma ferramenta online que proporciona uma excelente visão global dos
ataques DDoS. Com atualizações de hora em hora, ela pode ser vista em
www.digitalattackmap.com.
Totalmente gráfica, a Digital Attack Map é resultado de uma colaboração
entre a Arbor Networks e a Google Ideas, que abastecem a ferramenta com
dados enviados por cerca de 270 provedores de serviço internet em todo o
mundo. Esses provedores de serviço firmaram um acordo para
compartilhar dados com o ATLAS, sistema global de inteligência contra
ameaças da Arbor Networks. Os dados estão também disponíveis por meio
do portal de ameaças ATLAS da Arbor e pode valer a pena dar uma olhada
em www.arbornetworks.com/threats.
Além disso, em www.digitalattackmap.com/gallery, há uma galeria útil
ressaltando os ataques-chave históricos para referência. Pode ser feita uma
interação posicionando o mouse sobre os fluxos de ataque e observando
quantos gigabits por segundo extrapolaram a largura de banda durante o
ataque. São também informadas as fontes aproximadas dos ataques (por
exemplo, se um ataque foi gerado por uma botnet, ele pode ter origens em
dezenas de países diferentes), a vítima supostamente pretendida e a
duração do ataque. Há interesse também em saber as portas da fonte e do
destino usadas durante o ataque; em um dos primeiros poucos ataques aos
quais prestei consultoria, constatei a presença da porta NTP, porta UDP
123. Contudo, é interessante que as portas 80 e 53, respectivamente HTTP
e DNS, ainda parecem ser os serviços DDoS mais populares, a julgar pelos
dados disponíveis.
A Figura 4.1 contém uma amostra de ataques revelados pelo site da Digital
Attack Map, com os tipos de ataques e seus códigos de cores no lado
esquerdo do mapa global. Esta é apenas a janela inicial desse site altamente
funcional. Podemos gastar horas expandindo tanto as informações atuais
quanto as históricas permitidas pelo site em um formato facilmente
digerível.
Figura 4.1 – O abrangente site Digital Attack Map da Arbor Networks,
equipado pela Google Ideas.

Resumo
Neste capítulo, foram vistas diversas questões de segurança passíveis de
afetar os serviços críticos de infraestrutura. Esses serviços, impactados de
forma mais severa devido ao uso do UDP, mais vulnerável, ajudam de
forma genuína a operação da internet e claramente devem ser protegidos.
Alguns desses ataques são de uma concepção mais antiga, porém é
interessante notar como as categorias dos ataques reaparecem e decrescem
em diferentes períodos de tempo. Por exemplo, um ataque que não tinha
mais sido visto por muitos anos ressurge em um estado ligeiramente mais
evoluído. Como visto mais recentemente, as ferramentas de ataque SNMP
originadas da comunidade de hackers, na maioria das vezes encorajada
pelo sucesso dos ataques reflexivos NTP, geraram o maior interesse.
Mesmo não sendo possível seguir os intrincados meandros dos ataques
mais sofisticados em detalhes, a premissa é simples. Os serviços baseados
em UDP são atualmente os mais expostos a riscos. O UDP nem sempre
espera que haja respostas (o TCP conta com um handshake triplo),
portanto tem maior probabilidade de ser explorado por ataques reflexivos
e de amplificação.
O leitor pode ter pensado inicialmente que, ao bloquear inicialmente os
serviços de rede na fase da construção (apenas abrindo parcialmente os
serviços necessários usando ACLs), esses tipos de ataques raramente
poderiam impactar uma rede ou as operações diárias do sistema. No
entanto, se desejar sucesso no funcionamento de uma infraestrutura face
ao panorama de ataques atual em mutação contínua, é imperativo haver
um monitoramento permanente de como as redes e os sistemas interagem
com o mundo externo, revisando frequentemente as ACLs e as políticas.
Essa é uma proeza impossível de conseguir sem a consulta diligente às
listas de segurança e o acompanhamento vigilante dos comunicados da
imprensa técnica. Ao fazer isso, portanto, garante-se que seus serviços
internet não passarão a fazer parte do problema e a comunidade global
pode manter a internet funcionando.
CAPÍTULO 5
Nping

Assim como a DARPA – Defense Advanced Research Projects Agency


(Agência de Projetos de Pesquisa Avançada de Defesa) muito contribuiu e
ajudou a dar forma à internet tal qual a conhecemos e amamos hoje, de
forma similar a transição do uso militar para o civil resultou também na
ferramenta mais comum de descoberta de rede usada na internet hoje: o
comando ping. O ping foi inspirado na área naval, em que o sistema sonar
de navios envia impulsos sonoros para detectar outras embarcações ou
ocorrências geofísicas nas proximidades.
Como parte da funcionalidade de descoberta de rede contida na poderosa
ferramenta de segurança Nmap (https://nmap.org), esta também inclui
acesso a um aprimoramento do comando-padrão ping, denominado
Nping (https://nmap.org/nping/). Caso o leitor já tenha usado o Nmap,
sabe que está em boas mãos com qualquer ferramenta criada pelo projeto
Nmap em termos de confiabilidade e concepção funcional.
Vamos ver como a ferramenta Nping pode ajudar o leitor a obter um maior
conhecimento do que está ocorrendo em seus sistemas e redes,
pesquisando as conexões remotas e locais.

Funcionalidade
Na superfície, são esperadas funcionalidades relativamente limitadas do
Nping. Afinal de contas, quando um ping é emitido, uma questão é
enviada e é esperada apenas uma resposta. Embora Nping não seja ainda
uma peça de software acabada, podemos afirmar com segurança que ela é
uma ferramenta altamente abrangente e sofisticada para uso em redes.
Vamos começar nos acostumando com a sintaxe. É necessário fazer login
com privilégios de root, o superusuário, para executar alguns comandos
Nping, e nesse caso deve ser considerado o modo TCP. O primeiro
exercício é enviar “pings” TCP (o leitor leu corretamente; não são pings
ICMP) para sua máquina local. Na página de manual do ping, podemos
ver que a operação normal de ping “usa o datagrama mandatório
ECHO_REQUEST do protocolo ICMP para obter uma resposta ICMP
ECHO_RESPONSE de um host ou um gateway”. Em outras palavras, há
uma pergunta e uma resposta envolvidas.
Caso o leitor esteja se perguntando, usarei minha máquina local para esses
exemplos para evitar perturbar quaisquer outras máquinas e não
congestionar logs de firewall com atividades suspeitas. Assim como todas
as ferramentas de white hat, esta também deve ser usada com muito
cuidado.
Não apenas no caso do ICMP, a impressionante funcionalidade Nping é
uma extensão muito bem concebida do comando-padrão ping, que pode
também “falar” em muitos protocolos diferentes. Ela também possibilita
resultados de fácil compreensão.
Caso o leitor ainda não a tenha em sua máquina, a ferramenta Nping pode
ser instalada da forma descrita a seguir.
Em derivados do Debian, basta usar o comando seguinte para instalar o
pacote Nmap:
# apt-get install nmap
Em derivados do Red Hat, a instalação do Nmap é feita usando este
comando:
# yum install nmap

TCP
De volta ao exemplo do TCP (Transmission Control Protocol). O comando
a seguir pode ser rodado em uma máquina local, o que afasta a
preocupação com problemas relacionados a firewalls e não aborrece outros
administradores de sistema:
# nping -c1 --tcp -p 80,443 localhost
Nesse caso está sendo enviado para a máquina local um pacote ping (com
uma opção de contagem -c1) sobre TCP, para as portas TCP 80 e 443. A
saída desse comando pode ser parecida com a Listagem 5.1.
Listagem 5.1 – Após o envio dos primeiros pings TCP usando Nping, são dadas as boas-
vindas com um bom nível de detalhes.
Starting Nping 0.5.51 ( http://nmap.org/nping ) at 2016-11-16 11:16 GMT
SENT (0.0145s) TCP 127.0.0.1:16463 > 127.0.0.1:80 S ttl=64 id=58041
iplen=40 seq=2781160014 win=1480
RCVD (0.0148s) TCP 127.0.0.1:80 > 127.0.0.1:16463 SA ttl=64 id=0
iplen=44 seq=2400211610 win=65495 <mss 65495>
SENT (1.0148s) TCP 127.0.0.1:16463 > 127.0.0.1:433 S ttl=64 id=58041
iplen=40 seq=2781160014 win=1480
RCVD (1.0150s) TCP 127.0.0.1:433 > 127.0.0.1:16463 RA ttl=64 id=0
iplen=40 seq=0 win=0
Max rtt: 0.079ms | Min rtt: 0.055ms | Avg rtt: 0.067ms
Raw packets sent: 2 (80B) | Rcvd: 2 (84B) | Lost: 0 (0.00%)
Tx time: 1.00054s | Tx bytes/s: 79.96 | Tx pkts/s: 2.00
Rx time: 2.00171s | Rx bytes/s: 41.96 | Rx pkts/s: 1.00
Nping done: 1 IP address pinged in 2.03 seconds
A Listagem 5.1 mostra que a resposta foi obtida das duas portas TCP, a 80
e a 443. Os pings se interrompem depois de cada porta enviar dados por
uma única vez (e houver o retorno de dados) de acordo com a opção --c.
Caso não haja uma resposta válida óbvia, pode ser visto algo como
apresentado a seguir:
nping_event_handler(): READ-PCAP killed: Resource temporarily unavailable
nping_event_handler(): TIMER killed: Resource temporarily unavailable
Agora, com alguma ideia de como o Nping se parece e reage aos
comandos, não será surpresa saber que ele pode sempre usar a notação de
rede Classless Inter-Domain Routing (CIDR) (por exemplo,
10.10.10.0/24). Por enquanto, o leitor deve permanecer no básico e ter
preocupação com a forma de especificar uma faixa de portas para realizar o
ping, em vez de fazer essa especificação em uma lista recém-preparada.
Vamos considerar as “portas privilegiadas” (privileged ports) em uma
máquina Unix. No passado, alguns poucos nomes foram atribuídos a essas
portas, como portas de superusuário (superuser) ou portas de sistema, mas
essencialmente somente um usuário com privilégios de root tem permissão
para abri-las. Esta era uma funcionalidade original de segurança
significando que, em uma conexão remota a um desses números de porta,
havia uma razoável certeza de estar rodando um serviço genuíno. Em
outras palavras, a porta estaria sendo servida por um software rodando
com privilégios de root, não um usuário comum. A seguir vemos como
verificar todas as portas TCP privilegiadas com o Nping:
# nping -c1 --tcp -p 0-1024 localhost
Usando um método quase certamente diferente de outras ferramentas de
rede, o Nmap interage com múltiplos hosts e múltiplos números de porta
de forma incomum. Para manter a eficiência, caso mais de uma máquina-
alvo esteja especificada, o Nping não envia uma solicitação à primeira
máquina da lista e pacientemente espera por uma resposta. Pelo contrário,
ele emprega uma abordagem round-robin ao mesmo tempo simples e
inteligente, na qual as máquinas são contatadas de forma alternada em
uma rotação, para não introduzir retardos ao usuário quando este estiver
aguardando respostas. Com hosts múltiplos, isso é também aplicável a
múltiplas portas para dar chance de recuperação ao alvo antes de
responder à próxima porta a ser sondada pelo Nping.

Intérprete
O Nping pode funcionar como um intérprete para diversos protocolos.
Caso a opção --tcp-connect seja usada, é associado o modo de conexão
TCP para o Nping. Neste caso não é necessário usar privilégios de root
para enviar o que poderiam ser pacotes brutos (raw packets); em vez disso,
o Nping pergunta ao sistema operacional se este pode criar as conexões
apropriadas em seu nome. O conteúdo dos pacotes recebidos ou
transmitidos não pode ser visto neste modo, porém pelo menos o status
das transmissões pode ser conhecido.
Como poderíamos esperar, a opção --tcp, quando rodada pelo usuário
root, possibilita a obtenção de excelentes resultados com pacotes TCP. Por
exemplo, pode ser tentado manipular os resultados de uma conexão
completando apenas parcialmente um handshake TCP com mensagens
TCP SYN. A documentação informa que há uma possibilidade real de
ocorrer danos (na verdade, ela usa a expressão “evil” – maldade, em inglês)
com pacotes TCP RST customizados, com falsificação dos endereços IP e o
fechamento de sessões TCP ativas, portanto o leitor está devidamente
alertado.
A seguir vemos como a manipulação de handshakes TCP é apresentada no
caso de uso de três comandos separados:
# nping --tcp -p 80 --flags rst -c1 localhost
# nping --tcp -p 80 --flags syn -c1 localhost
# nping --tcp -p 80 --flags ack -c1 localhost

UDP
Podemos optar também pelo emprego de pacotes UDP (User Datagram
Protocol) usando a opção --udp. Normalmente, os pacotes TCP e UDP são
embutidos dentro de pacotes IP, porém, como já citado, sem permissões de
root, e contanto que os cabeçalhos do protocolo default não tenham sido
alterados, o conteúdo dos pacotes não pode ser visto, apenas o status da
transmissão. O mesmo é aplicável a pacotes UDP.
Um ping UDP pode às vezes descobrir máquinas onde outros protocolos
falham. É possível que um ping UDP iluda um firewall e apresente um
relatório se um dispositivo estiver escutando depois daquele firewall. Este é
um acréscimo muito útil ao kit de ferramentas. Um exemplo de comando
simples pode ser parecido com este:
# nping --udp localhost
Quando tento executar esse comando na máquina local sem ter os
privilégios de usuário de root, a seguinte mensagem de retorno é
apresentada:
SENT (0.0069s) UDP packet with 4 bytes to localhost:40125 (127.0.0.1:40125)
ERR: (0.0070s) READ to 127.0.0.1:40125 failed: Connection refused
No entanto, como superusuário, root, posso completar a transação da
seguinte maneira:
SENT (0.0161s) UDP 127.0.0.1:53 > 127.0.0.1:40125 ttl=64 id=64074 iplen=28
RCVD (0.0163s) ICMP 127.0.0.1 > 127.0.0.1 Port unreachable (type=3/code=3)
ttl=64 id=18756 iplen=56
Como podemos ver, o tráfego de ping UDP é destinado à porta UDP 40125
nos dois exemplos.

ICMP
Assim como o comando ping padrão, ao ser executado com privilégios de
usuário de root, o Nping usa o ICMP por default quando nenhum outro
protocolo estiver selecionado. A documentação afirma enfaticamente que
“qualquer tipo de mensagem ICMP pode ser criado”. Por exemplo, ao
redirecionar pacotes podemos solicitar um registro de tempo (time stamp),
gerar mensagens falsas de “destino inatingível” ou causar problemas em
outro sistema ou rede.
O leitor pode tentar o comando seguinte, logado tanto como um usuário
com privilégios de root quanto como um usuário-padrão:
# nping localhost
A diferença pode ser claramente vista pelo nível de detalhamento. A seguir
vemos o usuário-padrão, com poucos detalhes:
SENT (0.0027s) Starting TCP Handshake > localhost:80 (127.0.0.1:80)
RECV (0.0028s) Handshake with localhost:80 (127.0.0.1:80) completed
No exemplo seguinte, como usuário com privilégios de root, podemos ver
que foram fornecidas mais informações sobre o conteúdo do pacote ICMP.
O dado type=8 significa “8 Echo” de acordo com o RFC
(https://tools.ietf.org/html/rfc792), correspondendo ao esperado.
SENT (0.0152s) ICMP 127.0.0.1 > 127.0.0.1 Echo request (type=8/code=0)
ttl=64 id=31032 iplen=28
RCVD (0.0154s) ICMP 127.0.0.1 > 127.0.0.1 Echo reply (type=0/code=0)
ttl=64 id=18763 iplen=28

ARP
Há também a opção --arp, que permite experimentar o protocolo ARP
(Address Resolution Protocol – Protocolo de Resolução de Endereços).
Além de possibilitar ataques de envenenamento do cache ARP, vários tipos
de pacotes ARP podem ser criados. O agora obsoleto RARP (Reverse ARP)
era usado para a tradução de um endereço MAC em um endereço IP. O
RARP foi sucedido pelos protocolos BOOTP e DHCP, porém às vezes ele
ainda tem algum uso. Houve uma versão evoluída do RARP denominada
Dynamic RARP (DRARP), também suportada. Ela foi usada
principalmente pela Sun Microsystems próximo ao final do último milênio,
mas hoje é muito pouco usada. Há também suporte para solicitações
“InARP”, similar ao RARP, porém aplicada principalmente a redes frame
relay e ATM.
Finalmente, para complementar esses protocolos, pode ser acrescentado --
traceroute aos resultados para ajudar a determinar qual foi o caminho
tomado pelo tráfego, o que pode ser obtido consultando o endereço-fonte
dos pacotes “destino inatingível” enviados como resposta.

Opções de payload
Estando familiarizado com as opções do protocolo principal, vamos ver
como utilizar esse conhecimento recém-adquirido de forma produtiva. É
oportuno lembrar que o Nmap foi feito para atividades white hat e deve ser
usado desta forma, não para obtenção de vantagens ilegítimas.
Ferramentas dessa natureza podem causar muito tumulto.
Caso o leitor deseje acrescentar um payload (carga útil de dados) aos seus
pacotes de sondagem, há três variantes, conforme mostrado na Tabela 5.1.
Tabela 5.1 – Opções de payload e suas descrições
Opção Descrição
-- Alguns dados hexadecimais podem ser incluídos aqui. A documentação oferece exemplos
data como --data 0xdeadbeef e --data \xCA\xFE\x09
--
Uma string pode ser acrescentada, como --data-string "Per Ardua ad
data-
Astra"
string
-- Usando esta opção, um pacote com dados aleatórios entre 0 e 65.400 bytes pode ser
data- preenchido, como --data-length 999. É preciso estar ciente de que, se houver
lengthultrapassagem de 1.400 bytes, algumas MTUs na rede podem ser encobertas.

Modo Eco
Entre as sofisticadas funcionalidades incluídas no Nping está o modo Eco
(Echo mode), cuja finalidade é mostrar em detalhes o que ocorre com os
pacotes quando eles trafegam pela rede. Com a habilitação do modo Eco
em dois hosts, uma relação cliente-servidor pode ser configurada para
monitorar exatamente o comportamento durante uma troca de
informações.
Vamos dar uma olhada nesta funcionalidade. O servidor captura os
pacotes e envia os detalhes de volta para o cliente por um “canal” de
comunicações TCP. É tarefa do cliente gerar os pacotes mencionados.
Essa técnica é uma excelente forma de identificar qualquer pacote
mutilado, caso isso ocorra. E, por exemplo, caso a NAT (Network Address
Translation – Tradução de Endereços de Rede) estiver envolvida, diversos
detalhes de pacotes são também alterados. Pelo uso dessa técnica, caso um
dispositivo no sistema altere qualquer uma das opções TCP ou se houver
modelamento de tráfego, por exemplo, estes detalhes, que de outra forma
seriam de muito difícil diagnóstico, ficam aparentes. É possível também
determinar o ponto em que os pacotes em trânsito ficam misteriosamente
bloqueados, possibilitando o suporte a questões de diagnóstico.
Vamos fazer uma pequena experiência usando o modo Eco. A propósito, o
acréscimo de -vvv permite uma maior verbosidade caso deseje mais dados
na saída e um maior nível de detalhes do Nping. Para iniciar, o usuário
deve ter privilégios de root para atuar no lado servidor da conexão.
Devemos usar a senha “please_connect” (“conecte-se, por favor”) e
acrescentar verbosidade à saída recebida da interface de rede eth0 com o
seguinte comando:
# nping -e eth0 -vvv --echo-server "please_connect"
Os resultados desse comando são os seguintes:
Starting Nping 0.5.51 ( http://nmap.org/nping ) at 2016-11-16 11:16 GMT
Packet capture will be performed using network interface eth0.
Waiting for connections...
Server bound to 0.0.0.0:9929
Como podemos ver, o servidor está agora escutando um cliente em
conexão à porta TCP 9929.
Em seguida, devemos gerar algum tráfego acionando o cliente. Devemos
novamente observar que, neste caso, estamos usando no teste o localhost,
sua máquina local, tanto para o elemento servidor quanto para o elemento
cliente. Apesar de não ser a melhor forma de encaminhamento de tráfego
por um firewall ou um gateway NAT, isso oferece informações suficientes
para entender como o processo funciona.
Para rodar esse comando também é necessário ser um superusuário.
Devemos informar a senha apropriada e estar seguros de que a conexão foi
feita ao localhost. Evidentemente, esta opção pode ser substituída pelo
endereço IP da máquina remota à qual se deseja conectar da seguinte
forma:
# nping -vvv --echo-client "please_connect" localhost --tcp -p1001-1003
--flags ack
Como podemos ver, a conexão está sendo feita em três portas TCP (1001,
1002 e 1003) e em seguida aplicando nestas os pacotes TCP ACK. Se
houver dificuldades de conexão e for recebida uma mensagem de erro
“Handshake failed” (falha no handshake), a senha pode ter sido
incorretamente digitada em uma ponta.
Vamos ver o que ocorre em cada lado da conexão, começando pelo cliente.
Pelo acréscimo da opção -vvv, por um usuário com privilégios de root,
podemos ver o conteúdo dos pacotes quando estes trafegam pela rede; caso
contrário, a saída será muito mais quieta. A Listagem 5.2 mostra um
exemplo simplificado da visualização obtida.
Listagem 5.2 – Exemplo simplificado da saída de um cliente mostrando apenas um
pacote transmitido e um pacote recebido em vez de muitos pacotes
Starting Nping 0.5.51 ( http://nmap.org/nping ) at 2016-11-16 11:16 GMT
SENT (0.4256s) TCP [127.0.0.1:20869 > 127.0.0.1:1000 A seq=33133644
ack=4112791867 off=5 res=0 win=1480 csum=0x91F7 urp=0] IP [ver=4
ihl=5 tos=0x00 iplen=40 id=4058 foff=0 ttl=64 proto=6 csum=0x6cf4]
0000 45 00 00 28 0f da 00 00 40 06 6c f4 7f 00 00 01 E..(....@.l.....
0010 7f 00 00 01 51 85 03 e8 01 f9 94 4c f5 24 39 3b ....Q......L.$9;
0020 50 10 05 c8 91 f7 00 00 P.......
RCVD (0.4258s) TCP [127.0.0.1:1000 > 127.0.0.1:20869 R
seq=4112791867 ack=0 off=5 res=0 win=0 csum=0x2E11 urp=0] IP [ver=4
ihl=5 tos=0x00 iplen=40 id=0 flg=D foff=0 ttl=64 proto=6 csum=0x3cce]
0000 45 00 00 28 00 00 40 00 40 06 3c ce 7f 00 00 01 E..(..@.@.<.....
0010 7f 00 00 01 03 e8 51 85 f5 24 39 3b 00 00 00 00 ......Q..$9;....
0020 50 04 00 00 2e 11 00 00 P.......
^C
Max rtt: 0.085ms | Min rtt: 0.083ms | Avg rtt: 0.083ms
Raw packets sent: 4 (160B) | Rcvd: 4 (160B) | Lost: 0 (0.00%)| Echoed:
0 (0B)
Tx time: 3.23067s | Tx bytes/s: 49.53 | Tx pkts/s: 1.24
Rx time: 3.23067s | Rx bytes/s: 49.53 | Rx pkts/s: 1.24
Nping done: 1 IP address pinged in 3.66 seconds
Na Listagem 5.2, a saída foi resumida para a visualização de somente um
pacote “SENT” enviado pelo cliente à porta TCP 1000. Em seguida, o
cliente recebe uma resposta do servidor (recebimento, o que tem a
marcação “RCVD”) da porta TCP 1000 para a porta TCP 20869, uma das
portas efêmeras de numeração alta.
O ruído adicional, devido à opção -vvv, inclui a linha de checksum
(começando com csum) e as três linhas de conteúdo logo abaixo. O ^C
significa que a saída foi parada logo após o início, por questões de
concisão. E, assim como ocorreu com o comportamento do comando ping
padrão, são recebidos o rtt (Round Trip Times) e as estatísticas de
transmissão abaixo, seguidas de um prazo de execução geral.
No servidor (e também na máquina local, o que na realidade tem poucas
consequências), o Nping escuta na porta TCP 9929. A Listagem 5.3 mostra
a saída produzida no lado servidor.
Listagem 5.3 – Os pacotes enviados pelo cliente, vistos pela perspectiva do servidor
Starting Nping 0.5.51 ( http://nmap.org/nping ) at 2016-11-16 11:16 GMT
Packet capture will be performed using network interface eth0.
Waiting for connections...
Server bound to 0.0.0.0:9929
[1479294971] Connection received from 127.0.0.1:51099
[1479294971] Good packet specification received from client #0
(Specs=8,IP=4,Proto=6,Cnt=5)
[1479294971] NEP handshake with client #0 (127.0.0.1:51099) was
performed successfully
[1479294971] Client #0 (127.0.0.1:51099) disconnected
Na Listagem 5.3, o servidor informa “Good packet specification
received from client #0” (os pacotes recebidos do cliente #0 contêm
boas especificações) e também que um handshake foi concluído sem
qualquer problema, seguido de um instante Epoch (Epoch time stamp) do
momento da desconexão pelo cliente. Não há muito mais a coletar do lado
servidor, portanto é necessário somente fazer o login no cliente se o
servidor estiver sempre disponível para teste.
O projeto Nmap oferece de forma muito conveniente algumas máquinas de
teste para uso. A senha é “public” no caso do host “echo.nmap.org.”
Para varreduras Nmap (e não Nping), podemos tentar este host:
http://scanme.nmap.org.
Devido à grande popularidade da NAT (a conexão do leitor com a internet
provavelmente passa por pelo menos uma NAT em seu próprio roteador
doméstico), há uma boa chance de que as entradas CAPT sejam
visualizadas sob as linhas SENT e antes da próxima linha RCVD caso
aquela máquina seja solicitada. Este comando trabalha para mim:
# nping --echo-client "public" echo.nmap.org --tcp
Uma cuidadosa observação das entradas de pacotes capturados (captured
packet entries – CAPT) permite saber se a NAT alterou seu endereço da
fonte de saída. Poderemos um endereço IP privado, como o 10.10.10.10,
conforme o RFC 1918 (https://tools.ietf.org/html/rfc1918), sendo
alterado para mostrar um endereço IP roteado publicamente, como o
123.123.123.123 caso a NAT tenha sido envolvida. É relativamente fácil
detectar se a NAT está intrometida no meio da conexão. É necessário
lembrar que, onde a NAT estiver presente, por vezes poderão ocorrer
coisas como outros dispositivos alterando as MTUs (Maximum
Transmission Units – Unidades Máximas de Transmissão), mutilação de
pacotes em modelamento de tráfego, firewalls não previstos e switches
invisíveis, todos com potencial de causar mudanças sutis na conexão.
Há diversos outros cenários dentro dos quais o Nping pode auxiliar, como,
por exemplo (após algum aprendizado), ser capaz de detectar se proxies
transparentes podem ser empregados na rota. Mais adiante o leitor pode
avançar em seus conhecimentos, mas por enquanto vamos nos concentrar
na seção a seguir, que descreve algumas outras opções que podem ser úteis.

Outras opções Nping


Usando a opção --delay 10, é possível optar pela limitação da frequência
dos pacotes. O default é geralmente enviar pings com separação segundo a
segundo, porém o aumento deste valor pode reduzir o ruído na tela caso se
esteja concentrado fazendo uma observação de um evento em particular.
Na mesma linha está a opção --rate 3, em que uma máquina-alvo pode
ser inundada (“flooding”) pelo envio de três pacotes por segundo no
exemplo recém-citado. No entanto, não fique atrapalhado lutando contra
os ajustes das opções rate e delay. De acordo com a documentação:
estas opções [rate] e --delay são inversas; --rate 20 é o mesmo que -
-delay 0.05. Se as duas opções forem usadas, somente a última no
parâmetro é levada em conta.
A opção -H ou a --hide-sent pode ser utilizada quando não são
mostrados os pacotes enviados. Por exemplo, se houver flooding sendo
imposto a uma conexão, isso ajudará.
Além disso, no caso de a rede estar recebendo flooding e um teste estiver
sendo realizado para saber como é a resposta a uma carga significativa, é
provável que não desejemos processar cada pacote recebido. A opção -N ou
--no-capture não captura qualquer desses pacotes.
Muitas outras opções de linha de comando estão disponíveis para Nping.
Por exemplo, o acréscimo de --debug permite um maior detalhamento da
ajuda. As TTLs (Time To Live settings) podem ser alteradas. Caso muitos
hosts estejam sendo escaneados, podemos também desejar o acréscimo de
uma opção de temporização, de modo que o Nping nunca será deixado à
espera de uma resposta com --host-timeout 10, em que 10 é o valor em
segundos.
Mencionei brevemente a falsificação de endereços IP (spoofing) para forjar
o endereço IP de envio; o Nping pode ir um passo além e até mesmo
preencher o campo de envios com valores aleatórios, usando um comando
como o seguinte para atacar o host whitehat.chrisbinnie.tld:
# nping --arp --sender-ip random --ttl random whitehat.chrisbinnie.tld
Quando li pela primeira vez sobre essas funcionalidades, as campainhas de
alarme tocaram. A habilidade de falsificar um endereço IP com valores
aleatórios (e obter sucesso) deve causar preocupação a qualquer
administrador de sistemas. Basta que roteadores upstream com
configuração pobre permitam a esse tipo de tráfego atingir uma rede
corporativa.
Finalmente, caso deseje ajustar a forma como o canal é usado em modo
Eco, --channel-tcp ou --channel-udp farão exatamente isso:
# ping -vvv --client --channel-tcp 1234 --tcp -p 8100 localhost
Como o leitor pode estar imaginando, o fato de contar com a possibilidade
de ajustar o modo Eco para enviar os dados “canal” de volta para o cliente
via TCP e UDP pode ter o significado de salva-vidas no caso de um firewall
rigoroso estar no caminho.

Resumo
Se o Nping for experimentado de tempos em tempos, o leitor deve enfim
perceber que o relatório por ele fornecido é realmente longo. Encorajo-o a
usar o Nmap em qualquer oportunidade.
Com suas possibilidades de criação de pacotes, o poderoso Nping pode
superar a maioria de seus rivais. O acréscimo do sofisticado modo Eco
significa que, quando temos acesso às duas pontas de uma conexão, há
menos chance de um dispositivo escapar da detecção. Como resultado, a
pesquisa de problemas pode ser feita de forma mais ágil e com menor
dificuldade.
O poderoso Nping do projeto Nmap pode ser considerado como uma
ferramenta dentro de um kit de ferramentas white hat. Usando ferramentas
desse tipo dentro da lei, o leitor se destacará nas tarefas do dia a dia e,
como uma segunda possibilidade bem-vinda, aprenderá a manter seus
servidores funcionando de forma otimizada.
CAPÍTULO 6
Análise de logs

Às vezes, é necessário prestar especial atenção a quem está se conectando a


um servidor. Por exemplo, uma série de ataques pode ter ocorrido
recentemente, por isso mesmo queremos observar isso bem de perto, ou a
paranoia pode estar se manifestando no administrador de TI, devido ao
aspecto sensível dos dados ou à natureza crítica do serviço.
Uma abordagem de pouca sofisticação na monitoração das máquinas
agressoras que estão fazendo “campana” para observar seus servidores
poderia ser manter um registro (log) de todos os endereços IP externos que
estão disparando pings e traceroutes contra nós. O leitor pode até pensar
que as informações obtidas dessa forma não sejam muito usuais, porém
elas podem ser realmente importantes na construção de um quadro
mostrando quem realiza conexão aos servidores, quantas vezes isso ocorre
e quando. De forma comparável ao estudo de imagens de circuito fechado
de TV mostrando pessoas visitando um escritório, depois de algum tempo
percebemos quem não é um visitante usual ou alguém que não é esperado
em um determinado dia. Os arquivos de log são fantásticos porque, mesmo
sendo momentaneamente deixados de lado, pode ser feita uma nova
consulta para análise meses depois.
Caso, por qualquer razão, deseje manter olhos vigilantes nos servidores, o
truque usado para monitorar o sistema depende propriamente de duas
coisas, em minha opinião. Primeiro, é necessário contar com um daemon
confiável rodando em segundo plano (background), escutando como uma
sentinela; ele deve ser confiável no sentido de não introduzir uma condição
de corrida (race condition) nem provocar falha no servidor. Em segundo
lugar, a quantidade de logs gravados em disco deve ser mínima, de modo a
ser possível retornar a eles meses depois e encontrar a informação desejada
sem que o espaço em disco tenha sido esgotado pelos logs, gerando assim
outros problemas. Evidentemente, discos cheios com logs de ataque não
são uma situação desejada, a não ser que, obviamente, desejemos
provisionar um sistema de armazenamento de alta capacidade, além de ser
um entusiasta de arquivos de log verbosos.
Neste capítulo, veremos como fazer o registro das explorações de qualquer
invasor mal-intencionado que tenha visitado suas máquinas e também
como lutar contra problemas potenciais no protocolo ICMP (Internet
Control Message Protocol). O leitor também aprenderá como alguns
invasores no passado se aproveitavam da boa natureza do ICMP, obtendo
uma visão geral de como eram os ataques comuns antes de o ICMP ganhar
sua atual reputação de inseguro.

Equívocos no uso de ICMP


O tráfego gerado por pings e traceroutes usa o mal-afamado ICMP, com
UDP em menor grau em consultas DNS, se requeridas.
No entanto, vale mencionar que a criação do ICMP foi movida por muito
bons motivos, sendo ainda usado para tarefas bastante importantes na
operação diária da internet. Por exemplo, existe a necessidade de informar
aos dispositivos sobre o tamanho de suas Unidades Máximas de
Transmissão (Maximum Transmission Unit – MTU) para garantir a tráfego
sem problemas dos pacotes em links de rede heterogêneos. Como
resultado, depois da leitura das informações a seguir, o leitor não mais
cometerá um dos equívocos comuns praticados por administradores de
sistemas novatos: o bloqueio de todo o tráfego ICMP nos servidores.

tcpdump
Vamos dar uma olhada rápida nas opções de monitoração de pings e
traceroutes, que devem ser efetivas 24 horas por dia. Além do kit de
ferramentas útil do administrador de sistemas, devemos considerar a
poderosa ferramenta de farejamento de pacotes tcpdump. Há muito tempo
essa ferramenta tem sido utilizada para esmiuçar o tráfego de rede em
peças menores, com o objetivo de oferecer uma visão bastante
aprofundada do que está sendo transmitido.
No meu caso, por exemplo, quando desejo fazer um levantamento dos
pings ocorridos, utilizo o comando a seguir ao fazer um ping no meu
paranoico servidor a partir de outra máquina:
# /usr/sbin/tcpdump -i eth0 icmp and icmp[icmptype]=icmp-echo
No exemplo a seguir, mostrando os recursos de farejamento de pacotes
ICMP do tcpdump, os traceroutes também são detectados:
# /usr/sbin/tcpdump ip proto \\icmp
Como podemos ver no código a seguir, os pings dependem de perguntas e
respostas; no entanto, devido ao firewall paranoico do meu servidor estar
bloqueando certas partes do tráfego ICMP, um erro admin prohibited é
registrado quando os traceroutes aparecem.
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
17:06:47.925923 IP recce.chrisbinnie.tld > noid.chrisbinnie.tld: ICMP echo
request, id 21266, seq 1, length 64
17:06:47.925979 IP noid.chrisbinnie.tld > recce.chrisbinnie.tld: ICMP echo reply,
id 21266, seq 1, length 64
17:06:48.927871 IP recce.chrisbinnie.tld > noid.chrisbinnie.tld: ICMP echo
request, id 21266, seq 2, length 64
17:06:48.927921 IP noid.chrisbinnie.tld > recce.chrisbinnie.tld: ICMP echo reply,
id 21266, seq 2, length 64
17:06:49.928069 IP recce.chrisbinnie.tld > noid.chrisbinnie.tld: ICMP echo
request, id 21266, seq 3, length 64
17:06:49.928136 IP noid.chrisbinnie.tld > recce.chrisbinnie.tld: ICMP echo reply,
id 21266, seq 3, length 64
17:06:52.215139 IP noid.chrisbinnie.tld > recce.chrisbinnie.tld: ICMP host
noid.chrisbinnie.tld unreachable - admin prohibited, length 68
17:06:52.215179 IP noid.chrisbinnie.tld > recce.chrisbinnie.tld: ICMP host
noid.chrisbinnie.tld unreachable - admin prohibited, length 68
17:06:52.215194 IP noid.chrisbinnie.tld > recce.chrisbinnie.tld: ICMP host
noid.chrisbinnie.tld unreachable - admin prohibited, length 68
17:06:52.215210 IP noid.chrisbinnie.tld > recce.chrisbinnie.tld: ICMP host
noid.chrisbinnie.tld unreachable - admin prohibited, length 68
17:06:52.215220 IP noid.chrisbinnie.tld > recce.chrisbinnie.tld: ICMP host
noid.chrisbinnie.tld unreachable - admin prohibited, length 68
17:06:52.215231 IP noid.chrisbinnie.tld > recce.chrisbinnie.tld: ICMP host
noid.chrisbinnie.tld unreachable - admin prohibited, length 68
No trecho de código, um servidor denominado noid é objeto de sondagens
de um host chamado recce. O recce está verificando se o servidor está
online.

Iptables
O comando iptables, que usa o firewall embutido no kernel do Linux,
chamado Netfilter, pode ser também empregado:
# iptables -I INPUT -p icmp --icmp-type 8 -m state --state NEW,
ESTABLISHED, RELATED -j LOG --log-level=1 --log-prefix "Pings Logged "
Se o leitor estiver prestando atenção, deve ter notado o número 8 sendo
usado como valor para --icmp-type. Na Tabela 6.1, os códigos usados
pelo ICMP podem ser vistos. Mais informações podem ser obtidas na
página RFC (Request for Comments) em
https://tools.ietf.org/html/rfc792. De acordo com essa página, o
ICMP existe desde 1981 ou por volta disso, quando a internet ainda era um
animal exótico.
Tabela 6.1 – Códigos (tipos de mensagem) do ICMP retirados do arquivo-
fonte include/linux/icmp.h, presente no kernel do Linux
Tipo Código
0 Echo Reply
3 Destination Unreachable *
4 Source Quench *
5 Redirect
8 Echo Request
B Time Exceeded *
C Parameter Problem *
D Time stamp Request
E Time stamp Reply
F Info Request
G Info Reply
H Address Mask Request
I Address Mask Reply
Como reação ao uso do ICMP em ataques, o kernel do Linux foi sendo
alterado ao longo do tempo. Devido ao uso abusivo do ICMP, as funções
marcadas com um asterisco na Tabela 6.1 são limitadas por default nas
implementações modernas do kernel (desde o Linux 2.4.10).
No trecho de código seguinte, os endereços IP de fonte e destino
(SRC=10.10.10.200 e DST=10.10.10.10) envolvidos no tráfego ping estão
logados no arquivo /var/log/messages.
Feb 31 17:19:34 noid.chrisbinnie.tld kernel: Pings Logged IN=eth0 OUT=
MAC=00:61:24:3e:1c:ef:00:30:16:3c:14:3b:02:10 SRC=10.10.10.200 DST=10.10.10.10
LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=40978 SEQ=1
Feb 31 17:19:35 noid.chrisbinnie.tld kernel: Pings Logged IN=eth0 OUT=
MAC=00:61:24:3e:1c:ef:00:30:16:3c:14:3b:02:10 SRC=10.10.10.200 DST=10.10.10.10
LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=40978 SEQ=2
Feb 31 17:19:36 noid.chrisbinnie.tld kernel: Pings Logged IN=eth0 OUT=
MAC=00:61:24:3e:1c:ef:00:30:16:3c:14:3b:02:10 SRC=10.10.10.200 DST=10.10.10.10
LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=40978 SEQ=3
Se eu usasse o tcpdump ou o iptables para log do tráfego, teria muito
interesse em reduzir o tamanho dos arquivos de log. A primeira razão para
isso seria evitar que um atacante (de forma consciente ou não) causasse
problemas de espaço em disco devido à criação de pesados arquivos de log,
após a inundação de um servidor com tráfego ICMP. O segundo motivo
seria manter em valores mínimos os significativos níveis de ruído que os
logs geram, permitindo que as consultas possam ser rápidas e facilitando a
busca do que quer que estejamos querendo encontrar.
Supondo que, por questões de prudência e estabilidade do sistema, o leitor
não queira manter o tcpdump rodando em segundo plano o ano inteiro,
temos como alternativa usar o iptables para obter a informação desejada.
Vamos ver, a partir de uma visão geral mais elevada, como fazer para
eliminar o ruído de um log. Para efeitos de clareza, pode ser desejado
despejar os logs gerados pela atividade do agressor em um arquivo
separado do log do sistema (syslog).
Vou usar como exemplo o excelente rsyslog, um servidor de log do sistema
“rápido como um foguete” (mais informações podem ser encontradas em
www.rsyslog.com). O motivo dessa escolha é que o Red Hat e o Debian (e
seus muitos derivados) atualmente usam o rsyslog por default, portanto há
uma boa chance de o leitor ter acesso a ele.
Vamos dar outra olhada no exemplo de pings das iptables citado há pouco:
# iptables -I INPUT -p icmp --icmp-type 8 -m state --state NEW,
ESTABLISHED, RELATED -j LOG --log-level=1 --log-prefix "Pings Logged "
Vamos agora prestar mais atenção na opção --log-prefix, mostrada a
seguir:
--log-prefix "Pings Logged "
Caso deseje salvar todos os avisos do kernel em um novo arquivo de log,
isso é algo relativamente fácil de fazer. Abra o arquivo /etc/rsyslog.conf
e acrescente a seguinte linha na seção RULES ou próxima a ela (desde que
não exista ainda uma linha para kern.warning; caso exista, decida se deve
substituí-la ou acrescentar algo a ela):
kern.warning /var/log/iptables.log
Naturalmente, quando se trata de manipular arquivos de texto, uma
grande quantidade de resultados diferentes pode ser obtida com um script
rápido de shell (ou usando alguma ferramenta de linha de comando como
grep, awk ou sed). No entanto, com o objetivo de evitar problemas
temporários de espaço em disco, podemos tentar não fazer o log de todo
aviso do kernel no caso de uma peça de hardware começar a apresentar
comportamento indevido e registrar milhares de avisos em um curto
período de tempo.
Devemos agora criar um novo arquivo de configuração syslog e nomeá-lo
como /etc/rsyslog.d/iptables-pings-logging.conf. Esse arquivo
pode ser batizado da forma como desejar caso seu arquivo de configuração
principal (/etc/rsyslog.conf) importe o conteúdo de todos os arquivos
de configuração existentes na pasta. Por default, há uma entrada nesse
arquivo parecida com esta e que lê de uma só vez todos os arquivos de
configuração:
$IncludeConfig /etc/rsyslog.d/*.conf
No entanto, posso dizer que enfrentei problemas no funcionamento dos
filtros quando os obtive de um novo arquivo naquela pasta. Isso tudo
apesar de ter verificado as permissões e me certificado de que o syslog
remoto estava funcionando bem a partir de um dos arquivos (e tentando
startswith e regex em vez do operador contains a ser visto a seguir).
Caso o leitor se defronte com o mesmo problema, pode, em vez de
acrescentar as duas linhas seguintes ao novo arquivo de configuração em
separado, simplesmente navegar até a linha mencionando kern.* logo
abaixo de RULES no arquivo de configuração principal
(/etc/rsyslog.conf) e acrescentar estas duas linhas:
:msg, contains, "Pings" /var/log/iptables-pings.log
& ~
A primeira linha recebe entradas que incluem a string “Pings” e solicita ao
log do sistema a escrita delas no arquivo /var/log/iptables-pings.log.
A segunda linha não é muito usual e instrui o software do log do sistema a
ignorar qualquer entrada presente nas linhas anteriores para não ocorrer a
duplicação dos logs pela escrita do mesmo conteúdo em outro arquivo.
Evidentemente, é possível deixar essa segunda linha de fora se for também
desejado fazer o log em outro local.
Agora que o leitor está apto a colocar conteúdo em um arquivo de logs e
fazer a filtragem de eventos iptables específicos (acrescentando suas
próprias etiquetas se preferir), vamos ver outros exemplos.

Regras multipartes
Caso deseje que os servidores possam tanto receber pings quanto também
enviá-los, devemos levar em conta o fato de cada operação envolver
configurações de iptables ligeiramente diferentes.
A página a seguir explica como permitir pings direcionados a determinados
endereços IP do servidor (assumindo que haja mais de um IP configurado
na mesma placa de rede do servidor) junto com as diferentes configurações
de pings de saída: www.cyberciti.biz/tips/linux-iptables-9-allow-
icmp-ping.html.
Observe que o -d para destino nas regras de ping para tráfego entrante
significa um endereço IP específico.

Registro completo para análise forense


Caso esteja preocupado por estar experimentando um ataque e deseje
registrar todas as conexões entrantes de sua máquina, o comando a seguir
deve ser (brevemente) habilitado:
# iptables -I INPUT -m state --state NEW -j LOG --log-prefix "Logged Traffic: "
Esteja ciente de que o arquivo /var/log/messages ficará bem cheio em
pouco tempo, portanto pode ser necessário desabilitar o logging pela
remoção da regra o mais breve possível (mais adiante nesta seção há um
exemplo descrevendo como isso pode ser feito). Podemos esperar uma
saída parecida com a mostrada a seguir a partir do comando iptables:
Nov 11 01:11:01 ChrisLinuxHost kernel: New Connection: IN=eth0 OUT=
MAC=ff:ff:ff:ff:ff:ff:00:41:23:4f:4d:1f:08:00 SRC=10.10.10.10 DST=10.10.10.255
LEN=78 TOS=0x00 PREC=0x00 TTL=128 ID=28621 PROTO=UDP SPT=137 DPT=137 LEN=58
Esse trecho foi obtido do meu agora importante arquivo
/var/log/messages. O tráfego é apresentado como se fosse gerado por um
pacote Netbios. Basta fazer uma permuta entre INPUT e OUTPUT caso a
preferência seja rastrear o tráfego ocorrido.
A propósito, o que ocorre se desejarmos registrar os dados de tráfego,
porém impondo limitações à taxa de escrita nos logs do servidor? Aqui está
um exemplo:
# iptables -I INPUT -p icmp -m limit --limit 5/min -j LOG
--log-prefix "Blocked ICMP Traffic: " --log-level 7
A troca de -p icmp para -p tcp ou -p udp é muito simples, permitindo
trabalhar com os pacotes TCP e UDP, respectivamente. Esse exemplo
significa que somente cinco pacotes de logging estão trafegando por
minuto nesse tipo de tráfego. Isso pode ser útil porque, geralmente, as
primeiras poucas sondagens são informativas antes do início da repetição.
Eventualmente, se for descoberto que os logs são preenchidos muito
rapidamente, podemos fazer uma remoção de todas as regras iptables
como mostrado a seguir:
# iptables -F
# iptables -X
# iptables -t nat -F
# iptables -t nat -X
# iptables -t mangle -F
# iptables -t mangle -X
# iptables -t raw -F
# iptables -t raw -X
# iptables -t security -F
# iptables -t security -X
# iptables -P INPUT ACCEPT
# iptables -P FORWARD ACCEPT
# iptables -P OUTPUT ACCEPT
Minha preferência é colocar essa string de comandos em um script (ou em
aliases bastante longos do Bash, com os comandos separados por ponto e
vírgula) e, como usuário com privilégios de root, digitar flush sempre que
precisar de uma remoção de todas as regras firewall em uso, de forma
rápida e livre de falhas.

Hardening
Se o leitor estiver preocupado com sobrecargas no sistema causadas por
tráfego ICMP, há duas coisas relativamente simples que podem ser
verificadas. Isso é possível devido ao poder dos sistemas operacionais Unix.
Em primeiro lugar (e sua máquina já deve contar com este ajuste como
default), os broadcasts ICMP podem ser ignorados pelo acréscimo da linha
seguinte na parte inferior do arquivo /etc/sysctl.conf:
net.ipv4.icmp_echo_ignore_broadcasts = 1
Esse exemplo sysctl.conf mantém a reinicialização (reboot), ao passo
que o comando a seguir fará uma ativação imediata:
# echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
O próximo comando fará ativação imediata se o exemplo sysctl.conf foi
seguido (ele recarrega todos os ajustes de configuração existentes dentro do
arquivo sysctl.conf):
# sysctl -p
O ajuste icmp_echo_ignore_broadcasts interrompe os broadcasts ICMP
para que eles não derrubem a rede com tráfego broadcast indesejado.
Na realidade, este é um ataque obsoleto (os kernels modernos usam
limitação de taxa como padrão), e o ajuste do kernel só é realmente útil
para ataques ping direcionados ao endereço broadcast que estiver forçando
todos os dispositivos no domínio de broadcast da rede local a responder.
Se cada dispositivo responder ao mesmo tempo e responder também a
outras respostas, o excesso de tráfego na rede provocará uma negação de
serviço. Todavia, assim como para todos os ajustes de kernel, é
recomendável saber mais acerca do tema para auxiliar no entendimento de
como uma rede funciona.
Outro ataque (ocorrido em 1996) foi chamado de Ping of Death (ping da
morte) e gerou números colossais de pacotes ICMP com o objetivo de
derrubar a máquina remota. Ele afetou muitas das pilhas de rede populares
(18 sistemas operacionais se revelaram vulneráveis). Bastou apenas
conhecer um endereço IP e disparar pacotes ICMP com extensão maior
que 65.536 bytes para esse endereço, e a máquina visada entrou em
colapso. O excelente site Insecure.org, em
http://insecure.org/sploits/ping-o-death.html, contém mais
informações.
Outro ataque muito comentado no passado envolveu um homem no meio
(man-in-the-middle – MITM) e foi chamado de ataque smurf. Os ataques
smurf são um bom exemplo de como a falsificação (spoofing) funciona,
pertencendo a um tipo de ataque que recentemente se tornou mais
frequente, denominado ataque de amplificação (amplification attack).
O homem no meio fica em uma posição confortável, devido à
impossibilidade de identificar a fonte original do ataque. O objetivo do
ataque é provocar a saturação da largura de banda, causando ao final uma
negação de serviço. De forma preocupante, o bloqueio do tráfego ICMP
aparece na prática como originado pelas próprias vítimas. O homem no
meio (às vezes chamado também de amplificador) recebe esses pacotes
falsificados e envia uma resposta de eco normal para a vítima, que não tem
sequer como formular uma resposta. A vítima tem possibilidades reduzidas
de interromper a chegada dos pacotes. Nos primórdios da internet, o
provedor de serviços podia somente desabilitar todo o tráfego ICMP para
interromper o fluxo massivo de dados. Devido à falsificação dos pacotes,
mesmo a realização de logs pouco ajudava no rastreio visando identificar a
origem.
Uma solução para este problema é fazer com que os próprios pacotes
tenham a taxa limitada. Isso libera a recepção do tráfego ICMP,
possibilitando à rede uma operação relativamente normal, apesar de
possivelmente um pouco mais lenta.
Isso pode ser conseguido em hardware de roteadores proprietários, como
Cisco ou Juniper, e também em hosts individuais usando iptables com um
conjunto de regras similares a estas:
# iptables -I INPUT -p icmp -m limit --limit 30/minute --limit-burst 60
-j ACCEPT
# iptables -I INPUT -p icmp -m limit --limit 6/minute --limit-burst 10
-j LOG
# iptables -I INPUT -p icmp -j DROP
Pela configuração mostrada na primeira linha, a opção --limit-burst
permite a recepção inicial de até 60 pacotes antes da habilitação da
limitação de taxa de um pacote a cada segundo (o valor 30/minuto). A
segunda linha informa que devemos determinar (embora de forma bem
mais restrita) o volume de tráfego aceito antes de fazer log no sistema: seis
entradas por minuto após uma rajada de dez pacotes. Finalmente, esses
pacotes são descartados para mitigação de qualquer efeito danoso.
Se eu estiver entendendo a documentação da forma correta, o valor --
limit-burst é referente ao período especificado usado por --limit.
Quando esse limite não é atingido, --limit-burst recebe um incremento
– em outras palavras, com o valor um – a cada vez que o limite não é
alcançado, até o número configurado.
Resumo
Algumas das alterações exploradas podem ser danosas tanto para os
sistemas quanto para as redes. O leitor deve saber o que está fazendo (o
ideal é fazer experimentos em uma máquina de teste) antes de tentar
qualquer desses ajustes em sistemas em operação. Como mencionado, o
equívoco clássico de entrar em pânico pela má reputação do ICMP e com
isso banir todas as menções a este protocolo na rede é um procedimento
imprudente.
Foram estudados os ataques e a forma de evitar que eles afetem as
operações normais da rede e dos servidores. Foi também abordada a
limitação de taxa do tráfego ICMP entrante.
Além disso, foi estudada a análise de pings e traceroutes para identificar
qualquer invasão ocorrendo com objetivos ilícitos no servidor e, mais
importante, como direcionar essas sondagens indesejadas para um arquivo
específico para que um ataque não encha os discos com volumosos
arquivos de log.
Podemos dizer com segurança: o conhecimento adquirido será raramente
necessário, porém na próxima vez que alguém alegar ter bloqueado todo o
tráfego ICMP no servidor, o leitor olhará para ele como quem conhece o
assunto e afirmará estar confiante da ausência de problemas relacionados
com ICMP.
CAPÍTULO 7
O prodigioso NSE do Nmap

Mesmo administradores de sistema novatos provavelmente já ouviram falar


de escaneamento de portas em hosts locais e remotos e muitos até já
executaram essa tarefa. Eles também devem ter ouvido falar de um famoso
scanner de portas do mercado, criado pelo Nmap Project, denominado
Nmap. Nmap significa “Network Mapper” (Mapeador de Rede), e além de
ser super-rápido, sofisticado e eficiente, é repleto de funcionalidades.
Dentre suas muitas funcionalidades, ele pode descobrir qual é o sistema
operacional de um servidor remoto, fazer auditoria da segurança em
máquinas locais e remotas e criar um inventário das máquinas e dos
serviços ativos em uma rede.
É provável que no passado o leitor tenha usado o Nmap basicamente para
escaneamento de portas, porém há uma boa chance de não ter percebido o
grande poderio desta ferramenta em testes de penetração. Isso é devido
parcialmente ao seu sofisticado motor de script embutido. Antes de ver
isso, porém, devemos revisar a funcionalidade básica de escaneamento de
portas do Nmap. Com isso aprenderemos como o Nmap pode ser usado
para atividades white hat mais avançadas.

Escaneamento de portas básico


Mesmo as funcionalidades básicas (escaneamento de portas) existentes no
Nmap incluem opções avançadas, como a falsificação (spoofing) do
endereço IP de origem (usando a opção -S). Uma magnífica seleção de
funcionalidades está disponível. Inicialmente, porém, vamos começar com
a instalação do pacote.
Para instalar o Nmap em derivados do Red Hat, o seguinte comando pode
ser usado:
# yum install nmap
No Debian e suas distribuições derivativas, o comando pode ser:
# apt-get install nmap
Caso deseje usar Gerenciadores de Pacotes RPM em derivados do Red Hat
em vez de executar esses comandos, o leitor deve buscar mais informações
em https://nmap.org/book/inst-linux.html.
Se estiver familiarizado com o arquivo /etc/services em máquinas Unix,
a inclusão do arquivo /usr/share/nmap/nmap-services com o Nmap
pode ser interessante. Esteja ciente de que o local do arquivo pode ser
ligeiramente diferente. Dentro desse arquivo, os números de porta podem
ser vinculados a nomes de serviços compreensíveis para humanos –
parecido um pouco com o DNS localizado, suponho (como no arquivo
/etc/hosts em que há geralmente um formato chave:valor). Uma linha
na versão Nmap desse arquivo pode ser um tanto parecida com:
Service name Portnum/protocol Open-frequency Optional comments
ftp 21/sctp 0.000000 # File Transfer [Control]
ftp 21/tcp 0.197667 # File Transfer [Control]
ftp 21/udp 0.004844 # File Transfer [Control]
ssh 22/sctp 0.000000 # Secure Shell Login
ssh 22/tcp 0.182286 # Secure Shell Login
ssh 22/udp 0.003905 # Secure Shell Login
telnet 23/tcp 0.221265
telnet 23/udp 0.006211
Esse arquivo é útil porque ele pode ser editado para atender às atividades
Nmap sem causar desconfiguração acidental no arquivo da máquina local
/etc/services. A versão personalizada que o Nmap inclui acrescenta
também um pouco mais de detalhes aos dois campos normais do arquivo
local. Como pode ser visto nesse exemplo, há quatro colunas com as
descrições dos campos na parte superior.
Alguns chamam isso de mapeamento de portas, o que não é uma descrição
ruim. Caso esteja curioso, o campo open-frequency (frequência aberta) foi
preenchido com dados obtidos de uma extensa pesquisa online (realizada
executando um grande número de escaneamentos Nmap) e informa
quantas vezes a pesquisa encontrou aquela porta aberta. Esse arquivo de
configuração mais abrangente pode ser também uma útil referência para
quando estiver tentando fazer uma pesquisa de um determinado problema.
Vamos pedir para o Nmap rodar um escaneamento simples em uma
máquina? Isso pode ser feito com a execução de um escaneamento básico
de portas em um endereço IPv4 remoto. Neste exemplo é usada a opção -
PN para não incluir um teste ping, assumindo que temos conhecimento da
condição online da máquina (as versões mais antigas do Nmap usavam -P0
e -PN; para isso não gerar confusão, o significado é “descoberta de hosts”):
# nmap -PN 123.123.123.123
Os resultados devem ser um pouco parecidos com isto:
Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-16 11:16 GMT
Nmap scan report for www.chrisbinnie.tld (123.123.123.123)
Host is up (0.00051s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
22/tcp open ssh
Nmap done: 1 IP address (1 host up) scanned in 0.09 seconds
Podemos ver que 999 portas foram escaneadas por default, sem ter havido
solicitação ao Nmap para considerar quaisquer outras, e somente a porta
SSH estava escutando o host remoto.
Como podemos esperar, toda uma rede pode ser escaneada, conforme
mostrado a seguir:
# nmap -PN 123.123.123.0/24
Pela inclusão de -n nas opções, as consultas DNS podem ser desabilitadas
com a finalidade de acelerar os resultados e evitar detecção por servidores
DNS, o que caso contrário poderia gerar respostas às solicitações.
Se o interesse for no TCP, o Nmap pode fazer conexão a portas TCP
conforme mostrado a seguir:
# nmap -sT www.chrisbinnie.tld
Se houver interesse em operar com portas UDP, basta trocar de -sT para -
sU.
Como já mencionei, há simplesmente muitas e muitas opções a explorar,
mas antes do leitor ir para as que realmente lhe interessam, vamos ver duas
outras opções muito úteis, no meu entender.
Primeiro, se estiver escaneando a rede local, mas não desejar que certos
hosts sejam incluídos, a opção a ser usada é exclude file, como
mostrado a seguir:
# nmap 10.10.10.0/24 --excludefile /home/chrisbinnie/exclusions.txt
Se o caso for a necessidade de ignorar alguns servidores, a opção pode ser o
uso da seguinte sintaxe:
# nmap 10.10.10.0/24 --exclude 10.10.10.1,10.10.10.10, 10.10.10.100
Para escanear números de porta específicos, inserimos U para UDP e T para
TCP conforme mostrado a seguir:
# nmap -p U:53,T:0-1024,8080 10.10.10.111
Finalmente, caso deseje ver quais hosts estão ativados e rodando na rede
local, o comando a escolher é este (está sendo usada uma “descoberta” ou
escaneamento por ping, por isso o P):
# nmap -sP 10.10.10.0/24
Podemos esperar uma saída similar a esta:
Nmap scan report for mail.chrisbinnie.tld (10.10.10.10)
Host is up (0.028s latency).
Nmap scan report for smtp.chrisbinnie.tld (10.10.10.11)
Host is up (0.029s latency).
Em outras palavras, uma linha por host.

Motor de script do Nmap


O Nmap tem um conjunto altamente sofisticado de entranhas
tecnológicas. Ele chama seu motor de script de NSE (Nmap Scripting
Engine). Vou abordar alguns dos temas tratados por sua extensa
documentação e indicar quando o leitor pode usar algumas de suas
funcionalidades.
O extraordinário NSE foi projetado tendo em mente algumas poucas
funções-chave. Essas funções incluem descoberta de rede (na maioria das
vezes por meio de escaneamento de portas), serviço avançado de detecção
usando diversas assinaturas predefinidas, teste de vulnerabilidade (e
exploração) e, finalmente, detecção de backdoor.
O poder do NSE está em sua versatilidade e ele estende essa funcionalidade
oferecendo o acréscimo, como o nome sugere, de scripts que podem ser
escritos por qualquer pessoa usando a linguagem de programação Lua.
Para ativar o NSE pela linha de comando, basta lançar o binário nmap com
a opção --script= ou, alternativamente, a opção -sC.
A seguir há dois exemplos de escaneamento de portas com Nmap. O
primeiro não faz habilitação do NSE e o segundo o faz. Isso pode ser útil,
visto que o leitor se familiariza com as diferenças na saída. Na Listagem 7.1
podem ser vistos os resultados do primeiro comando. Observe que a
execução do comando é realizada não por meio do usuário com privilégios
de root, mas sim como um usuário-padrão.
Listagem 7.1 – Nmap realizando descoberta de rede, porém sem a habilitação do NSE
# nmap -p0-1024 -T4 localhost
Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-16 11:16 GMT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00049s latency).
Not shown: 1021 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
80/tcp open http
111/tcp open rpcbind
Nmap done: 1 IP address (1 host up) scanned in 0.11 seconds
Porém, na Listagem 7.2 podemos ver que o NSE foi habilitado, e neste caso
ele acrescenta uma visão valiosa nesta história.
Listagem 7.2 – A saída mais detalhada possibilitada pela descoberta de rede com o NSE
habilitado
# nmap -sC -p0-1024 -T4 localhost
Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-16 11:16 GMT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00054s latency).
Not shown: 1021 closed ports
PORT STATE SERVICE
22/tcp open ssh
| ssh-hostkey: 1024 d7:46:46:2d:fc:ad:9e:c7:25:d3:a1:96:45:4f:59:d9 (DSA)
|_2048 80:f2:29:c0:ee:a1:80:99:2e:7f:26:c3:b1:2d:c4:37 (RSA)
25/tcp open smtp
80/tcp open http
| http-methods: Potentially risky methods: TRACE
|_See http://nmap.org/nsedoc/scripts/http-methods.html
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
111/tcp open rpcbind
Nmap done: 1 IP address (1 host up) scanned in 0.16 seconds
Na Listagem 7.2 podemos visualizar a entrada adicional do NSE. Em
contraste com a Listagem 7.1, são também recebidos URLs para uma
pesquisa posterior dessas descobertas, mais detalhes de host (como a chave
de host SSH neste caso) e também comentários sobre o HTML, que o
Nmap não considera um HTML válido.
Modelos de temporização (timing templates)
Nas Listagens 7.1 e 7.2, foram solicitadas informações sobre portas na
faixa de 0 a 1.024 (que são as portas privilegiadas, portas de sistema ou
portas de superusuário dos sistemas Unix) usando a opção -p0-1024. A
opção -T4 não é na verdade um valor de tempo vencido de quatro
segundos, mas oferece em vez disso uma forma de ativar um template de
temporização específico usado pelo NSE. Quanto maior for o valor do
ajuste, mais rápido o Nmap roda; a faixa de valores disponíveis vai de 0 a
5.
Os valores no template de temporização são importantes e podem fazer a
diferença para o bem-estar emocional do leitor. Esses valores, entre 0 e 5,
significam as condições paranoica, traiçoeira, educada, normal, agressiva e
insana. As palavras podem também ser usadas no lugar dos números, caso
o leitor ache que assim fica mais fácil de lembrar.
Devido ao grande número de ajustes incluídos no NSE, o programador
principal percebeu a possibilidade de os usuários ficarem perdidos em
meio à complexidade, por isso introduziu modelos (templates) que podem
ser úteis.
O motivo principal dos templates serem tão importantes no uso do Nmap
é devido ao fato de que, quando o NSE roda em diversos hosts, ou em uma
grande rede ou em várias redes, o processo pode levar um tempo muito
longo para ser concluído. O leitor pode também descobrir informações
pouco interessantes (devido à boa configuração dos firewalls) e achar que
as tarefas parecem durar uma eternidade para ser concluídas.
Uma pergunta poderia ser feita: qual é a diferença entre os templates? Os
templates paranoico e traiçoeiro oferecem algum grau de detecção de
invasões mediante um sistema de detecção de intrusos (intrusion detection
system – IDS). O template educado baixa a velocidade do processo de
escaneamento para limitar não só a largura de banda usada nas duas
pontas da conexão, como também os recursos da máquina-alvo. A chave -
T3 não faz absolutamente coisa alguma; isso devido ao fato de o template
normal ser default e ser ativado de qualquer modo. O template agressivo,
usado na chave -T4 em um exemplo anterior, acelera o processo de
escaneamento e realiza testes relativamente mais rigorosos nos limites da
rede de alta capacidade. O último template, insano, assume que estamos
satisfeito com o equilíbrio entre alguma precisão nos resultados providos
pelo NSE e o tempo de execução. É necessário contar com uma rede
confiável e de alta capacidade para o uso desse modo de operação.

Categorização de scripts
Apesar de empregar um motor subjacente altamente sofisticado, o NSE foi
cuidadosamente projetado de modo que mesmo um usuário principiante
possa entender sua operação com relativa facilidade. Portanto, é possível
usar o NSE de imediato e sem necessitar de muita leitura prévia.
No entanto, para evitar ir além das próprias possibilidades, é aconselhável
saber como o NSE se refere aos diferentes scripts que usa. Quando um
script roda no NSE, uma varredura de portas geralmente é executada antes
ou durante sua execução, para verificar o estado atual da disponibilidade
de uma máquina-alvo na rede. Há também outras similaridades entre os
diversos scripts NSE, como consultas DNS e traceroutes.
A Tabela 7.1 mostra como o NSE categoriza seus scripts; há diversas
categorias a considerar.
Tabela 7.1 – Categorias de script do NSE
Categoria Descrição
Estes scripts contemplam métodos de autenticação e a forma de contorná-los – por
auth exemplo, x11-access, ftp-anon e oracle-enum-users. A categoria
bruta é destinada à força bruta e não para autenticação.
broadcastCaso precise fazer broadcast na rede local, este pacote de scripts deve ser utilizado.
Esta coleção de scripts é usada para aplicar força bruta em credenciais de
brute autenticação em um host remoto. Há disponibilidade de muitos deles em diferentes
protocolos.
Os scripts default são executados se as opções -sC ou -A forem usadas. Para usar
default
scripts específicos, substitua o default por --script=.
Para rastrear quem e o que está conectado a uma rede, todos estes scripts são
discoveryrelacionados com exames, por exemplo, de registros públicos, dispositivos
habilitados para SNMP e serviços de diretório.
Caso deseje testar uma vulnerabilidade ou (cuidadosamente) rodar scripts que
dos tenham a possibilidade de derrubar serviços, este conjunto é adequado para as
necessidades de negação de serviço.
exploit Para testar uma exploração com o objetivo de ver se ela tem chance de sucesso.
Esteja ciente de que, pela execução destes scripts, suas ações serão registradas por
outras partes. Isso porque, em seu conjunto, estes scripts podem atuar como uma
external solicitação de terceiros, como (por exemplo) uma pesquisa WHOIS, tornando-o
assim visível para o serviço WHOIS.
Estes scripts procuram bugs de software e falha de segurança por meio de injeção de
campos aleatórios dentro das solicitações enquanto uma busca é realizada. Eles
fuzzer gastam muito mais tempo que outras técnicas para localizar um servidor offline ou
encontrar algo de interesse.
Discriminados por pertencer a uma categoria incômoda, estes scripts representam
um alto risco quando são executados, o que os afasta da categoria segura. Alguns
intrusivedesses riscos incluem panes, saturação de largura de banda e exposição a
administradores de sistema em máquinas-alvo.
Os malwares conhecidos deixam alguns rastros no sistema, como backdoors ou
malware sinais de infecção. Números de porta não usuais e excentricidades de serviço são
pesquisados com scripts de malware.
Este conjunto de scripts tem menor potencial de ofender os administradores de
safe sistemas-alvo. Ainda assim, para evitar problemas não se deve confiar
completamente neles.
Estes scripts não podem ser selecionados diretamente porque são uma extensão da
version funcionalidade de detecção da versão do NSE. Podem ser executados se a opção de
detecção de versão (-sV) for usada.
Caso sejam descobertas vulnerabilidades, este conjunto emite alertas sobre elas; por
vuln outro lado, será gerado pouco ruído. Os exemplos são realvnc-auth-bypass
e afp-path-vuln.

Fatores de contribuição
Quando o conjunto de scripts default é usado, podemos ficar surpresos
com a forma como o poderoso NSE toma suas decisões. Não há limiares
ajustados; em vez disso ele chega a um tipo de pontuação (score) depois de
rodar com base nos critérios seguintes:
• Velocidade – As varreduras default são concluídas rapidamente, por
exemplo, de modo a não empregar força bruta.
• Utilidade – Se um script não produz resultados úteis, sua inclusão em
scripts default deve ser esquecida.
• Verbosidade – A saída resultante da execução de um script deve ser
sucinta. Da mesma forma, quando não há nada a informar, o silêncio é
uma virtude.
• Confiabilidade – Inevitavelmente, premissas e suposições são feitas
durante a operação de alguns scripts. No entanto, se há erros frequentes,
elas não podem rodar na categoria default.
• Intromissão – Se um script provoca o aparecimento repentino da polícia
na sua porta, ele é provavelmente muito intrusivo para o conjunto de
scripts default.
• Privacidade – Na mesma linha do conjunto externo de scripts, os scripts
default devem respeitar a privacidade e não revelar a presença do
operador.

Falhas de segurança
Agora que o leitor já viu a multiplicidade de categorias de script do NSE e
apreciou o significado da execução do conjunto de scripts default, vamos
executar alguns testes de penetração usando os novos conhecimentos
adquiridos e a abundância de scripts empacotados como padrão no Nmap.
Vamos rodar primeiro um teste de vulnerabilidade na máquina local desta
forma:
# nmap --script vuln localhost
Na Listagem 7.3 pode ser vista a saída desse comando, observando que os
scripts de vulnerabilidade somente foram habilitados usando a opção vuln.
Listagem 7.3 – O escaneamento de vulnerabilidade direta resultou em leituras
preocupantes
Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-16 11:16 GMT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00090s latency).
Not shown: 996 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
80/tcp open http
| http-enum:
|_ /icons/: Potentially interesting folder w/ directory listing
111/tcp open rpcbind
Nmap done: 1 IP address (1 host up) scanned in 1.18 seconds
Os resultados da Listagem 7.3 despertaram imediatamente meu interesse
quando vi a expressão “Potentially interesting folder” (pasta com potencial
interesse) no serviço RPC. Evidentemente, é possível que somente minha
máquina local possa interrogar a pasta /icons/ em referência, porém há
também a chance de isso ser algo a ser investigado (e de forma
relativamente urgente). Pelo firewall é possível bloquear totalmente a porta
TCP 111 ou paralisar o serviço para fazer a correção, a não ser que
estejamos cientes das regras de configuração responsáveis pela limitação do
acesso ao RPC.
Em vez de ir atrás de arquivos de configuração, meu primeiro teste para
corrigir este problema seria usar o netcat a partir de outra máquina para
interrogar a porta TCP 111 na tentativa de obter uma resposta. (O ncat
mais moderno, também escrito pelo projeto Nmap, é a minha versão
preferida ou, caso não esteja disponível, uso o comando telnet.)
Casualmente, se o NSE identificar uma vulnerabilidade conhecida, com
sorte será recebido um patch ID para servidores Windows ou algum outro
URL relevante, permitindo uma pesquisa posterior. Isso pode economizar
tempo na pesquisa de exploração online. Há uma boa chance de que, se o
NSE sinalizar de forma positiva, alguns poucos testes diferentes tenham
sido satisfeitos para chegar àquela conclusão; e, diferente de algumas
outras ferramentas, os resultados não podem ser desconsiderados sem
primeiro analisá-los.

Testes de autenticação
Vamos considerar quais seriam os resultados se mais alguém tivesse
executado o NSE do Nmap em minha máquina local, em busca de obter
autenticação. Claramente, minha máquina local tem permissões fracas (ao
falar com ela própria e não com um host remoto), porém esta forma de
teste ainda tem méritos educacionais. O comando a seguir faz exatamente
isso e procura ocorrências de script auth:
# nmap --script auth localhost
Os resultados desse comando revelam alguns dos testes executados pelo
NSE, como pode ser visto na Listagem 7.4.
Listagem 7.4 – Meus scripts de autenticação foram postos para trabalhar, novamente
em minha máquina local.
Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-16 11:16 GMT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00062s latency).
Not shown: 996 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
80/tcp open http
| http-brute:
|_ ERROR: No path was specified (see http-brute.path)
|_citrix-brute-xml: FAILED: No domain specified (use ntdomain argument)
| http-form-brute:
|_ ERROR: No uservar was specified (see http-form-brute.uservar)
| http-domino-enum-passwords:
|_ ERROR: No valid credentials were found (see domino-enum-passwords.username and
domino-enum-passwords.password)
111/tcp open rpcbind
Nmap done: 1 IP address (1 host up) scanned in 0.17 seconds
Olhando para os resultados mostrados abaixo dos números de porta na
Listagem 7.4, é possível ver que o Nmap claramente deseja mais
informações (de entradas diversas) e gerou três mensagens ERROR (erro)
nesse meio tempo. Algumas contas de usuário descobertas pelo NSE
podem ser visualizadas, dispostas sob uma seção como a “Host script
results” (resultados de script de host) ao final desta visualização caso
tenham sido obtidos nomes de usuário em função da execução da
solicitação, por exemplo, em um domínio Windows.

Descoberta
Considere o comando a seguir, para a obtenção de mais informações sobre
um host:
# nmap --script discovery localhost

Listagem 7.5 – Descoberta de muitas informações úteis sobre o host local.


Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-16 11:16 GMT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00070s latency).
Not shown: 996 closed ports
PORT STATE SERVICE
22/tcp open ssh
|_banner: SSH-2.0-OpenSSH_5.3
| ssh-hostkey: 1024 d7:46:46:2d:fc:ad:9e:c7:25:d3:a1:96:45:4f:59:d9 (DSA)
|_2048 80:f2:29:c0:ee:a1:80:99:2e:7f:26:c3:b1:2d:c4:37 (RSA)
25/tcp open smtp
|_banner: 220 mail.chrisbinnie.tld ESMTP Postfix
| smtp-enum-users:
| root
| admin
|_ Method RCPT returned a unhandled status code.
|_smtp-open-relay: Server is an open relay (16/16 tests)
80/tcp open http
| http-headers:
| Date: Mon, 16 Nov 2015 11:37:52 GMT
| Server: Apache/2.2.15 (Red Hat)
| Last-Modified: Mon, 15 Jun 2015 13:57:09 GMT
| ETag: "4bc-61-5188ed5743e6a"
| Accept-Ranges: bytes
| Content-Length: 97
| Connection: close
| Content-Type: text/html; charset=UTF-8
|
|_ (Request type: HEAD)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_http-date: Mon, 16 Nov 2015 11:37:52 GMT; 0s from local time.
| http-vhosts:
|_393 names had status 200
| http-enum:
|_ /icons/: Potentially interesting folder w/ directory listing
111/tcp open rpcbind
| rpcinfo:
| 100000 2,3,4 111/tcp rpcbind
|_ 100000 2,3,4 111/udp rpcbind
Nmap done: 1 IP address (1 host up) scanned in 11.51 seconds
Na Listagem 7.5 o leitor é abençoado, via scripts de descoberta (discovery
scripts), com a habilidade de recuperação de cabeçalhos HTTP, banners
SMTP, questões RPC, entre outras coisas. Apesar de o erro SMTP “Server
is an open relay (16/16 tests)” (O servidor é um retransmissor aberto
[testes 16/16]) ser apresentado, é como se fosse um falso-positivo, portanto
vale a pena fazer testes para conferir a veracidade disso.
Com todas essas funcionalidades incluídas, este modo é altamente útil e
representa uma parte fundamental da funcionalidade NSE. Afinal, o leitor
não pode explorar serviços sem saber de sua existência. A partir dos
resultados gerados pelo NSE, é seguro dizer que, quando o assunto é a
descoberta de máquinas e serviços, informação é poder. No entanto, o
sofisticado NSE não produz um bombardeio contendo excesso de detalhes,
entregando apenas o suficiente para ser útil.
O impacto negativo de executar scripts por categoria é que isso pode
causar uma pequena redução de desempenho se todos os scripts forem
incluídos em uma única categoria. No entanto, isso sem dúvida significa
falta de confiança no sistema de pontuação usado pelo conjunto de scripts
default ou na execução de todos os scripts disponíveis em um template. No
entanto, a concentração será muito maior se o leitor estiver apenas olhando
para um tipo específico de informação.

Atualização de scripts
Como podemos imaginar, os scripts personalizados escritos para o NSE
usando a linguagem Lua são frequentemente melhorados e aumentados.
Caso deseje atualizar seus scripts NSE, o leitor pode fazê-lo de forma
seletiva baixando-os e copiando-os em uma pasta, de maneira similar ao
caminho mostrado a seguir, em sistemas Unix:
/usr/share/nmap/scripts
Caso haja o acréscimo ou a remoção de scripts da pasta scripts ou se a
categoria de um script foi alterada, é necessário posteriormente executar o
comando a seguir (como usuário com privilégios de root):
# nmap --script-updatedb
É esperada uma saída como esta:
Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-16 11:16 GMT
NSE: Updating rule database.
NSE: Script Database updated successfully.
Nmap done: 0 IP addresses (0 hosts up) scanned in 0.14 seconds
Para baixar scripts do site Nmap, podemos clicar no link Scripts no painel
Categories em https://nmap.org/nsedoc/lib/nmap.html.
Na época da elaboração deste livro, havia cerca de 500 scripts a considerar,
cada um deles contendo informações relacionadas à sua funcionalidade.

Tipos de script
Vale mencionar que, dentro da infraestrutura subjacente do NSE, há
quatro tipos de script suportados:
• Prerule scripts (scripts pré-regra) – Como podemos imaginar, são scripts
executados na partida e antes que qualquer escaneamento seja iniciado.
Por exemplo, podemos desejar a realização de consultas DNS reversas
em uma lista de endereços IP antes de examiná-los.
• Host scripts (scripts de host) – Durante processos de escaneamento
padrão (ou seja, após descoberta, escaneamento de portas, detecção de
versão e detecção do sistema operacional), esses scripts são executados
no alvo.
• Service scripts (scripts de serviço) – Se o NSE identifica um serviço, ele
pode executar nele esses scripts. Por exemplo, há mais de 15 scripts
HTTP que podem rodar em servidores web.
• Postrule scripts (scripts pós-regra) – Rodam assim que o NSE tiver
concluído suas tarefas de escaneamento e a tendência é se concentrar na
forma como os resultados são fornecidos. Como já foi dito, a concisão é
importante, pois a verbosidade pode causar confusão.
A documentação abrangente do Nmap (encontrada em
https://nmap.org) destaca a explicação que diz: “[m]uitos scripts
podem potencialmente rodar como pré-regra ou pós-regra. Nesses casos, é
recomendável usar pré-regra por razões de consistência”.

Expressões regulares
A familiar linha de comando inteligente do NSE pode também lidar com
expressões regulares (regex). Por exemplo, mencionei os 15 scripts HTTP;
para incluir todos esses scripts em uma execução, um comando como o
mostrado a seguir deve ser executado em um servidor web alvo:
# nmap --script "http-*"
Podem também ser feitas decisões booleanas da forma mostrada a seguir
(exatamente o que seria de esperar com regex):
# nmap --script "default or safe"
Por sorte esse comando é suficientemente fácil de entender. A
documentação também apresenta este exemplo mais complexo:
# nmap --script "(default or safe or intrusive) and not http-*"
Aqui é possível ver que desejamos habilitar o default, seguro, e categorias
de script intrusivas, porém não as utilizadas em servidores web.

Interfaces gráficas de usuário


A título de informação, é possível também salvar os resultados (que se
forem muito extensos podem rolar com muita rapidez no console) em uma
pasta na forma usual, como pode ser visto neste exemplo, para sistemas
Unix:
# nmap -sC -p0-1024 -T4 localhost > /home/chrisbinnie/output.txt
No entanto, a forma como o NSE salva os resultados é mostrada a seguir,
com resultados em texto simples:
# nmap -T5 localhost -o outputfile.txt
A informação também pode ser fornecida em XML:
# nmap -T5 localhost -oX outputfile.xml

Zenmap
Há ocasiões, especialmente quando lidamos com muitas máquinas-alvo em
diferentes redes, que se torna necessário obter alguma ajuda com os
resultados. Imagine o leitor poder colocar os resultados em um banco de
dados, podendo assim pesquisar padrões comuns com facilidade em
escaneamentos históricos.
O Zenmap (https://nmap.org/zenmap/) representa um passo adiante. Na
qualidade de interface gráfica de usuário (Graphical User interface – GUI)
oficial do Nmap, o bem projetado Zenmap é também gratuito e apropriado
para usuários de todos os níveis. Um criador de comandos é incluído para
suporte na elaboração de comandos complexos e para possibilitar a
capacidade de pesquisar dados históricos por meio de um banco dados. É
também possível criar perfis para comandos frequentemente executados,
evitando a necessidade de redigitá-los continuamente.
Esta ferramenta gráfica multiplataforma altamente útil é disponível para
Linux, BSD, Mac OS, Windows, entre outros sistemas.
Outra funcionalidade muito bacana é poder executar um diff e depois
comparar os resultados de duas varreduras para, de forma muito fácil,
descobrir o que ocorreu entre elas.
Para usuários realizando escaneamentos frequentes, e logicamente para
qualquer usuário novato em segurança, o Zenmap é a escolha preferencial.
Os usuários de todos os níveis de experiência descobrem que a curva de
aprendizado é consideravelmente menos traumática se o Zenmap for usado
primeiro. A Figura 7.1 mostra o que pode ser esperado com o uso do
Zenmap gráfico em um Desktop Manager no Linux.

Resumo
Neste capítulo foram abordados alguns aspectos da funcionalidade básica
do Nmap, introduzidas e explicadas as diferentes categorias de script do
NSE, discutidos os tipos de scripts usados pelo Nmap e explorados os usos
de uma interface gráfica de usuário para afastar a complexidade inicial de
tarefas repetitivas. Naturalmente, não posso deixar de mencionar outra vez
que a interface gráfica de usuário também auxilia em análises.

Figura 7.1 – Um exemplo do Zenmap em ação, obtido da homepage do


Zenmap (https://nmap.org/zenmap/). Copyright 2015 Insecure.Com LLC
Há centenas de opções, bem como cenários white hat e black hat, que o
Nmap suporta e encoraja a experimentar. É importante aprender como os
atacantes podem abordar um sistema, mas também saber como usar essas
poderosas ferramentas com cuidado e respeito.
Afinal de contas, derrubar servidores alheios não tem lá muita graça. O
desafio maior para um responsável por um sistema é evitar que outras
pessoas derrubem os servidores sob sua responsabilidade, e o resultado
disso é uma satisfação muito maior (e completamente legal).
CAPÍTULO 8
Detecção de malware

O termo malware (software malicioso) engloba uma ampla faixa de


softwares indesejados criados para danificar computadores. Uma lista
parcial de malwares pode, por exemplo, incluir vírus, spywares, cavalos de
Troia e worms. A rápida proliferação deste tipo de software é o suficiente
para causar preocupação a usuários de todos os níveis, de novatos a
administradores veteranos. O impacto dos malwares vai desde brincadeiras
essencialmente inofensivas até o roubo de informações pessoais, dados
bancários e negação de serviço.
Apesar do alarmismo sensacionalista que acomete nossa combalida e
tendenciosa imprensa, todo bom administrador de sistemas entende não
existir nada melhor que um sistema completamente seguro. Apesar do
gigantesco número de ameaças de vírus e malwares visando máquinas
Windows, todos os usuários de máquinas baseadas em Unix, como o
Linux, devem levar em conta as ameaças também existentes para esses
sistemas.
Um sofisticado e popular pacote de software denominado LMD – Linux
Malware Detect (detecção de malwares para sistemas Linux), da R-fx
Networks (https://www.rfxn.com), ajuda na mitigação de ameaças de
malware em sistemas Linux. Vamos ver como as máquinas Linux podem
ser protegidas contra malwares usando o pacote LMD, que se concentra
somente em malwares, diferentemente de outras soluções mais diluídas.

Para começar
Antes de começar a avaliação do LMD em si, vamos considerar alguns
aspectos potencialmente menos óbvios do que é necessário para manter
qualquer software anti-malware funcionando corretamente e com sucesso.
Frequência de atualização das definições
É fundamental que as atualizações de assinaturas de malware sejam
realizadas frequentemente; de fato, o seu sistema pode ficar vulnerável caso
a última atualização não tenha sido feita. A arquitetura intrínseca do
software de detecção é de pouca valia se as ameaças mais recentes não
forem detectadas. Felizmente, o LMD frequentemente providencia ele
próprio suas atualizações, das quais gera assinaturas de dados
comunitários, submissões de usuários e dados de firewall sobre ameaças
ativas de malware.
O site LMD oferece um feed RSS das últimas ameaças, oferecendo também
uma versão paga, outro incentivo para que as atualizações sejam atuais e
relevantes. O feed, repleto de achados de malware correntes coletados pelo
LMD, pode ser encontrado em https://www.rfxn.com/feed/.
O site do LMD afirma que as assinaturas recebem uma atualização
praticamente diária, ou com uma frequência maior caso uma intensa
atividade seja constatada.

Registro de hashes de malware


Um site de segurança muito respeitado denominado Team Cymru
(www.team-cymru.org/MHR.html) mantém um Registro de Hashes de
Malware (Malware Hash Registry). Este registro oferece um serviço de
consulta para comparação de infecções por malware. De acordo com o site
LMD, mais de 30 das maiores empresas de antivírus usam esses dados para
compor seus bancos de dados. O site LMD informa o número atual de
ameaças relatadas, como mostrado a seguir:
DETECTED KNOWN MALWARE: 1951
% AV DETECT (AVG): 58
% AV DETECT (LOW): 10
% AV DETECT (HIGH): 100
UNKNOWN MALWARE: 6931
O site LMD prossegue e explora algumas das pontuações usadas para
medir identificações positivas e as falhas de outros produtos de detecção de
malwares, resultando em uma conclusão preocupante.
Usando o registro de hashes de malware do Team Cymru, podemos ver
que, dos 8.883 hashes de malware contidos no LMD 1.5, 6.931 deles
(78% das ameaças) não foram detectados pelos 30 produtos comerciais
de antivírus e malwares. As 1.951 ameaças efetivamente detectadas
tinham uma taxa média de detecção de 58% com limites de detecção
inferior e superior de 10% e 100% respectivamente. Não há uma
referência clara à necessidade de um projeto de correções de malwares
aberto ou promovido pela comunidade priorizando o horizonte de
ameaças em ambientes multiusuário compartilhados.
Como podemos ver nesse trecho do site, ocorre um número significativo de
falhas entre os produtos comerciais de detecção de malwares. O objetivo
do LMD é, onde for possível, preencher esta lacuna do mercado, sendo
também um defensor das discussões abertas e da colaboração,
compartilhando os detalhes do conhecimento sobre as ameaças entre os
fabricantes.

Ameaças prevalentes
Quando este livro estava sendo escrito, o LMD alegava manter 10.822
assinaturas de malware em seu banco de dados. Olhando para o conteúdo
da Figura 8.1, podemos ver uma lista das 60 ameaças mais prevalentes
contidas no banco de dados do LMD. Como esperado, a linguagem de
script no lado servidor mais popular em todo o mundo, a PHP
(https://www.php.net), é um vetor de ataque comum. A poderosa
linguagem Perl também aparece com destaque.

Funcionalidades LMD
O conjunto de funcionalidades do LMD está longe de ser trivial. Na Figura
8.2 podem ser vistas as funcionalidades relacionadas em sua
documentação.
Figura 8.1 – Os 60 ataques mais prevalentes de acordo com o LMD.
Figura 8.2 – A considerável lista de funcionalidades oferecidas pelo LMD.
É possível dizer que, além da detecção inteligente de ameaças, o LMD atua
na combinação de relatórios abrangentes com a colocação das ameaças em
quarentena, entre diversas outras funcionalidades. A facilidade em receber
relatórios resumidos diariamente via email por meio de uma tarefa cron é
claramente útil para transmitir segurança em relação ao funcionamento do
sistema de detecção conforme o esperado. Adicionalmente, a capacidade
do LMD em se conectar ao Apache e monitorar diretamente os uploads de
arquivos dos usuários será abordada mais adiante. Caso esta seja a única
forma usada pelo usuário para obter arquivos em um sistema, ela é
claramente uma escolha à prova de balas.

Monitoração de sistemas de arquivos


Um método moderno de observar alterações em sistemas de arquivos é o
uso do inotify. Para que ele funcione corretamente é necessário um kernel
compatível. Não se preocupe, pois o inotify deve estar incluído nos kernels
a partir da versão 2.6.13, portanto a maioria das construções Linux deve
ter esse recurso.
O sofisticado inotify pode monitorar, em tempo real, tanto arquivos únicos
quanto diretórios completos em busca de alterações, emitindo alertas ao
software configurado se qualquer mudança for descoberta. Caso perceba
que uma peça de software no espaço do usuário contenha alterações, o
inotify considera isso um evento e informa imediatamente.
Pela criação de uma watch list (lista de acompanhamento), o inotify pode
manter o rastreio dos watch descriptors (descritores de acompanhamento)
únicos associados a cada item em sua lista. Apesar de o inotify não
informar detalhes sobre o usuário ou sobre o processo responsável pelas
alterações em um arquivo ou diretório, o simples fato de saber que uma
alteração ocorreu é suficiente para satisfazer à maioria das aplicações. Se o
inotify não estiver disponível, pode ser empregada também a clássica
abordagem de fazer um polling em um sistema de arquivos ou realizar uma
varredura manual. No caso de pesquisar alterações em sistemas de
arquivos em rede, qualquer software configurado deve recorrer ao polling
do sistema de arquivos usando uma frequência predeterminada. Isto
porque o rastreio em sistemas de arquivos remotos é mais difícil.
Infelizmente, os pseudossistemas de arquivos, que incluem /proc, /sys e
/dev/pts, não são visíveis ao inotify. Porém, isso não deve ser causa de
muita preocupação porque os arquivos “reais” não existem nesses
caminhos, mas sim as tarefas efêmeras de um sistema, caracterizadas por
mudanças frequentes.

Instalação
Vamos ver agora a instalação do LMD, tanto em derivados do Debian
quanto Red Hat. Primeiro, devemos verificar se o pacote wget está
instalado. No caso do Red Hat é o seguinte comando:
# yum install wget
A alternativa para o Debian é:
# apt-get install wget
Muitas distribuições incluem o wget por default, portanto isso talvez não
seja necessário.
Para obter o máximo do LMD, também podemos instalar o inotify-
tools caso desejemos que o LMD realize interface direta com o inotify.
Mais informações e o download do inotify-tools podem ser obtidos de
https://github.com/rvoicilas/inotify-tools/wiki.
No entanto, para fazer esta instalação a partir do seu gerenciador de
pacotes, caso tenha sorte e use um “filho” do Red Hat, o leitor pode usar
este comando:
# yum install inotify-tools
E, em máquinas da linhagem Debian, o comando a executar é:
# apt-get install inotify-tools
Se isso não funcionar em seu sabor Debian, tente o procedimento a seguir.
Sei que isso funciona porque quis comprovar a facilidade de instalação do
LMD no Ubuntu 14.04 LTS. Precisei acrescentar o repositório Universe
para ter sucesso na instalação do pacote inotify-tools em meu arquivo
/etc/apt/sources.list, como segue:
deb http://us.archive.ubuntu.com/ubuntu trusty main universe
A palavra “trusty” pode ser mudada para “precise” ou outro nome de
versão do Ubuntu caso esteja usando outros sabores. As listas de pacotes
podem ser então atualizadas com o seguinte comando:
# apt-get update
O comando Ubuntu final pode ser simplesmente como este:
# apt-get install inotify-tools
Vou deixar para o leitor experimentar igualmente com repositórios Debian
(substituindo “trusty” pelo nome da versão apropriada no Debian).
Como o pacote LMD não estava disponível em nenhum repositório na
época da elaboração deste livro, ele pode ser baixado e instalado da
seguinte forma:
# cd /usr/local/src/
# wget http://www.rfxn.com/downloads/maldetect-current.tar.gz
# tar -xzf maldetect-current.tar.gz
# cd maldetect-*
# sh ./install.sh
Após rodar o script install.sh, como mostrado na última linha de
comando, será apresentada uma tela com um conteúdo que inclui o
seguinte:
Linux Malware Detect v1.5
(C) 2002-2015, R-fx Networks <proj@r-fx.org>
(C) 2015, Ryan MacDonald <ryan@r-fx.org>
This program may be freely redistributed under the terms of the GNU GPL
installation completed to /usr/local/maldetect
config file: /usr/local/maldetect/conf.maldet
exec file: /usr/local/maldetect/maldet
exec link: /usr/local/sbin/maldet
exec link: /usr/local/sbin/lmd
cron.daily: /etc/cron.daily/maldet
maldet(6617): {sigup} performing signature update check...
maldet(6617): {sigup} local signature set is version 2015112028602
maldet(6617): {sigup} latest signature set already installed
Os caminhos de instalação escolhidos certamente podem sofrer variações
caso o script install.sh tenha sido editado (a variável inspath em
particular). Como podemos ver, também é incluída uma nota informando
o status da atualização das assinaturas LMD.

Modos de monitoração
Com o pacote já instalado, vamos ver o que o LMD pode monitorar em um
sistema. Uma boa forma de começar é considerar os modos de
monitoração do LMD.
O LMD oferece diversos modos de monitoração que podem ser
configurados para verificar diferentes partes de um sistema de arquivos.
Como será visto, o LMD usa o executável binário denominado Maldet,
forma abreviada de “malware detect” (detecção de malwares).
Para monitorar um componente do sistema, pode ser usada a opção -m,
também grafada como --monitor. O que o LMD pode monitorar pode ser
decomposto entre usuários, arquivos e caminhos. O site apresenta o
exemplo seguinte de como os três modos podem aparecer na linha de
comando:
# maldet --monitor users
# maldet --monitor /root/monitor_paths
# maldet --monitor /home/mike,/home/ashton
Pelo uso da primeira opção, --monitor users, o LMD faz a monitoração
de qualquer identificador único (unique identifier – UID) no sistema que
estiver acima de um ajuste UID mínimo (a opção de configuração a ser
ajustada no arquivo de configuração é chamada de notify_minuid).
O segundo exemplo é um arquivo, /root/monitor_paths, que pode
conter os arquivos cuja monitoração é desejada (um item por linha).
No caso da terceira opção, poderíamos criar uma única linha de comando
extensa, com uma lista de caminhos de sistema de arquivos separados por
vírgula dos itens que queremos monitorar.
A Figura 8.3 mostra o resultado da execução do seguinte comando:
# maldet -m /home/ubuntu

Figura 8.3 – O que é mostrado quando se pede para o LMD monitorar um


caminho específico.

Configuração
O arquivo de configuração principal do LMD é
/usr/local/maldetect/conf.maldet. Ele é bem comentado e muito útil
para compreender como o LMD prefere ser ajustado.
Todavia, um alerta antes de continuar: o arquivo de configuração do LMD
não usa asterisco como caractere curinga, mas sim um ponto de
interrogação. Portanto, o caractere ? pode ser usado no lugar de * para
substituir caracteres múltiplos em uma opção de configuração. Apesar
dessa pequena ressalva, o uso é relativamente simples.

Exclusões
Vamos ver como fazer os ajustes no LMD. A documentação começa
perguntando ao usuário quais elementos do sistema ele deseja ignorar. No
mesmo estilo adotado para os modos de monitoração recém-estudados, há
arquivos que podem ser preenchidos com dados para conseguir isso. Cada
entrada nos arquivos de configuração a seguir deve estar contida em sua
própria linha.
No arquivo seguinte podemos acrescentar caminhos completos de arquivos
que não desejamos que o LMD verifique:
/usr/local/maldetect/ignore_paths.
Podemos também excluir globalmente uma extensão de arquivo específica
colocando uma entrada do tipo .jpg neste arquivo:
/usr/local/maldetect/ignore_file_ext.
Por uma razão ou outra, certas assinaturas LMD podem levar a linhas
desnecessárias e de pouca utilidade nos arquivos de log. Determinadas
assinaturas podem ser desabilitadas pelo acréscimo de uma linha do tipo
php.mailer.10hack a este arquivo:
/usr/local/maldetect/ignore_sigs.
A última opção de exclusão significa que podem ser usadas expressões
regulares (regex) sofisticadas para compatibilizar de uma só vez múltiplos
caminhos do sistema de arquivos. Basta acrescentar uma lista ao arquivo
/usr/local/maldetect/ignore_inotify, que usa um formato como:
^/home/premium-user-$
Evidentemente, com o uso de regex, as possibilidades de compatibilização
de arquivos são inúmeras, podendo ser usadas para evitar a realização de
alterações manuais na configuração no caso de um novo usuário receber
permissão para se logar no servidor. Esse exemplo de regex ressalta que um
conjunto específico de usuários pode receber um nome, com o formato de
nome de usuário nas linhas premium-user-123456.

Execução a partir da CLI


As opções de interface de linha de comando CLI (Command Line
Interface) para o LMD são bem-conceituadas e relativamente fáceis de
seguir. Vou deixar que todas elas sejam exploradas pelo leitor, porém agora
é necessário estudar algumas das opções-chave.
Como já havia mencionado, o binário executável do LMD é chamado de
maldet. Vamos começar rodando o LMD em segundo plano (background)
enquanto ele verifica um caminho de sistema de arquivos em particular.
Pelo exemplo da documentação a seguir, podemos ver como rodar, em
segundo plano, varreduras potencialmente extensas usando -b:
# maldet -b -r /home/?/public_html 7
Nesse exemplo, -b é usado para varredura em segundo plano e para
verificação de arquivos que foram alterados ou modificados nos últimos
sete dias, período configurado pelo acréscimo do caractere 7. A sintaxe e a
forma opcional de rodar esse comando é --scan-recent PATH DAYS.

Relatórios
Vamos fazer uma verificação rápida na forma como o LMD gera seus
relatórios. A Figura 8.4 mostra um relatório produzido.

Figura 8.4 – Relatório de uma varredura do LMD usando o comando maldet


–report.
Para obter relatórios específicos, é necessário um SCANID. Esta é a única
referência visualizada próxima à parte superior da Figura 8.4, em que este
comando é executado para fornecer um relatório do último comando
LMD:
# maldet --report
Tendo esse ID, o relatório pode ser enviado manualmente por email para o
próprio emitente, da maneira seguinte:
# maldet -e, --report SCANID chris@binnie.tld
Para interrogar um SCANID específico, com um registro de tempo (time
stamp) formatado incluído dentro do nome (neste exemplo, 010116 é a
data e o restante corresponde ao horário), o comando pode se apresentar
de forma parecida com esta:
# maldet --report 010116-1111.21212
Estas opções também podem ser úteis se usadas com a opção --log ou -l:
# maldet --log
Os eventos de log do LMD podem ser visualizados ao rodar esse comando.
Em meu caso, apesar de ter rodado somente uns poucos comandos até
agora, há um número de detalhes relativamente grande em meu arquivo de
logs. Com esse comando, são mostradas as últimas 50 linhas do arquivo
/usr/local/maldetect/logs/event_log. Esse arquivo pode ser
consultado posteriormente caso seja necessário descobrir informações além
do mostrado nessas 50 linhas. Em minha opinião, o nível de detalhes
obtidos pelo LMD é outra indicação de que ele é um pacote bem elaborado
e sofisticado.

Quarentena e limpeza
A documentação ressalta que o LMD, por default, não atua quando
encontra arquivos suspeitos (evil-look files). Portanto, é importante
entender que, na maioria dos casos, o malware deve ser posto em
quarentena manualmente.
Caso esteja certo de que deseja habilitar a quarentena automática, isso
pode ser feito ajustando a opção de configuração quar_hits=1 no arquivo
de configuração principal, residente por default em
/usr/local/maldetect/conf.maldet.
Caso deseje colocar em quarentena todos os malwares obtidos em uma
varredura específica, devemos usar a opção -q, que é igual a --quarantine
SCANID:
# maldet -q 010116-1111.21212
Caso tenha havido um engano, os arquivos em quarentena podem ser
recuperados de um SCANID específico usando o comando a seguir, que é
igual ao da função --restore:
# maldet -s 010116-1111.21212
Um erro como o mostrado a seguir é visualizado caso nada exista a
recuperar:
maldet(18748): {restore} could not find a valid hit list to restore.
Se desejar que o LMD tente corrigir as infecções por malware por ele
descobertas, o comando a ser usado é o --clean, também grafado como
opção -n. A seguir é mostrado um exemplo de comando para limpeza de
malware encontrado em um SCANID em particular:
# maldet -n 010116-1111.21212
Para uma limpeza ser considerada bem-sucedida, a varredura resultante
após a limpeza de uma infecção de malware deve ocorrer sem que haja
registro de HIT de um arquivo problemático.
Caso haja dúvidas em relação aos resultados ou não estiver seguro de que
as alterações de configuração funcionaram da forma correta, pode ser feita
uma purga de todos os dados de sessão, logs e arquivos temporários
existentes usando o seguinte comando:
# maldet -p
O resultado deve ser similar a:
maldet(19219): {glob} logs and quarantine data cleared by user request (-p)

Atualização do LMD
Como disse no começo deste capítulo, a atualização das assinaturas LMD é
de importância primordial. Para fazer manualmente uma atualização,
devemos usar a opção de comando -u. Caso o leitor esteja se perguntando,
saiba que ao fazer isso é feita conexão ao site rfxn.com para baixar os
dados. Pode ser feita tentativa manual com -u, ou seu equivalente --
update, desta forma:
# maldet -u
Os resultados esperados devem ser parecidos com:
maldet(19278): {sigup} performing signature update check...
maldet(19278): {sigup} local signature set is version 2015112028602
maldet(19278): {sigup} latest signature set already installed
Há também um mecanismo inteligente para a atualização da versão
atualmente instalada, também via rfxn.com:
# maldet --update-ver
Isso pode ser abreviado para -d caso deseje, e os resultados desse comando
serão parecidos com:
maldet(19357): {update} checking for available updates...
maldet(19357): {update} hashing install files and checking against server...
maldet(19357): {update} latest version already installed.
Execução e parada de varreduras
Na Figura 8.1 foram vistos os resultados da monitoração de um caminho
em particular com a opção -m ou --monitor. Vamos dedicar um tempo a
isso visando um melhor entendimento.
Imagine que seja desejado monitorar duas partições de sistema de arquivos
em particular, devido aos usuários terem a capacidade potencial de
escrever dados nelas. A monitoração dos caminhos pode ser feita da
seguinte forma:
# maldet -m /usr/local,/home
Observe a vírgula separando os caminhos. A saída para rodar esse
comando é mostrada na Figura 8.5. Devemos lembrar que varreduras
extensas podem usar a opção background -b, como visto anteriormente.

Figura 8.5 – O que é visualizado quando o LMD inicia a monitoração de


duas partições de sistema de arquivos com inotify habilitado.
Vamos ver como fazer a varredura manual de um diretório e seus
subdiretórios sem o uso do modo background. Imagine que os usuários
estão enviando arquivos via FTP ou SFTP a um diretório de upload:
# maldet -a /home/?/uploads
Nesse exemplo, o LMD é usado para fazer uma varredura do diretório
uploads de todos os usuários com um diretório home (lembrando
novamente que o ponto de interrogação é o caractere curinga no LMD, não
o asterisco).
Além da conclusão da execução do comando de varredura, é também
oferecido um SCANID para referência futura, conforme podemos ver nos
dados gerados:
maldet(28566): {scan} scan of /home/*/uploads (1 files) in progress...
maldet(28566): {scan} 1111/1111 files scanned: 0 hits 0 cleaned
maldet(28566): {scan} scan completed on /home/*/uploads: files 1111,
malware hits 0, cleaned hits 0, time 11s
maldet(28566): {scan} scan report saved, to view run: maldet --report 151212-
1724.28566
Caso qualquer varredura demore mais que o esperado, o LMD pode
acomodar também este cenário. A chave kill ou a opção -k (também com a
grafia alternativa --kill) interrompe qualquer instância inotify sendo
rastreada. Na ocorrência de uma carga da máquina muito alta ou havendo
a suspeita de algo não estar se comportando como deveria, isto é um
acréscimo útil às opções disponíveis.

Tarefa cron
O LMD inclui uma funcionalidade de tarefa cron (cron job) diária,
localizada em /etc/cron.daily/maldet. Ela atualiza as assinaturas e
limpa os dados de varredura, mantendo essas informações por até quatorze
dias, rodando também uma varredura diária usando a configuração
especificada.
Observe que os dados de sessão e os arquivos temporários são mantidos
entre as execuções de tarefa cron. Como resultado, é necessário executar a
opção -p anteriormente mencionada para purgar esses arquivos caso
suspeitemos da exatidão dos resultados.
Os parâmetros de configuração de email devem ser ajustados para
possibilitar o recebimento de relatórios diários a cada manhã. A
atualização diária é importante por razões de arquivamento dos emails e
para garantir que as varreduras possam ocorrer diariamente e não sejam
sujeitas a falhas.

Relatórios de malware
O grau de sofisticação e a concepção aprimorada do LMD são
funcionalidades bem conhecidas, portanto não é surpresa que o LMD
contenha um mecanismo simples para gravar arquivos suspeitos para
análise. No caso de arquivos evidenciando conter alguma variedade
desconhecida de malware, novas assinaturas podem ser criadas e
acrescentadas à lista de ameaças conhecidas do LMD, visando a divulgação
desse malware para outros usuários. O método usado para enviar arquivos
de volta ao LMD para verificação é mostrado a seguir, usando a
funcionalidade --checkout, também grafada com a opção -c:
# maldet -c suspicious_file.gz
Quando esse comando é executado, o arquivo é enviado para rfxn.com e
analisado em um momento oportuno.

Integração com Apache


Anteriormente neste capítulo, fiz uma breve alusão a uma funcionalidade
inteligente incluída no LMD: a capacidade de integração do LMD com o
módulo Apache mod_security2. A documentação LMD explica que ela
usa a maleável funcionalidade de hook inspectFile do módulo Apache
para a habilitação da execução de um script de validação, determinante
para decidir se um upload deve ser aceito ou não. Assim, por exemplo, no
arquivo de configuração do Apache, a entrada mostrada a seguir pode ser
visualizada, extraída da documentação:
SecRequestBodyAccess On
SecRule FILES_TMPNAMES "@inspectFile /usr/local/maldetect/hookscan.sh" \
"id:'999999',log,auditlog,deny,severity:2,phase:2,t:none"
Por projeto, cada upload de um arquivo realizado por um usuário pode ser
escaneado automaticamente, o que pode reduzir significativamente o
número de ameaças em um sistema, especialmente nos casos de muitos
usuários transferindo arquivos com frequência.
A documentação inclui detalhes de como o desempenho e a exatidão foram
consideradas nas opções default. Caso haja interesse nessa funcionalidade,
encorajo o leitor a consultar o arquivo incluído README para mais
informações.

Resumo
Além de tratar do LMD, abordei o mecanismo inotify que ele usa para
verificar as alterações no sistema de arquivos. O inteligente e eficiente
inotify realiza verificações de malwares em tempo real sem introduzir
cargas significativas no sistema.
Com os smartphones Android atualmente respondendo por cerca de 80%
do mercado global, não há muitas dúvidas de que os malwares produzidos
para explorar vulnerabilidades nesses dispositivos deverão futuramente
afetar também em alto grau os dispositivos de usuários Linux, o mesmo
ocorrendo com os servidores.
Com a adoção de testes de sistema de arquivos em tempo real pelo uso de
ferramentas sofisticadas como o LMD, os riscos de infecções por malwares
devem ser significativamente reduzidos. O LMD foi inicialmente concebido
para atender servidores de hospedagem compartilhada porque seu criador
levou em conta um vetor de ataque que normalmente é ignorado por
outros produtos: a conta de usuário. Geralmente, os produtos de detecção
de malware do mercado focam infecções de kernel e rootkit.
Supondo que o leitor instalou primeiro o LMD em um ambiente de testes e
se familiarizou com a forma como ele opera, entendo que definitivamente
vale a pena usar o LMD em máquinas em produção.
CAPÍTULO 9
Quebra de senhas com Hashcat

Duas sofisticadas ferramentas de segurança me chamaram a atenção


recentemente. Elas foram colocadas em destaque pela imprensa porque
foram liberadas com código-fonte aberto, aparentemente causando um
frenesi no GitHub pela forma como os desenvolvedores olharam para o
código-fonte da ferramenta. As ferramentas em questão são chamadas de
Hashcat e oclHashcat. A Hashcat (https://hashcat.net/hashcat), de
forma ousada, refere-se a si própria como “a mais rápida ferramenta de
recuperação de senhas do mundo baseada em CPU”. Sua parente próxima,
a oclHashcat, usa GPU (Graphics Processing Unit – Unidade de
Processamento Gráfico) para recuperar senhas por meio de processamento
intensivo de dados (number crunching), em contraponto à Hashcat que
opera baseada em CPU. Como resultado, a oclHashcat é ainda mais rápida
quando comparada com a Hashcat.
Enquanto ferramentas como essas podem ser muito úteis para recuperação
legítima de senhas perdidas, elas também podem ser usadas para
finalidades ilícitas. É desnecessário dizer que essas poderosas ferramentas
devem ser usadas de forma responsável. Elas são empregadas por cientistas
forenses e testadores de penetração, porém, se forem encontradas
evidências de ferramentas similares em uma máquina, isso pode ser o
suficiente para disparar um alarme.
Vamos ver como essas ferramentas trabalham para salvar o dia caso uma
senha seja perdida e também a maneira como um hacker opera para atacar
suas senhas.

História
Outra ferramenta de segurança popular e venerável usada para ripar senhas
é chamada de John the Ripper, de origem um tanto antiga. A Hashcat
entrou em cena em 2009, tomando a iniciativa de usar CPU multitarefa
para realizar quebra de senhas. À época, apesar de outros desenvolvedores
de ferramentas terem começado a considerar o uso de todos os núcleos
disponíveis de uma CPU, nenhum deles foi capaz de fazer isso de forma
plena e sem patchings (correções). Durante o desenvolvimento da Hashcat,
percebeu-se que fazia todo sentido tirar vantagens da capacidade das
modernas CPUs e com isso agilizar significativamente o processo de
recuperação de senhas.
Para evitar confusão: a Hashcat originalmente passou por alguns nomes
diferentes em seus primeiros releases, como atomcrack e Dr. Hash. A partir
da versão 0.30, o nome Hashcat, pelo qual é agora conhecida, foi aplicado
ao software (e tenho certeza de que conhecendo-a melhor, o leitor vai
começar a amar essa ferramenta).

Compreensão das senhas


Pode ser útil ver como os sistemas de senha funcionam. No meu caso, vou
usar sistemas Linux antes de continuar detalhando a Hashcat.

Keyspace
É importante compreender o conceito do que é o keyspace em criptografia.
O termo tem certa relação com a quantidade de esforços despendidos por
uma ferramenta de quebra de senhas.
O keyspace é basicamente o conjunto de teclas disponíveis usadas na
geração de uma determinada chave. O NIST (National Institute of
Standards and Technology – Instituto Nacional de Normas e Tecnologia)
descreve keyspace como “o número total de valores possíveis que uma
chave, como uma senha, por exemplo, pode conter”.
Ele continua: “Um componente de keyspace usado em senhas comuns é o
conjunto de caracteres (Character Set) usado para formar a chave”.
Em outras palavras, em uma senha podem ser usados somente os
caracteres existentes no teclado (ou o conjunto de caracteres encontrados
localmente em uma determinada aplicação), sendo que eles representam o
keyspace da senha.
Até mesmo um caractere único pode ter um keyspace de dez caracteres se
ele for um número, indo de zero a nove.
A segurança de uma senha pode ser aprimorada aumentando tanto o seu
comprimento quanto o tamanho do conjunto de caracteres. Assim, por
exemplo, uma senha com 16 caracteres que usa um conjunto de caracteres
com tamanho de 10 caracteres tem um keyspace de
10.000.000.000.000.000, tornando-a muito mais difícil de atacar quando
comparado com o keyspace de 10 caracteres de um único caractere.
Este site útil pode encorajar o leitor a aumentar a segurança de suas senhas:
https://howsecureismypassword.net.
Esse site, ao mesmo tempo simples e sofisticado, usa termos básicos e
discute as possíveis combinações levando em conta o keyspace. Após
informar a senha, um clique no link SHOW DETAILS (Mostrar detalhes)
sob a caixa de entrada1 faz o site mostrar o nível de segurança dessa senha.
Por exemplo, a tela apresentou as seguintes informações depois que
informei uma senha de somente um caractere:
Length 1 characters
Character Combinations 10
Calculations Per Second 4 billion
Possible Combinations 10
Vamos agora para uma parte muito preocupante para o leitor. A poderosa
ferramenta de senhas do site “How Secure Is My Password” (Quão segura é
minha senha) informa que o tempo necessário para quebrar a senha do
dígito por mim informado é de aproximadamente 0,0000000025 segundos
em um computador desktop convencional. Imagine então a rapidez disso
quando estiver sendo usada a capacidade de processamento resultante do
uso combinado de muitas placas de vídeo.
Por outro lado, tentando ser um pouco mais inteligente, vamos ver o que
acontece no exemplo seguinte quando é usada uma senha de 16 caracteres.
Casualmente, estou usando o conjunto de caracteres default do meu
computador, portanto neste caso o conjunto com 10 caracteres de
comprimento citado não é aplicável.
A senha digitada foi uma combinação de caracteres alfabéticos maiúsculos
e minúsculos, números e caracteres especiais, mostrada a seguir:
Rx951&RTdIp-"2YT
Nesse caso o site respondeu com um tempo mais reconfortante para
conseguir a quebra: 412 trilhões de anos. Como podemos ver na tela
seguinte, alguns novos vocábulos foram incluídos (for me – para mim; at
least – pelo menos). Aparentemente, a palavra “nonillion” (nonilhão) é um
número seguido de 30 zeros nos Estados Unidos e de 54 zeros no Reino
Unido.
Length 16 characters
Character Combinations 96
Calculations Per Second 4 billion
Possible Combinations 52 nonillion
Desse exemplo, podemos depreender claramente que uma senha
“complicada” padrão com comprimento de oito caracteres é preferida em
vez de usar uma senha única de um caractere.

Hashes
Agora que foi mostrado como uma senha complexa pode aumentar
drasticamente o esforço envolvido em um ataque, vou continuar minha
explanação sobre quebra de senhas. No entanto, é necessário primeiro uma
última explicação.
Como o nome sugere, a Hashcat lida com hashes de senha. A criação de
um hash em criptografia envolve a conversão de uma string de caracteres,
como uma senha, em um número determinado de caracteres, resultando
em algo análogo a uma impressão digital. Não há como desfazer ou
reverter um hash (bem, é possível fazê-lo na prática, porém é muito, muito
difícil).
Aqui estão dois exemplos MD5. Primeiro, o hash para a palavra “hello” é:
5d41402abc4b2a76b9719d911017c592
Segundo, o hash MD5 para “Hello” com inicial maiúscula é:
8b1a9953c4611296a827abf8c47804d7
Como podemos ver, a mudança de um único caractere de minúsculo para
maiúsculo fez uma enorme diferença.
Agora, se usarmos outra palavra, “Hello There,” fica assim:
32b170d923b654360f351267bf440045
O hash MD5 de duas palavras tem o mesmo comprimento do exemplo
anterior, com uma única palavra. Sabendo que seus hashes têm sempre o
mesmo comprimento, é possível dizer se uma string de caracteres
aparentemente não relacionados atende a um padrão.
Da mesma forma, pense por um segundo sobre por que não
criptografamos senhas em um servidor Linux e depois descriptografamos o
arquivo de senhas do sistema quando um usuário faz login. A resposta é:
simplesmente porque o processo de criptografar dados pode ser revertido,
enquanto uma função de mão única (one-way function) é preferível
quando comparada com a criptografia de uma senha. Algumas pessoas
ficam surpresas ao saber que o arquivo /etc/shadow efetivamente não
lembra uma senha de usuário, apenas de uma versão de hash temperado
(salted hash) dela.
Por que uma entrada no arquivo de senhas /etc/shadow do Linux é
apresentada desta forma? À primeira vista, ela se parece com alguma forma
de criptografia.
chrisbinnie:$6$TRIYWb5l$ef6Tm54qpV2nYCn6f20b7w/
5nvp8zpsjacFqeTwqx7fCeW3plG2pkKsGgf1CtWzWhHOPWykFGrfPGmCde4HWY/
:12231:3:32:11:32::
O usuário chrisbinnie tem uma entrada muito extensa porque a Shadow
Suite está usando um salt para reforço posterior das senhas. Depois de um
usuário introduzir uma senha em um sistema Linux, por default, um salt é
usado.
No pacote de criptografia do Linux, por exemplo, salt é uma string de dois
caracteres escolhida de um conjunto de caracteres. Pode ser qualquer um
deles no conjunto de caracteres da língua inglesa (a-z, A-Z, 0-9./). Tendo
escolhido um tempero, o algoritmo original usado para o hash da senha de
usuário é então “perturbado” de 4.096 formas diferentes. O tempero é
então salvo na senha codificada.
Por um momento, vamos pensar um pouco mais sobre senhas Linux. Os
modernos sistemas Linux aumentam a segurança de suas senhas com
senhas Shadow. Antes, as senhas eram armazenadas no arquivo
/etc/passwd, que podia ser lido por todos os usuários de um sistema. No
entanto, somente o root pode ler o arquivo /etc/shadow, e isso torna
possível a aplicação adequada de outras políticas, como o envelhecimento
de senhas.
O processo de login de usuário funciona desta forma. Quando alguém se
loga em uma máquina, o salt da entrada relevante desse usuário no arquivo
/etc/shadow é lido. Em seguida, a senha digitada pelo usuário é codificada
com o tempero que acabou de ser lido. Os resultados desse processo são
checados em relação à senha salva em /etc/shadow. Caso elas sejam
idênticas, o acesso é permitido ao usuário. Simples e inteligente2.
Uma forma comum de ataque a uma lista de senhas é o conhecimento
antecipado dos hashes de um conjunto de senhas corriqueiras e a
combinação destas com os 4.096 valores de salt disponíveis. Isso é
conhecido como ataque de dicionário.
Já foi citado que, hoje em dia, o mínimo estritamente necessário para a
especificação de um sistema de senhas seguras deve incluir um algoritmo
hashing atualizado, e o hash resultante deve ser temperado. Os populares
algoritmos modernos de hashing incluem SHA256, SHA512, whirlpool,
tiger, ripemd e SHA3. Cada um deles apresenta sutis diferenças em seus
atributos.
Esses algoritmos não devem ser confundidos com os algoritmos
criptográficos como os 3DES, Triple DES, Crypt, Blowfish e Rijndael.

Uso da Hashcat
A Hashcat, flexível e bem projetada, inclui uma extensa lista de hashes e
wordlists para experimentações. Vamos ver como trabalhar com tudo isso.

Capacidades da Hashcat
A abordagem geral das ferramentas de quebra de senhas (password-
cracking tools) consiste em importar um arquivo de senhas cheio de dados
criptografados e em seguida gerar um arquivo de saída resultante do
processamento do arquivo de entrada. Vamos ver algumas das opções
disponíveis na ferramenta Hashcat. As outras ferramentas disponíveis na
suíte de software serão abordadas em um momento oportuno.
A Hashcat suporta diversos tipos de algoritmos de hashing, como MD5,
SHA1 e NTLM. Na realidade, se meus cálculos estiverem corretos, o
número ultrapassa inacreditáveis 90 variedades. A Hashcat alega que pode
quebrar as versões MD5 de aplicativos populares como o WordPress,
Cisco-ASA e Drupal 7. Além do seu impressionante suporte a algoritmos,
os muitos e diferentes modos de ataque disponíveis incluem força bruta,
ataques de dicionário, ataques baseados em regras (rule-based) e ataques
de impressão digital (fingerprint).

Instalação
Quando este livro estava sendo escrito, a versão da Hashcat era a v2.003.
Para instalar a Hashcat (supondo não encontrá-la nos repositórios das
distribuições), o leitor pode ir para o site e baixar os últimos binários. O
link direto para a v2.00 é este: https://hashcat.net/files/hashcat-
2.00.7z.
O link para a versão 2.00 está no alto da página em
https://hashcat.net/hashcat/. Nessa página, deve ser feita uma
verificação para assegurarmos que a última versão disponível está sendo
baixada.
Após o download, é necessário somente extrair o arquivo .7z e assegurar-
se de possuir a permissão correta para escrever arquivos no diretório do
qual os arquivos foram extraídos. Caso tenha havido problemas durante a
extração de qualquer derivativo Debian, o pacote 7za pode ser então
instalado usando o seguinte comando:
# apt-get install p7zip-full
Em derivados do Red Hat, pode ser necessário adicionar um repositório.
Feito isso, o comando a seguir deverá trabalhar para você:
# yum install p7zip p7zip-plugins
Em seguida, para extrair os arquivos compactados e preservar os nomes de
diretório com x, rode o arquivo 7za com:
# 7za x hashcat-2.00.7z
Observe a falta do sinal de menos antes do x, o que corresponde à
convenção usual. Isso não é um erro de digitação.
Tendo feito isso, podemos agora usar cd no diretório hashcat-2.00/
recém-criado, o qual contém muitos arquivos e subdiretórios. Os diretórios
docs e examples são de particular interesse, que o leitor pode explorar à
vontade. Não se preocupe, pois daqui a pouco será explicado como rodar o
executável Hashcat.
A propósito, caso o leitor esteja interessado na última versão de
desenvolvimento, pode acessar a página GitHub em
https://github.com/hashcat/hashcat. Ela inclui também
documentação e links para o wiki, o que pode ser interessante.
Se o leitor estiver rodando a sofisticada suíte de testes de penetração Kali
Linux, está habilitado a instalar a Hashcat da maneira mostrada a seguir,
graças ao fato de ela estar incluída:
# apt-get install hashcat

Identificação por hash


Há duas coisas a considerar antes de usar a Hashcat. É necessário primeiro
saber o tipo de hash que estamos tentando recuperar da senha.
Vamos por um momento pensar sobre senhas de usuário Linux. O
algoritmo hash default em uso sofreu mudanças periódicas ao longo do
tempo e pode também ser dependente da distribuição. No passado, os
defaults comuns eram MD5 e DES, porém agora o SHA512 está muito
presente.
Ele ajuda a Hashcat caso seja possível identificar o tipo de hash sendo
atacado. O comando seguinte pode ser executado para descobrir qual
algoritmo de hashing está em uso:
# authconfig --test | grep hash
Caso esteja preocupado com a segurança da máquina e deseje fazer uma
atualização do algoritmo de hashing usado pelas senhas Shadow, pode usar
o seguinte comando:
# authconfig --passalgo=sha512 --update
Nesse exemplo, sha512 pode ser substituído por sha256 caso desejado.
Porém, observe que, para essa alteração se tornar efetiva, é necessário
convencer os outros usuários a trocar suas senhas, de modo a convertê-las
para o novo tipo de hash. Uma senha de usuário pode expirar de forma
forçada, obrigando o usuário a alterá-la no próximo login. Para isso, o
seguinte comando deve ser usado:
# chage -d 0 chrisbinnie
O comando “change age” nesse exemplo empurra a data de expiração para
1º de janeiro de 1970, garantindo que ela sempre será anterior ao ajuste
atual do relógio do sistema.
Vamos nos ater ao meu exemplo de entrada /etc/shadow, usando
novamente o usuário chrisbinnie:
chrisbinnie:$6$TRIYWb5l$ef6Tm54qpV2nYCn6f20b7w/
5nvp8zpsjacFqeTwqx7fCeW3plG2pkKsGgf1CtWzWhHOPWykFGrfPGmCde4HWY/
:12231:3:32:11:32::
Não é necessário rodar o comando authconfig para determinar que está
sendo usado o hash SHA512 nesse exemplo. Isso pode ser deduzido pela
consulta aos códigos na Tabela 9.1.
Tabela 9.1 – Como identificar algoritmos de hashing
SímboloAlgoritmo de hashing
$0 DES
$1 MD5 Hashing
$2 Blowfish
$2A Eksblowfish
$5 SHA256
$6 SHA512
No exemplo de senha Shadow, ensanduichado entre dois símbolos de
dólar diretamente após o nome de usuário, há estes três caracteres: $6$.
Pela Tabela 9.1 podemos ver que as senhas /etc/shadow estão usando
SHA512. Essa é uma boa notícia porque ele é um algoritmo forte.
A próxima seção de entrada de senha, depois de $6$ e até o próximo
símbolo de dólar, é o salt. Neste caso é o TRIYWb5l.
A senha (codificada com o salt) é a próxima seção em seguida ao símbolo
de dólar e antes do primeiro sinal de dois-pontos. Depois disso, as outras
seções, dentro de dois-pontos, fornecem algumas informações de login
pertinentes ao sistema, como a data de expiração da senha de usuário,
quando ela foi alterada pela última vez, e assim por diante.
Para avaliar o uso recente de algoritmos mais fortes, devemos considerar o
seguinte: de acordo com a Fedora, desde o Fedora 8 o pacote glibc
suporta os hashes SHA256 e SHA512. Como resultado, a partir do Fedora
9 tem sido possível usar o SHA256 e o SHA512 em senhas.
Caso o leitor esteja em dúvida, pode conferir no site
http://verifier.insidepro.com para determinar qual variedade de hash
deseja para a Hashcat. No meu caso, tive sucesso limitado com os hashes
de exemplo usados aqui, gerados usando uma ferramenta diferente do site,
portanto esteja avisado que a identificação de um tipo desconhecido de
algoritmo hash pode levar algum tempo.
Caso ache útil, o leitor pode tentar rodar o comando a seguir para gerar
uma senha MD5 com um salt (é necessário que o openssl esteja
instalado):
# openssl passwd -1 -salt 123 PASSWORD
$1$123$YPya29UI1XS9hz1d23ltx/
Analisando os resultados da execução desse comando, observe a posição
de $1$ e 123 em relação à senha codificada.
Às vezes também rodo um teste de hashing MD5 como este (sem um sal):
# echo PASSWORD | md5sum
8b04b6229e11c290efd5cd8190aa9261 -
Outras formas de gerar senhas manualmente podem ser encontradas em
http://unix.stackexchange.com/questions/81240/manually-
generate-password-for-etc-shadow.

Escolha do modo de ataque


Agora que o trabalho dos hashes foi compreendido, vamos em frente.
Mesmo quando o tipo de hash em uso é conhecido, é necessário ainda
considerar como atacar qualquer senha codificada à qual se tenha acesso.
Já mencionei um modo de ataque comum referido como ataque de força
bruta. Esse tipo de ataque se baseia no uso de caracteres que, tomando
como base pelo menos os conjuntos em uso nos Estados Unidos e no
Reino Unido, inclui os caracteres a-z, A-Z, 0-9./, e assim por diante.
Outro modo de ataque popular é o que usa wordlists. Neste, a Hashcat
roda por listas de palavras predefinidas, realizando testes para ver se elas
trabalham com as senhas apresentadas.
Uma forma mais complexa de usar wordlists é acrescentando regras
programadas, nas quais a Hashcat promove um ataque baseado em regras.
As palavras podem ser alteradas ou estendidas, por exemplo, usando regras
personalizadas. Com dedicação especial em alguns pontos específicos de
como a Hashcat funciona, os ataques podem ser mais precisos e, no final
das contas, mais eficientes.

Download de uma wordlist


Caso o leitor deseje rodar um ataque de wordlist, precisa antes ter uma
lista de palavras para a tarefa. Há alguns poucos sites online que afirmam
hospedar listas de senhas vazadas.
O site citado a seguir aparentemente não está envolvido com práticas
criminosas. Ele disponibiliza diversas wordlists para download. Usando
um dicionário da língua inglesa como exemplo, o site possibilita o
download de uma lista com 319.378 palavras que a Hashcat ficará muito
feliz em rodar. Essas wordlists podem ser encontradas em
www.md5this.com/tools/wordlists.html (a senha para destravar os
arquivos Zip contendo as palavras é mostrada como md5this.com).
Caso o leitor tenha interesse, o site md5this oferece também um gerador de
wordlists na forma de um script Python, que pode ser baixado de
www.md5this.com/tools/wordlist-generator.html. O script trabalha
gerando palavras a partir do conteúdo do site. Para rodar o script, basta
apontá-lo para um site do qual se deseja obter dados.

Tabelas rainbow
Em vez de se apoiar na capacidade de uma CPU ou uma GPU do sistema,
outra abordagem é fazer isso em seu armazenamento, usando
potencialmente centenas ou milhares de gigabytes. Durante um ataque de
força bruta, em vez de calcular um hash a cada tentativa, é possível
consultar tabelas com respostas pré-calculadas existentes em uma extensa
lista. São as tabelas rainbow (rainbow tables).
Há formas de frustrar essa abordagem, notadamente usando grandes sais
em hashes unidirecionais (one-way hashes). Isso funciona muito bem
porque cada senha recebe um hash com um salt único, portanto cada
possível hash calculado do salt deve necessitar de uma entrada em uma
tabela rainbow em conjunto com o seu salt.

Execução da Hashcat
Agora que temos algum conhecimento sobre hashes, modos de ataque e de
onde baixar uma wordlist (e considerando a dedicação do leitor ao grande
número de exemplos informativos, é possível atestar a utilidade deste
conhecimento), finalmente é possível rodar a Hashcat.
O conteúdo do meu diretório de instalação é o seguinte:
charsets/ hashcat-cli32.exe hashcat-cliXOP.bin tables/ hashcat
-cli64.app hashcat-cliXOP.exe
docs/ hashcat-cli64.bin rules/ hashcat-cli32.bin examples/
hashcat-cli64.exe salts/
Na minha lista de diretórios é possível ver que há diversos tipos de
executáveis.
Para as finalidades do leitor, qualquer coisa que termine com .bin deve ser
suficiente. Se por alguma razão os arquivos .bin não estiverem na
condição executável de imediato, usualmente a correção é obtida apenas
com a digitação de chmod +x <executable>. Usarei a versão de interface
de linha de comando de 64 bits denominada hashcat-cli64.bin,
compatível com as capacidades da minha máquina.
Aparentemente, os diferentes executáveis Hashcat mostrados nesse
diretório contêm diversas funcionalidade que podem ser disponibilizadas
pelos processadores de sua máquina. O outro arquivo relevante .bin, de
interesse do leitor, contém XOP acrescentado ao nome (XOP significa
eXtended OPerations instructions – instruções de operação estendida).
Caso mais tarde o leitor deseje levar a sério o uso da Hashcat, pode buscar
informações em suas flags de processador e escolher quais executáveis
podem fazer melhor uso do seu sistema em particular. Por exemplo, de
acordo com os fóruns, os chips dos processadores AMD atendem à versão
XOP.
Vamos agora tratar de rodar o executável Hashcat. A sintaxe para o
comando hashcat é a seguinte:
# hashcat [options] hashfile [mask|wordfiles|directories]
Tendo baixado (ou gerado) sua wordlist e tendo-a salvo no arquivo de
nome wordlist.txt, é hora de ir em frente. Considere este comando de
exemplo depois de introduzir o subdiretório examples com o comando cd
examples/:
# ./hashcat-cli64.bin -m0 -a0 A0.M0.hash A0.M0.word
A opção -m significa que um hash MD5 está sendo especificado e a opção -
a 0 diz para a Hashcat fazer um ataque de dicionário (também conhecido
como um straight attack – ataque direto). Como referência, caso -m1800
tenha sido especificado, o leitor está se referindo ao algoritmo moderno
preferido de hashing Unix, o SHA512.
Como o leitor está provavelmente supondo, o arquivo A0.M0.hash no
diretório examples é a sua lista de hashes. Eles são revelados sem a seção
<username>: antecedendo o sal, ou sem a senha anexada com informações
envelhecidas incluindo os dois-pontos depois dela. É dessa forma que os
hashes devem ser coletados.
O arquivo A0.M0.word é o seu dicionário potencial de senhas, como uma
wordlist.
Caso deseje escrever diretamente no arquivo sem a visualização em tela,
basta acrescentar -o <filename> ou, se desejar remover uma linha do
arquivo cheio de hashes quando já tiver descoberto sua senha, acrescentar
--remove.
Os resultados da execução do comando hashcat são mostrados a seguir
(de forma muito abreviada):
651e96f9b94e1a3a117eade5e226bd1e:y[N"%e?U{<k[`x<TlG U6Z
465133fae5a994afb03c7158260b2e8d:kCQArZz)It

All hashes have been recovered


Input.Mode: Dict (A0.M0.word)
Index.....: 1/1 (segment), 102 (words), 2769 (bytes)
Recovered.: 102/102 hashes, 1/1 salts
Speed/sec.: - plains, 102 words
Progress..: 102/102 (100.00%)
Running...: 00:00:00:01
Estimated.: --:--:--:--
As duas primeiras linhas contêm os hashes até o sinal de dois-pontos;
depois desses dois-pontos está a senha descoberta. O restante mostra que
obtivemos sucesso em todo o arquivo.
Após entender os exemplos, o leitor pode experimentar em seus próprios
hashes /etc/shadow. Com alguma sorte, após a execução dos comandos
ajustados, a tela mostrará um ou mais hashes seguidos de suas
correspondentes senhas em texto simples. Caso não tenha obtido sucesso
suficiente, continue experimentando até estar satisfeito com os resultados.
Pode ser necessário usar o método de tentativa e erro para conseguir o
funcionamento esperado; minha recomendação é que antes de tudo o leitor
esteja confortável com os exemplos globais. Caso parta para a batalha,
conforme-se com o fato de nem todas as senhas poderem ser quebradas de
imediato.
Isto posto, tendo entendido a teoria e tendo tentado usar sua
funcionalidade básica, a Hashcat é muito simples de operar. Da perspectiva
de um administrador de sistemas Linux, isso deveria motivar o leitor,
levando-o a prestar atenção ao algoritmo de hashing usado pelos
servidores.
Há diversas opções que vou deixar para o leitor explorar. Por exemplo, a
opção de executar regras junto com o exemplo é simplesmente -r
rules/specific_rule.rule.
Havia prometido dar uma olhada em alguns dos valores hash e modos de
ataque correspondentes. O número de hashes é muito grande para listar,
porém o site Hashcat os fornece, junto com detalhes úteis, em
http://hashcat.net/wiki/doku.php?id=example_hashes.
Alguns dos modos de ataque que podem ser usados, com 0 sendo
conhecido como “straight” (direto) – em outras palavras, casando com
algo em um dicionário ou uma wordlist –, são mostrados na Tabela 9.2
junto com seus números correspondentes.
Tabela 9.2 – Modos de ataque Hashcat e seus números correspondentes
Número Descrição do modo de ataque
0 Direto (dicionário e wordlists)
1 Combinação
Força bruta (roda como parte de um ataque
3
máscara)
6 Híbrido
Vamos dar uma rápida olhada nas diferenças entre um ataque de força
bruta e o ataque de dicionário, já citados anteriormente.
A diferença principal entre os dois é relacionada com o fato de os ataques
de força bruta terem de pesquisar em todo o keyspace para detectar uma
coincidência de senha. Por outro lado, os ataques de dicionário trabalham
com um escopo limitado. Como resultado, eles são muito mais rápidos,
porém evidentemente com uma boa chance de não conseguir quebrar os
hashes com salt que estiverem tentando processar. De qualquer forma,
pelo menos seremos rapidamente avisados de quaisquer falhas com esse
modo.
O ataque de força bruta, por sua vez, é caracterizado por se manter
rodando (potencialmente por um tempo muito, muito longo) até obter
sucesso na quebra da senha. Com certeza, caso os ajustes tenham sido
configurados corretamente, a senha será obtida em algum ponto, mesmo
que isso leve centenas de anos para acontecer.
Em sua detalhada documentação online, a Hashcat menciona que os
ataques de força bruta são uma forma antiga e menos sofisticada de
descobrir senhas. A Hashcat agora inclui o estilo de ataque de força bruta
(o leitor deve ter notado a menção a isso na Tabela 9.2) dentro do seu
modo de ataque máscara.
A premissa principal em um ataque máscara é a redução do tamanho do
keyspace e com isso a aceleração do processo. Um exemplo inteligente
existente na documentação é relacionado com a técnica inovadora da
Hashcat que pode reduzir o tempo de recuperação da senha “Julia1984” de
aproximadamente quatro anos para impressionantes quarenta minutos.
A documentação afirma enfaticamente que não há desvantagens em rodar
um ataque máscara sobre um ataque de força bruta, algo promissor. Um
ataque máscara pode ser executado acrescentando uma máscara ao final do
comando-padrão, da seguinte maneira:
# hashcat -m 1800 -a 0 -o discovered_passwords.txt --remove hashes.txt
wordlist.txt -1 ?dabcdef
O acréscimo de -1 ?dabcdef nesse caso orienta a Hashcat a rodar pelos
caracteres 0123456789abcdef.
De acordo com a documentação, esta máscara, -1 ?l?d?s?u, oferece um
conjunto pleno de caracteres ASCII de 7 bits, também conhecido como
mixalpha-numeric-all-space. Há diversas opções de conjuntos de caracteres
incluídos na Hashcat, como ?l (que representa todos os caracteres
minúsculos de a até z), e ?u (representando todos os caracteres maiúsculos
de A até Z).
Mais detalhes referentes a ataques máscara podem ser encontrados em
https://hashcat.net/wiki/doku.php?id=mask_attack.

oclHashcat
O uso de oclHashcat e Hashcat requer níveis de conhecimento muito
similares para as duas ferramentas, considerando que elas operam quase da
mesma forma. Embora apresentem algumas diferenças – por exemplo, a
forma como a oclHashcat carrega seus dicionários quando comparada com
a Hashcat –, podemos esperar uma curva de aprendizado sem muitos
dissabores quando movermos entre uma ferramenta e outra.
Além disso, o trabalho computacional necessário para a quebra de senhas
usa um componente totalmente diferente no sistema, como já mencionei.
Em termos simples, a oclHashcat trabalha com placas de vídeo em vez de
CPUs. Há duas importantes versões de software a considerar, cada uma
delas compreendendo duas GPUs populares:
• cudaHashcat, para uso em placas de vídeo Nvidia
• oclHashcat, que trabalha com placas de vídeo AMD
As GPUs são muito mais rápidas que as CPUs (quando configuradas
corretamente) porque são projetadas exclusivamente para realizar cálculos
extensos e complexos, usualmente no processamento de gráficos. Apesar
de obviamente projetadas para serem inerentemente rápidas, em termos de
desempenho, as CPUs podem ser sujeitas a desvios de finalidade, incluindo
conjuntos de funcionalidades, causando uma redução na capacidade de
processamento. Como resultado, as GPUs são uma boa escolha para a
computação de grandes quantidades de dados porque podem ser
otimizadas de forma muito mais efetiva. É possível também escalar as
saídas de GPUs de forma quase perfeita pela combinação de diversas delas
em cadeia, potencializando assim a capacidade de processamento. Para ter
uma ideia da rapidez das GPUs, se forem usadas rainbow tables e o
keyspace for dividido (considerando os 95 caracteres disponíveis em um
teclado americano), podem ser gerados dez trilhões de textos simples por
segundo!
Em termos de aprendizado de Hashcat e oclHashcat, recomendaria
primeiro fazer a Hashcat funcionar e depois se informar sobre como fazer
os drivers da placa de vídeo GPU trabalharem. Mais informações podem
ser obtidas em http://hashcat.net/oclhashcat/.
Como pode causar confusão, o oclHashcat-plus caiu em desuso e é
considerado obsoleto. Como resultado, não há benefícios no uso da versão
“plus”.

Hashcat-utils
Um componente adicional da suíte Hashcat que vale a pena mencionar é
um grupo de utilitários chamado Hashcat-utils. Essa coleção de
ferramentas úteis pode ser baixada de
http://hashcat.net/wiki/doku.php?id=hashcat_utils.
As ferramentas incluem o combinador, que é um programa autônomo pelo
qual se pode rodar ataques de combinadores. Mais informações podem ser
encontradas em https://hashcat.net/wiki/doku.php?
id=combinator_attack.
Um arquivo wordlist também pode ser aprimorado e dividido em partes
com a ferramenta cutb, que pode ser usada para fazer uma limpeza de
caracteres comuns indesejados anteriores ou posteriores em um arquivo
wordlist.
Outra ferramenta incluída no conjunto, a rli, é similar ao comando Unix,
e simplesmente remove arquivos duplicados, após comparar um arquivo
com um ou mais arquivos.
Definitivamente, em uma outra ocasião pode valer a pena explorar esses
utilitários para aumentar o conhecimento da forma de trabalho da
Hashcat.

Resumo
Neste capítulo, discorri sobre a teoria por trás dos ataques de senhas. Citei
também a importância do número de combinações incluídas em um
conjunto de caracteres, o comprimento das senhas e como suas
combinações afetam o keyspace. Finalmente, descrevi o hashing e a
colocação de sal, recursos que aumentam de forma significativa o tempo
necessário para quebrar uma senha.
Adquirir a habilidade de conseguir quebrar senhas de forma eficiente é algo
para muitos anos, sendo certamente uma área com muitas facetas. No
entanto, a venerável Hashcat ajuda a tornar o processo de aprendizagem
uma tarefa leve. Há também um FAQ detalhado que pode ser encontrado
em http://hashcat.net/wiki/doku.php?
id=frequently_asked_questions.
Tendo visto os métodos usados por um agressor para quebrar suas senhas
e as formas como podemos tornar esse trabalho mais difícil para ele, o
leitor deve prestar muita atenção caso descubra em suas máquinas vestígios
de qualquer uma das ferramentas já discutidas. Com o poder possibilitado
pela aquisição dos novos conhecimentos, é desnecessário lembrar que essas
habilidades devem ser usadas com responsabilidade.

1 N. do T.: Ao visitar o site na época em que este livro estava sendo traduzido, não encontrei o link
SHOW DETAILS. O site foi reformulado e agora é muito mais dinâmico: à medida em que uma
senha de exemplo é digitada, a segurança desta é calculada imediatamente e mostrada na forma de
quanto tempo é necessário para que seja quebrada.
2 N. do T.: Esclarecendo o texto do autor, o processo é “simples e inteligente” porque quando o
usuário inicialmente cadastrou sua senha, ela foi transformada em um hash que não pode ser
descriptografado. Cada vez que ele quiser entrar no sistema, a senha que ele digita na tela de login
é criptografada em um outro hash, e é esse novo hash que é comparado ao que está guardado. Se
os dois forem idênticos, a senha está correta, mas o próprio Linux não sabe qual é a senha original,
ele apenas compara os hashes.
3 N. do T.: Na última revisão deste livro, a versão mais atual era 3.20.
CAPÍTULO 10
Ataques de injeção de SQL

Um dos tipos mais populares de ataques online é conhecido como injeção


SQL, às vezes abreviado como SQLi. Esses ataques envolvem a inserção de
códigos no banco de dados usando a linguagem SQL (Structured Query
Language – Linguagem Estruturada de Consulta), em que os agressores
têm acesso ao banco de dados, com poder para capturar dados ou escrever
sobre eles.
O leitor pode ficar surpreso em saber que, conforme o OWASP (the Open
Web Application Security Project), uma organização beneficente voltada à
segurança do software, a SQLi foi a ameaça número um em serviços online
em 2013 e citada como a ameaça mais comum em
https://www.owasp.org/index.php/Top_10_2013-Top_10.
Este capítulo trata do que está envolvido nesses ataques, como proteger
seus sites contra eles e finalmente como eles podem ser usados em testes de
penetração.
Desnecessário dizer, esta é uma área ampla e complexa que requer um
certo grau de conhecimento para executar ataques mais sofisticados. No
entanto, o leitor pode ficar surpreso em saber quão fácil é colocar de
joelhos um serviço online vulnerável após executar uns poucos comandos e
com somente pouco conhecimento sobre bancos de dados. Somente por
esse motivo, é imperativo que os profissionais de TI estejam cientes dos
riscos representados pelas injeções SQL e saibam como mitigar seus
efeitos.

História
Considerando sua simplicidade, o fato da SQLi ser assim tão eficaz a torna
uma modalidade extraordinária de ataque.
Tomem nota disso, senhores desenvolvedores júniores, porque quando se
trata de assuntos de segurança, os administradores de sistema não podem
ser diretamente responsabilizados pela ocorrência desses ataques. Isso
porque, na maioria das vezes, as explorações são possíveis devido a códigos
que não escapam caracteres especiais de forma adequada. Além de sua
simplicidade, outra causa de preocupação é o fato de este tipo de ataque
ser conhecido desde 1998. Uma edição da Phrack Magazine, publicada em
dezembro daquele ano, anunciou pela primeira vez esta enorme e
arrebatadora vulnerabilidade em sites. Com o tempo, o horror continuou
aumentando, tornando-se óbvio que diversas ferramentas automatizadas
poderiam ser usadas para uma varredura na web, em busca de sites,
corrompendo ou roubando dados da forma como bem entendessem.
Porém, a coisa não parou aí. Com a popularização dos ataques phishing
(nos quais os agressores enganam os usuários, induzindo-os a revelar
informações sobre eles próprios), os ardilosos agressores passaram a
reformular completamente determinados sites, injetando neles os códigos
necessários, dando ao usuário a impressão de estar visitando um site
autêntico.
Por muitos anos, mantive um servidor ISP muito pequeno compartilhado
com usuários de relativo conhecimento tecnológico. Em pelo menos três
ocasiões, nossos clientes de compartilhamento do servidor,
involuntariamente menos zelosos com seus scripts hospedados,
sucumbiram a ataques phishing. A partir da metade dos anos 2000, em um
período de apenas poucos anos, entraram em contato conosco o FBI (U.S.
Federal Bureau of Investigation), um banco e um serviço de segurança
white hat, informando ação de hackers em servidores de clientes. Assim,
mesmo em uma organização de pequeno porte, uma cópia falsa de um site
de leilões e de dois sites bancários foram clonados e usados em ataques
phishing em nossas redes dentro de um curto espaço de tempo.
Rapidamente ficou óbvio que os ataques SQLi estavam se tornando
populares entre os intentos com finalidades maliciosas.
Os administradores de sistemas e os desenvolvedores aprenderam com isso
e, em reação, começaram a endurecer os códigos. Recordo-me que nessa
época houve um escape diligente por caracteres especiais para cada
componente de usuário de entrada em um site baseado em PHP para evitar
ataques SQLi.
SQLi básica
Como já mencionei, a premissa principal por trás da SQLi é a captura
ilegítima de códigos de um banco de dados ou a injeção de códigos nele.
Para evitar esses problemas, não se deve mais expor consultas (queries)
para o mundo externo, e para consegui-lo a melhor maneira é abolir o uso
de linguagens que rodam no servidor (como o PHP, por exemplo). O
problema é que, com isso, o site perde fluidez e utilidade. Caso não seja
possível evitar o uso dessas linguagens, é preciso certificar-se de que todos
os vetores de ataque estejam sendo monitorados. A forma mais fácil de
conseguir isso é filtrar todos os dados de entrada recebidos de visitantes.
Em outras palavras, em qualquer ponto do site em que um usuário pode
introduzir dados, devem ser tomadas precauções relevantes dentro do
código utilizado. Isso envolve a análise da entrada em um formato
amigável antes do envio dos dados ao banco de dados.
Um tutorial completo sobre como proceder para manter o código seguro
não está no escopo deste livro. De imediato, farei uma recapitulação rápida
usando uma linguagem de programação popular. Antes disso, vou
recapitular algumas formas simples de funcionamento da SQLi.
Como havia mencionado, a mera deterioração de um site não é o único
prejuízo que uma SQL interceptada pode causar. Consideremos esta
instrução SQL, por exemplo:
sql-server> DROP TABLE special-offers;
Uma tabela pode ser completamente excluída de um banco de dados se os
nomes dessa tabela forem conhecidos. Além do comportamento
destrutivo, eu não havia ainda mencionado a extração de nomes de usuário
e de senhas de um banco de dados. Para quem tem intenções criminosas,
um ataque SQL é sem dúvida um prêmio que vale a pena perseguir. Muitas
marcas comerciais poderosas foram vítimas de códigos com programação
fraca e SQLi. A longa lista de vítimas inclui empresas como Yahoo, Adobe,
LinkedIn e Sony Music. Evidentemente, sem ter sido um dos agressores
nem tendo pertencido à equipe incumbida de recuperar os serviços
afetados por esses ataques, posso somente conjeturar em qual magnitude
esses ataques envolveram SQLi. Um Palácio da Vergonha SQLi pode ser
encontrado em http://codecurmudgeon.com/wp/sql-injection-hall-
of-shame/. Apesar de essa lista não ser muito completa, tenho certeza de
que o leitor concorda ser uma leitura necessária.
Há pouco fiz referência a uma linguagem de programação. Vou usar a que
talvez seja a linguagem de script do lado servidor mais popular do mundo,
a PHP, como exemplo para uma rápida demonstração de como a SQLi
funciona. Além de ser usada diretamente em milhões de sites, a poderosa
PHP está presente no Sistema de Gerenciamento de Conteúdo (Content
Management System – CMS) mais popular do planeta, o WordPress
(https://wordpress.com), e em muitas outras aplicações dinâmicas em sites,
como a Joomla! (https://www.joomla.org). Em resumo, a PHP está presente
de forma generalizada na web, constituindo-se em um alvo fácil para os
agressores caso uma exploit seja descoberta.
Vamos ver outro exemplo, desta vez em PHP:
$input = $variable[3];
$dbquery = "SELECT id, item, price FROM specialoffers ORDER BY id
LIMIT 15 OFFSET $input;";
Observando a linha superior, podemos notar a ausência de filtragem na
variável chamada $input. Isso significa que, quando a variável é usada na
segunda linha dentro da instrução SQL, ela pode potencialmente incluir
qualquer código desejado por um atacante. Com a injeção de um desses
códigos criados pelo atacante, podem ser causados estragos de toda sorte.
Outro exemplo é a atualização da senha de usuário administrador (sysop
user). Por exemplo, uma instrução SQL normal no código PHP é parecida
com esta:
$dbquery = "UPDATE credentials SET passwd='$password' WHERE
userid='$id';";
Acrescentando SQL depois dessa instrução, tal como or userid like
'%sysop%', o SQL se torna muito menos restrito e é possível solicitar ao
banco de dados que faça uma busca rápida de outros nomes de usuários
privilegiados similares a sysop, como sysops, atualizando suas senhas nesse
processo.
De forma preocupante, é possível também executar comandos shell que
podem ser incluídos dentro da SQL. Alguns servidores de banco de dados
permitem acesso a comandos de sistemas operacionais usando esse
método.
Mitigação de SQLi em PHP
Como havia mencionado, este é um tema muito extenso para abordar em
detalhes, porém seria uma negligência da minha parte não explorar
rapidamente como filtrar entradas SQL para ajudar na mitigação de
ataques SQLi. Há um bom número de funções PHP que podem ajudar
nessa tarefa. Na época da elaboração deste livro, a Fundação PHP estava
migrando a versão estável para a 7.0.0, sendo que a versão corrente é a
5.6.16 (embora até a publicação a nova versão deva ser superior).
Podemos ressaltar que, nas versões mais antigas (anteriores à 5.3.0), dentro
do arquivo de configuração principal do PHP (php.ini) era possível filtrar
(ou escapar) todos os dados de entrada via PHP usando
magic_quotes_gpc. Aparentemente, isso foi descontinuado após a 5.3
porque a lista de caracteres a escapar era gigantesca, e nem todos eram
escapados de fato. Essencialmente, as magic quotes não foram projetadas
para fins de segurança, mas acabaram sendo improvisadas para tal.
Para proteger a variável usada no primeiro exemplo SQL, a entrada de
usuário pode ser executada com a função stripslashes. O exemplo tem
esta forma:
$input = $variable[3];
Usando stripslashes, fica parecido com:
$input = stripslashes($variable[3]);
Como o leitor deve estar imaginando, isso significa a remoção de barras
invertidas (slashes) para ajudar na proteção contra entradas indesejadas.
Há também o trim para remover espaços em branco de uma variável, que
pode ser usado da mesma forma, bem como strip_tags para remoção de
HTML e de outras etiquetas de marcação (markup tags). Todas essas
funções são úteis e podem ser encadeadas para efeitos de facilidade:
$input = stripslashes((trim($input));
Além disso, até a versão 5.5.0 da PHP, podia ser usada a função
mysql_real_escape_string para limpar strings individuais como:
$input = mysql_real_escape_string($input);
No entanto, a partir da versão 7.0.0, quase sempre é possível usar um
driver aprimorado chamado MySQLi (significa MySQL improved
[melhorado]) no lugar da SQLi. Graças a esse aperfeiçoamento, é possível
adotar uma forma mais avançada para eliminar caracteres desnecessários e
potencialmente perigosos do código em execução. Um exemplo usando
mysqli apresenta poucas diferenças em relação ao exemplo anterior:
$input= mysqli_real_escape_string($input);
Usando MySQLi, a conexão ao banco de dados é feita usando um método
diferente:
$mysqli = new mysqli("localhost", "userid", "passwd", "DB_name");
Outra forma de mitigar ataques SQLi é usar instruções preparadas. A ideia
por trás desse acréscimo de segurança é fazer o gerenciador de banco de
dados processar a linguagem SQL de forma completamente separada de
qualquer parâmetro em uso. Teoricamente, isso significa que um agressor
não tem como injetar qualquer código na consulta. Um exemplo pode ser
parecido com:
$input = $mysqli->prepare("INSERT INTO table_name (column_name) VALUES (?)");
$input->bind_param("s", $actual_user_input);
$input->execute();
$input->close();
Essa nova e preferencial abordagem realiza filtragem nos parâmetros
usando a nova biblioteca. Note o ponto de interrogação no lugar do valor
da variável. A linha contendo execute concatena todos os parâmetros
anteriores. Essa função precisa ser lida apenas uma vez, o que é uma ajuda
extra; se fosse lida diversas vezes em poucas páginas, o interpretador PHP
teria seu desempenho prejudicado.
Outra abordagem que deve ser conhecida existe desde as primeiras versões
da PHP e faz uso de objetos de dados PHP (PHP Data Objects – PDO). Há
uma grande e extensa discussão aqui:
http://stackoverflow.com/questions/60174/how-can-i-prevent-
sql-injection-in-php.
Qual metodologia é melhor para uso é algo questionável, mas a PDO
parece ser muito popular. Eis um exemplo de PDO:
$input = $pdo->prepare('SELECT * FROM special_offers_table
WHERE offer = :specialoffer');
$input->execute(array('name' => $specialoffer));
Há algumas informações (em inglês) bem escritas sobre PDO em
http://whateverthing.com/blog/2014/08/28/the-heart-of-
darkness/. A leitura vale a pena, pela simples razão de auxiliar na escolha
entre métodos de combate a ameaças SQLi na última versão da PHP
(versão 7.0.0 em diante).

Exploração de falhas SQL


Agora que vimos algumas formas diferentes de proteção contra SQLi,
vamos aprender como um hacker pode atacar serviços online. Há diversas
ferramentas disponíveis, mas vou me concentrar na sqlmap
(http://sqlmap.org), uma ferramenta em código aberto popular entre
hackers, cientistas forenses e testadores de penetração. Bastante
sofisticada, essa ferramenta tem alto potencial para causar estragos,
portanto esteja plenamente ciente dos danos que pode causar nos testes em
seus próprios servidores. Em servidores alheios, nem pensar! Em nome da
segurança, para os testes definitivamente recomendo o uso de um servidor
de desenvolvimento ou uma máquina sandbox virtual.
A ampla compatibilidade da sqlmap é motivo de preocupação para os mais
diligentes administradores de sistema. De acordo com o seu site, a sqlmap
suporta os seguintes servidores de banco de dados: MySQL, Oracle,
PostgreSQL, Microsoft SQL Server, Microsoft Access, IBM DB2, SQLite,
Firebird, Sybase, SAP MaxDB e HSQLDB.
Vamos ver como instalar a sqlmap. Essa ferramenta é incluída em algumas
distribuições baseadas em segurança, como a Kali Linux, porém se ela não
existir em seus repositórios do gerenciador de pacotes, podem ser usadas
outras formas alternativas de instalação.
O repositório de sqlmap do GitHub pode ser utilizado mediante o
comando Git clone:
# git clone https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
Há também um arquivo compactado (zip) em
https://github.com/sqlmapproject/sqlmap/zipball/master.
Um tarball pode ser baixado de
https://github.com/sqlmapproject/sqlmap/tarball/master.
Uma vez seguidas as instruções de instalação, foi atingido o estágio que
permite executar o comando a seguir (depois de rodar previamente o
comando Git, basta fazer isto para iniciar):
# cd sqlmap-dev
# python ./sqlmap.py -h
Esse comando oferece uma lista de opções.

Lançamento de um ataque
Vamos ver agora a essência da funcionalidade sqlmap, especificamente
voltada ao comprometimento de uma máquina remota.
No entanto, esteja ciente disto: para testar suas próprias habilidades na
sqlmap, o leitor precisará configurar seu próprio servidor de teste para
torná-lo vulnerável ou identificar sites legítimos vulneráveis a ataques, e as
duas coisas consomem bastante tempo. Devido à forma como os URLs são
formados, é surpreendentemente fácil para o Google identificar sites
vulneráveis. Nem é preciso dizer, neste caso, que desencorajo ataques em
qualquer site encontrado via Google ou por qualquer outro método. Para
descobrir URLs potencialmente exploráveis, pode ser emitida uma consulta
como inurl:website.php?id= ou inurl:product.php?id=. O primeiro
termo de busca retorna preocupantes 1,7 milhão de resultados.
Os sites e outros recursos online que de forma incompetente deixam
expostas suas vulnerabilidades via Google ganharam um apelido:
Googledorks (bobocas do Google). Vale a pena dar uma rápida olhada em
alguns deles, relacionados no site www.hackersforcharity.org/ghdb/. As
listas incluem muitos dados potencialmente secretos, como páginas de
login, diretórios sensíveis e arquivos com nomes de usuários. Use essas
informações com responsabilidade.
Alternativamente, a sqlmap pode rodar via Python, o que significa a
necessidade de alguma versão dessa linguagem instalada na máquina.
Na Figura 10.1 podemos ver que os desenvolvedores são cautelosos o
suficiente para manter distância segura de atividades ilegais. Essas
ferramentas poderosas estão sempre sujeitas a abusos.
Figura 10.1 – Apresentação da sqlmap logo após seu lançamento, incluindo a
isenção de responsabilidade (legal disclaimer).
No exemplo a seguir, a sintaxe a ser usada para o comando sqlmap é muito
simples:
# python sqlmap.py -u http://www.a-vulnerable-website.com/product.php?id=1111
Se houver problemas com baixa conectividade ou com respostas lentas do
servidor de banco de dados remoto, a inclusão de --time-sec 10 no
comando atua no sentido de introduzir um ajuste de temporização mais
realista. Parece uma maneira não muito intuitiva, mas isso realmente
acelera o processo de forma geral.
Vamos agora, de forma metódica, ver alguns poucos comandos simples. O
leitor pode escolher encadeá-los juntos se já estiver familiarizado com o
uso da sqlmap.
O meu comando de exemplo sqlmap inclui a opção -u, significando que
um URL está especificado. Esse comando apenas verifica as
vulnerabilidades do parâmetro final (id=1111) usando diversos testes de
injeção SQL. Com isso, a sqlmap pode obter algumas informações, como o
fabricante e a versão do servidor web, o sistema operacional remoto e a
versão do servidor do banco de dados.
Deseja saber os nomes dos bancos de dados usados pelo site? Isso pode ser
obtido pelo acréscimo da opção --dbs:
# python sqlmap.py -u "http://www.a-vulnerable-website.com/product.php?id=1111" -
-dbs
Com essas informações úteis em mãos, o próximo passo é descobrir os
nomes das tabelas em uso. Isso pode ser feito substituindo o nome do
banco de dados real pela entrada <database-name>:
# python sqlmap.py -u "http://www.a-vulnerable-website.com/product.php?id=1111" -
-tables -D <database-name>
O próximo passo lógico é saber quais são as colunas usadas por uma tabela
de banco de dados de interesse com a entrada <database-name> e também
<table-name> com o nome da tabela:
# python sqlmap.py -u "http://www.a-vulnerable-website.com/product.php?id=1111" -
-columns -D <database-name> -T <table-name>
A parte final do processo é extrair todos os dados do banco de dados alvo.
Isso inclui nomes de usuário e senhas, informações pessoais ou,
simplesmente, informações de produtos de uma loja online. No caso de
ataque a um site remoto, o valor das informações extraídas é claramente
dependente do site em questão. Para fazer o despejo dos dados do banco
de dados, devemos usar a opção --dump:
# python sqlmap.py -u "http://www.a-vulnerable-website.com/product.php?id=1111" -
-dump --columns -D <database-name> -T <table-name>
Caso deseje extrair apenas colunas específicas, elas devem ser especificadas
diretamente. Uma vez conhecidos os nomes das colunas, elas podem ser
simplesmente listadas com uma opção como -C columnX, columnY e
separadas com vírgulas. Feito isso, basta remover a opção --columns
incluída no exemplo anterior.
O último comando pode produzir uma saída parecida com esta:
+-------+----------------+----------+--------+------------+--------------+
| id | title | color | price | category | received-date|
+-------+----------------+----------+--------+------------+--------------+
| 1111 | bars of soap | green | 1.22 | toiletries | 11.11.22 |
+-------+----------------+----------+--------+------------+--------------+
Caso seja um desenvolvedor ou um administrador de sistemas e não esteja
preocupado com a rapidez de um despejo de banco de dados, é melhor
passar a se preocupar. Tenha em mente que a identificação de uma lista de
alvos potenciais pode ter sido feita via Google, com um mínimo de esforço
e com poucos comandos sendo usados, conseguindo com isso realizar o
roubo de dados comerciais potencialmente valiosos. Além desse roubo de
dados, com o uso de sqlmap os dados existentes podem ser sobrescritos e o
serviço online em questão corrompido, afetando a marca e a reputação
com relativa facilidade.
A poderosa e sofisticada ferramenta sqlmap oferece uma longa lista de
opções simplesmente muito grande para ser abordada em detalhes. Minha
sugestão é a leitura da página GitHub, que contém maior detalhamento do
uso da sqlmap:
https://github.com/sqlmapproject/sqlmap/wiki/Usage.

Testando a SQLi de forma legal


Há diversos sites úteis que permitem rodar escaneamentos para confirmar
a correta configuração das ferramentas de testes de penetração. Um desses
sites, caso deseje testar seus novos conhecimentos sobre SQLi, é o Web
Scan Test. Uma injeção SQL é possível via subdiretório:
www.webscantest.com/datastore. No entanto, é aconselhável ler os
termos do site antes de continuar, apenas para ter certeza de não estar
cometendo nenhum crime.
Também pode ser interessante experimentar um demo online do site
Codebashing. Inteligente e interativo, esse site é descrito como uma
“aplicação de treinamento de segurança para programadores, feita por
programadores”. O demo discorre sobre como caracteres especiais fazem
uma enorme diferença em um processo de login e como o servidor de
banco de dados subjacente reage com a mudança na entrada. Esse demo
pode ser encontrado em www.codebashing.com/sql_demo.

Resumo
Neste capítulo, abordei os princípios básicos por trás da injeção SQL e
também apresentei um breve histórico dos ataques SQL. Além disso, vimos
como os desenvolvedores PHP recomendam ações de proteção contra
ataques SQLi relacionados com MySQL, no passado com versões mais
antigas e prosseguindo com as versões mais novas, particularmente após a
versão 7.0.0.
É fácil compreender porque os ataques SQLi são tão comuns – e de fato já
foram considerados como o tipo de ataque mais popular em alguns
contextos. Pelo uso de alguns poucos comandos sqlmap relativamente
simples, pode-se de forma poderosa abrir brechas na segurança de um site,
pesquisar e roubar seus dados valiosos, causando danos na reputação com
esse vandalismo.
É importante, para o pessoal técnico encarregado da segurança de
sistemas, estar ciente da simplicidade desses ataques e compreender as
implicações resultantes de equívocos aparentemente simples. Esses
equívocos podem deixar sites – construídos com muitos esforços e recursos
– vulneráveis a ataques devastadores que demandam um trabalho
considerável para a sua recuperação. Nunca é demais lembrar: esses
conhecimentos devem ser usados com responsabilidade. Há muito mais
satisfação em proteger adequadamente sua própria infraestrutura e menos
em realizar ataques em infraestrutura de terceiros.
Guia Prático de Cifragem Manual
Ribeiro, Fred
9788575226230
104 páginas

Compre agora e leia

Este guia visa recuperar técnicas úteis que têm sido


esquecidas ao longo do tempo, métodos de cifragem que
podem ser utilizados com um mínimo de recursos, pouco
além de papel e caneta. Também apresenta novas cifras e
adaptações de cifras a dispositivos do dia a dia, como
sudoku, batalha naval e tabuleiro de xadrez. Com linguagem
simples e repleto de exemplos, o livro prima pela praticidade.
A cifragem manual não visa substituir a criptografia digital,
mas complementar, ao suprir o indivíduo com técnicas que
sejam empregadas quando da ausência de recursos
computacionais.

Compre agora e leia


Automatize tarefas maçantes com Python
Sweigart, Al
9788575226087
568 páginas

Compre agora e leia

APRENDA PYTHON. FAÇA O QUE TEM DE SER FEITO.


Se você já passou horas renomeando arquivos ou
atualizando centenas de células de planilhas, sabe quão
maçantes podem ser esses tipos de tarefa. Que tal se você
pudesse fazer o seu computador executá-las para você?
Com o livro Automatize tarefas maçantes com Python, você
aprenderá a usar o Python para criar programas que farão
em minutos o que exigiria horas para ser feito manualmente
– sem que seja necessário ter qualquer experiência anterior
com programação. Após ter dominado o básico sobre
programação, você criará programas Python que realizarão
proezas úteis e impressionantes de automação sem nenhum
esforço: Pesquisar texto em um arquivo ou em vários
arquivos. Criar, atualizar, mover e renomear arquivos e
pastas. Pesquisar na Web e fazer download de conteúdos
online. Atualizar e formatar dados em planilhas Excel de
qualquer tamanho. Separar, combinar, adicionar marcas-
d'água e criptografar PDFs. Enviar emails para lembretes e
notificações textuais. Preencher formulários online.
Instruções passo a passo descreverão cada programa e
projetos práticos no final de cada capítulo desafiarão você a
aperfeiçoar esses programas e a usar suas habilidades
recém-adquiridas para automatizar tarefas semelhantes.
Não gaste seu tempo executando tarefas que um
macaquinho bem treinado poderia fazer. Mesmo que não
tenha jamais escrito uma linha de código, você poderá fazer
o seu computador realizar o trabalho pesado. Saiba como
em Automatize tarefas maçantes com Python.
Compre agora e leia
Desenvolvendo Websites com PHP
Niederauer, Juliano
9788575226179
320 páginas

Compre agora e leia

Desenvolvendo Websites com PHP apresenta técnicas de


programação fundamentais para o desenvolvimento de sites
dinâmicos e interativos. Você aprenderá a desenvolver sites
com uma linguagem utilizada em milhões de sites no mundo
inteiro. O livro abrange desde noções básicas de
programação até a criação e manutenção de bancos de
dados, mostrando como são feitas inclusões, exclusões,
alterações e consultas a tabelas de uma base de dados. O
autor apresenta diversos exemplos de programas para
facilitar a compreensão da linguagem. Nesta obra, você irá
encontrar os seguintes tópicos: O que é PHP e quais são
suas características; Conceitos básicos e avançados de
programação em PHP; Como manipular diversos tipos de
dados com o PHP; Criação de programas orientados a
objetos (OOP); Comandos PHP em conjunto com tags
HTML; Utilização de includes para aumentar o dinamismo de
seu site; Como tratar os dados enviados por um formulário
HTML; Utilidade das variáveis de ambiente no PHP; Criação
de banco de dados em MySQL, PostgreSQL ou SQLite;
Comandos SQL para acessar o banco de dados via PHP;
Como criar um sistema de username/password para seu
site; Utilização de cookies e sessões; Leitura e gravação de
dados em arquivos-texto; Como enviar e-mails pelo PHP.

Compre agora e leia


Jovem e Bem-sucedido
Niederauer, Juliano
9788575225325
192 páginas

Compre agora e leia


Jovem e Bem-sucedido é um verdadeiro guia para quem
deseja alcançar a realização profissional e a financeira o
mais rápido possível. Repleto de dicas e histórias
interessantes vivenciadas pelo autor, o livro desmistifica uma
série de crenças relativas aos estudos, ao trabalho e ao
dinheiro. Tem como objetivo orientar o leitor a planejar sua
vida desde cedo, possibilitando que se torne bem-sucedido
em pouco tempo e consiga manter essa realização no
decorrer dos anos. As três perspectivas abordadas são:
ESTUDOS: mostra que os estudos vão muito além da escola
ou faculdade. Aborda as melhores práticas de estudo e a
aquisição dos conhecimentos ideais e nos momentos certos.
TRABALHO: explica como você pode se tornar um
profissional moderno, identificando oportunidades e
aumentando cada vez mais suas fontes de renda. Fornece
ainda dicas valiosas para desenvolver as habilidades mais
valorizadas no mercado de trabalho. DINHEIRO: explica
como assumir o controle de suas finanças, para, então,
começar a investir e multiplicar seu patrimônio. Apresenta
estratégias de investimentos de acordo com o momento de
vida de cada um, abordando as vantagens e desvantagens
de cada tipo de investimento. Jovem e Bem-sucedido
apresenta ideias que o acompanharão a vida toda,
realizando importantes mudanças no modo como você
planeja estudar, trabalhar e lidar com o dinheiro.

Compre agora e leia


Wireshark para profissionais de
segurança
Bullock, Jessey
9788575225998
320 páginas

Compre agora e leia


Um guia essencial para segurança de rede e para o
Wireshark – um conjunto de ferramentas repleto de recursos
O analisador de protocolos de código aberto Wireshark é
uma ferramenta de uso consagrado em várias áreas,
incluindo o campo da segurança. O Wireshark disponibiliza
um conjunto eficaz de recursos que permite inspecionar a
sua rede em um nível microscópico. Os diversos recursos e
o suporte a vários protocolos fazem do Wireshark uma
ferramenta de segurança de valor inestimável, mas também
o tornam difícil ou intimidador para os iniciantes que queiram
conhecê-lo. Wireshark para profissionais de segurança é a
resposta: ele ajudará você a tirar proveito do Wireshark e de
ferramentas relacionadas a ele, por exemplo, a aplicação de
linha de comando TShark, de modo rápido e eficiente. O
conteúdo inclui uma introdução completa ao Metasploit, que
é uma ferramenta de ataque eficaz, assim como da
linguagem popular de scripting Lua. Este guia extremamente
prático oferece o insight necessário para você aplicar o
resultado de seu aprendizado na vida real com sucesso. Os
exemplos mostram como o Wireshark é usado em uma rede
de verdade, com o ambiente virtual Docker disponibilizado;
além disso, princípios básicos de rede e de segurança são
explicados em detalhes para ajudar você a entender o
porquê, juntamente com o como. Ao usar a distribuição Kali
Linux para testes de invasão, em conjunto com o laboratório
virtual e as capturas de rede disponibilizadas, você poderá
acompanhar os diversos exemplos ou até mesmo começar a
pôr em prática imediatamente o seu conhecimento em um
ambiente de rede seguro. A experiência prática torna-se
mais valiosa ainda pela ênfase em uma aplicação coesa,
ajudando você a explorar vulnerabilidades e a expandir
todas as funcionalidades do Wireshark, estendendo-as ou
integrando-as com outras ferramentas de segurança.

Compre agora e leia

Você também pode gostar