01 Jun
Postado por: Pedro Pereira em: Redes
Gostaria da ajuda de um especialista? Entre em contato e peça um orçamento.
Um sniffer é um programa cuja principal função é capturar pacotes que estão sendo transmitidos através de uma rede. Assim, ela permite a você, o administrador de redes, analisar o comportamento da rede auxiliando muito na hora de encontrar problemas, máquinas infectadas, tráfego malicioso, gargalos, etc.
Para que o sniffer consiga capturar os pacotes gerados por e destinados a outras estações, é necessário que esses pacotes cheguem à interface de rede da máquina onde o sniffer está sendo executado. Numa rede que usa switches isso não acontece, então é necessário configurar uma span port para que todo o tráfego que passa nas outras portas do switch seja enviado também para a porta onde o sniffer está rodando. Em uma rede com hub, isso não é necessário já que por padrão todas as portas receberão todos os pacotes que passam pelo dispositivo (alguém ainda usa hubs? :) ).
Aqui vou ensinar você a usar o TCPDump (site oficial www.tcpdump.org). Ele funciona em sistemas Unix-like (Linux, *BSD’s, Mac OS) e Windows – através do port chamado WinDump) e foi criado em 1987 por desenvolvedores do Lawrence Berkeley Laboratory Network Research Group. A interface dele é puramente através da linha de comando, não existe uma interface gráfica disponível (pelo menos que eu conheça, se você conhecer me avise aí nos comentários!). As capturas de pacotes executadas pelo TCPDump podem ser escritas em um arquivo e lidas no Wireshark ou pelo próprio TCPDump, por exemplo.
Uma das funcionalidades mais importantes do TCPDump são os filtros. Com eles você consegue especificar detalhadamente qual o tráfego que você quer que seja capturado para posterior análise. Aqui mostrarei uma introdução básica aos filtros para que você não precise capturar 2GB de tráfego para analisar somente 2MB :)
Lembre-se que para executar o TCPDump em um host é necessário que você seja o root (ou tenha permissões equivalentes).
Provavelmente o TCPDump já está instalado no seu sistema. Caso não esteja, é muito provável que haja um pacote pré-compilado para ele pronto para instalar nos repositórios oficiais da sua distribuição. Portanto, antes de sair compilando tudo e demorando horas resolvendo os problemas, tente usar o YUM, APT-GET, etc. para instalar!
O método mais simples de iniciar o TCPDump é simplesmente executando:
# tcpdump
Assim, iremos sniffar tráfego que passa pela primeira interface (excluindo a loopback, o que geralmente deixa a eth0) e o sniffer irá mostrar uma descrição rápida dos pacotes capturados. Por exemplo:
# tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on usbmon1, link-type USB_LINUX_MMAPPED (USB with padded Linux header), capture size 65535 bytes
20:42:14.231304 CONTROL SUBMIT to 1:7:0
20:42:14.231450 CONTROL COMPLETE from 1:7:0
20:42:14.231479 CONTROL SUBMIT to 1:6:0
20:42:14.231697 CONTROL COMPLETE from 1:6:0
20:42:14.231722 CONTROL SUBMIT to 1:5:0
20:42:14.231822 CONTROL COMPLETE from 1:5:0
20:42:14.231844 CONTROL SUBMIT to 1:1:0
20:42:14.231845 CONTROL COMPLETE from 1:1:0
Porém, esta saída não ajuda muito quando você está tentando debugar um problema ou fazer uma análise mais profunda dos pacotes capturados. Sem contar que a informação capturada não será armazenada em lugar nenhum, sendo apenas exibida na tela e descartada.
Vamos especificar uma interface na qual o TCPDump irá ouvir. Para isso devemos usar o switch -i . Por exemplo:
# tcpdump -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on p35p1, link-type EN10MB (Ethernet), capture size 65535 bytes
20:45:53.332881 IP c-68-54-80-123.hsd1.md.comcast.net.10870 > 192.168.1.100.57211: Flags [P.], seq 4112482480:4112483928, ack 3043195491, win 256, options [nop,nop,TS val 4793015 ecr 6885147], length 1448
20:45:53.332952 IP 192.168.1.100.57211 > c-68-54-80-123.hsd1.md.comcast.net.10870: Flags [.], ack 1448, win 2570, options [nop,nop,TS val 6886964 ecr 4793015], length 0
20:45:53.332969 IP host-89-230-141-177.inowroclaw.mm.pl.26883 > 192.168.1.100.50677: Flags [.], ack 4020898930, win 16086, options [nop,nop,TS val 6406293 ecr 6884378], length 0
20:45:53.344618 IP 192.168.1.100.51921 > google-public-dns-a.google.com.domain: 54154+ PTR? 100.1.168.192.in-addr.arpa. (44)
20:45:53.346747 IP c-68-54-80-123.hsd1.md.comcast.net.10870 > 192.168.1.100.57211: Flags [P.], seq 1448:2896, ack 1, win 256, options [nop,nop,TS val 4793015 ecr 6885157], length 1448
Faz com que o sniffer capture apenas os pacotes que chegarem ou saírem da interface eth0. Também podemos ver que mais detalhes foram adicionados à saída. Por padrão, o TCPDump exibe uma linha de texto para cada pacote capturado e a primeira coluna desta linha (20:45:53.332881) exibe a hora exata da captura do pacote. Depois, temos o nome do protocolo (nos exemplos acima, IP). Infelizmente, o TCPDump não consegue diferenciar muito bem os protocolos e reconhece apenas alguns deles. Por exemplo, um stream FTP ou um acesso à um site via HTTP aparecerá na linha de comando como “IP”. Porém, ele reconhece streams TCP e mensagens ARP, além de vários outros protocolos.
Aqui cabe uma nota rápida: se você quer saber quais interfaces o TCPDump aceitaria usar para fazer a sua captura, execute o comando “tcpdump -D”.
Depois disso, nós vemos os endereços IP de origem e destino e as portas utilizadas na transmissão de dados. Note que o TCPDump não utiliza “:” para separar o endereço IP do número de porta, ele utiliza apenas um “.”: IP 192.168.1.100.51921. O sinal de “>” indica a direção do fluxo. Então
20:45:53.332969 IP host-89-230-141-177.inowroclaw.mm.pl.26883 > 192.168.1.100.50677
Indica um fluxo originado em host-89-230-141-177.inowroclaw.mm.pl com destino ao host 192.168.1.100, que é o endereço do meu desktop.
Preste atenção na saída anterior, o TCPDump resolveu nomes DNS antes de mostrá-los a você. Se houver algum problema com a resolução do nome (por exemplo, um delay muito alto na rede) isso pode fazer com que o TCPDump deixe de mostrar alguns pacotes na saída enquanto espera a resolução do nome de algum IP. Para fazer com que o TCPDump não tente resolver qualquer nome DNS você deve utilizar o switch “-n”:
# tcpdump -i eth0 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on p35p1, link-type EN10MB (Ethernet), capture size 65535 bytes
20:57:11.225932 IP 192.168.1.100.60626 > 67.161.74.163.62397: Flags [F.], seq 285486535, ack 4125746745, win 18760, options [nop,nop,TS val 7564857 ecr 100610157], length 0
20:57:11.226968 IP 192.168.1.100.54334 > 70.70.132.176.44822: Flags [P.], seq 474260316:474260443, ack 405907353, win 229, options [nop,nop,TS val 7564858 ecr 740211622], length 127
20:57:11.227053 IP 192.168.1.100.35401 > 92.193.51.67.29828: Flags [P.], seq 450717029:450717043, ack 2807625402, win 245, options [nop,nop,TS val 7564858 ecr 11371786], length 14
A saída do comando fica visivelmente mais rápida do que quando ele tenta resolver nomes. Isso é muito importante quando você está capturando um fluxo muito grande de pacotes para analisar posteriormente, como por exemplo durante um ataque DDoS. Como em qualquer outro comando, você também pode juntar os switches:
# tcpdump -ni eth0 # produz exatamente a mesma saída que o comando anterior.
Existe também o switch “-nn” que faz com que o TCPDump não tente resolver nomes de protocolos e portas. Por exemplo, se o ID do protocolo for 6 ele não vai imprimir TCP, mas sim “6″. No caso de portas, no caso da porta 80 ele não vai imprimir www, mas sim 80. Isso não diminui significativamente o desempenho da captura, então isso vai depender da sua preferência. Não confunda -nn com -n! Para usar ambos no mesmo comando:
# tcpdump -nn -ni eth0
Assim, nomes DNS, nomes de protocolo ou porta não serão resolvidos. Apenas seus números serão exibidos.
Quando você faz uma captura nem sempre quer guardar todos os pacotes que passaram pelo sniffer. Provavelmente, você só vai querer gravar os pacotes gerados por um host X com destino ao host Y ou um pacote destinado à porta Z.
Neste quesito o TCPDump é extremamente flexível e vai ser de grande ajuda para você não fazer capturas gigantescas que irão levar horas para analisar!
Primeiro, vamos aprender a filtrar por host. Digamos, que você quer ver apenas o tráfego gerado/recebido pelo host 192.168.1.100. Neste caso, basta usar o comando “host”:
# tcpdump -nn -ni eth0 host 192.168.1.100
Assim, em qualquer pacote no qual o host 192.168.1.100 esteja envolvido (seja recebendo, seja enviando) o TCPDump irá capturar o pacote e exibí-lo. Mas, e se você só quisesse os pacotes destinados ao host 192.168.1.100? Usaria também o comando “src” assim:
# tcpdump -nn -ni eth0 src host 192.168.1.100
Pronto, assim a captura se restringe exclusivamente aos pacotes originados no host 192.168.1.100. Para inverter esta lógica, ou seja, capturar pacotes cujo destino é o 192.168.1.100:
# tcpdump -nn -ni eth0 dst host 192.168.1.100
Estas duas opções já diminuem muito a quantidade de pacotes capturados. Mas podemos ser ainda mais específicos. Por exemplo, usando port, dst port e src port podemos especificar também as portas. Assim, para capturar pacotes originados no host 192.168.1.100 com destino à porta 80 de qualquer outro host:
# tcpdump -nn -ni eth0 src host 192.168.1.100 and dst port 80
Note que, neste caso, começamos a precisar dos operadores lógicos (and, or). O “and” faz com que o TCPDump só capture os pacotes onde ambas as condições forem verdadeiras (o pacote deve ter saído de 192.168.1.100 E ter como destino a porta 80). Se usássemos o “or”, qualquer pacote onde pelo menos uma das duas condições fossem verdadeiras seria capturado. Por exemplo, a linha abaixo captura pacotes originados no host 192.168.1.100 OU com destino à porta 80:
# tcpdump -nn -ni eth0 src host 192.168.1.100 or dst port 80
Bem simples, não? Para especificar um host é a mesma coisa. Por exemplo, a linha abaixo vai capturar qualquer pacote que envolva os hosts 192.168.1.100 ou 192.168.1.101:
# tcpdump -nn -ni eth0 host 192.168.1.100 or host 192.168.1.101
Vale lembrar também que você pode utilizar nomes de domínio:
# tcpdump -i eth0 dst host www.google.com.br
Assim, iremos capturar todos os pacotes com destino ao site google.com.br.
Você também pode negar um host, excluindo apenas os hosts que você especificar da captura. A seguinte linha:
# tcpdump -nn -ni eth0 not host 192.168.1.101
Não irá capturar nada relacionado ao host 192.168.1.101, porém irá capturar todo o resto já que não adicionamos mais nenhum outro filtro. Para fazer um filtro melhor, utilize os outros comandos que já vimos anteriormente.
Claro que esta lista não contém todas as possibilidades que o TCPDump oferece, mas vai te dar uma boa base para começar a brincar com ele.
Não vai te ajudar muito apenas olhar o stream de pacotes todo na sua tela. Por isso, é importante que você armazene todos esses dados em um arquivo para que você possa analisar tudo com calma depois, identificando qual o problema.
No TCPDump isso é feito simplesmente usando a flag -w:
# tcpdump -nn -ni eth0 not host 192.168.1.101 -w /tmp/captura.pcap
Isso irá escrever todos os pacotes capturados no arquivo /tmp/captura.pcap. Este é um arquivo binário (escrever em um arquivo binário é mais rápido que escrever em um arquivo texto puro, evitando que o sniffer perca pacotes enquanto espera o fluxo ser salvo no arquivo), portanto não adianta você tentar lê-lo utilizando um editor de textos normal ou mesmo um comando como o cat, por exemplo. Você precisa de um software que saiba ler este arquivo como o próprio TCPDump ou o Wireshark (o qual não vou ensiná-lo a usar neste texto. Porém, existe muita documentação na Internet).
Depois que você escrever um arquivo binário com a captura, pode lê-lo utilizando a opção -r do TCPDump:
# tcpdump -r /tmp/captura.pcap
Lembre-se que aí estão os pacotes em si, não apenas aquele output que aparece na sua tela quando você executa o TCPDump. Portanto, PELO AMOR DE DEUS não pense que apenas redirecionar o output do TCPDump para um arquivo (seja da maneira que for) é uma captura de pacotes. Neste caso não haveria pacote nenhum, apenas um fluxo de texto puro.
Quando você fizer o TCPDump ler um arquivo, você também pode aplicar alguns switches para mudar um pouco o comportamento dele. Por exemplo, você pode usar a opção -XX para imprimir tanto o conteúdo do pacote e também o seu cabeçalho. Por exemplo:
# tcpdump -r /tmp/captura.pcap -XX
reading from file /tmp/captura.pcap, link-type EN10MB (Ethernet)
21:46:37.127671 IP 192.168.1.100.43532 > 95.215.62.5.http: UDP, length 16
0×0000: d85d 4cd9 70f6 001e 90fa d599 0800 4500 .]L.p………E.
0×0010: 002c 0000 4000 4011 dad8 c0a8 0164 5fd7 .,..@.@……d_.
0×0020: 3e05 aa0c 0050 0018 f0dc 0000 0417 2710 >….P……..’.
0×0030: 1980 0000 0000 8519 3adb ……..:.
21:46:37.385254 IP 192.168.1.100.43532 > 95.215.62.5.http: UDP, length 176
0×0000: d85d 4cd9 70f6 001e 90fa d599 0800 4500 .]L.p………E.
0×0010: 00cc 0000 4000 4011 da38 c0a8 0164 5fd7 ….@.@..8…d_.
0×0020: 3e05 aa0c 0050 00b8 8ac8 2342 0517 de41 >….P….#B…A
0×0030: 50ff 0000 0002 8519 3adc a901 95a9 900a P…….:…….
0×0040: d620 8dfe 9bc9 3787 3cfd fce8 0fcc dfa7 ……7.<…….
0×0050: 7e6f 43ed 4f83 14ad 5950 933d 67ca 4d96 ~oC.O…YP.=g.M.
0×0060: fe73 adec 2d0f 8dfc 776d 07f4 9587 d05c .s..-…wm…..\
0×0070: 454a a436 4109 ccce 06e4 2f01 022a 9b1a EJ.6A…../..*..
0×0080: 71e7 ea62 4e3f 8255 0093 60dc 2504 e250 q..bN?.U..`.%..P
0×0090: f906 c69e b4e9 de96 754b 6fe1 d939 1fc1 ……..uKo..9..
0x00a0: 4ff8 45f8 72d5 a8da 34d3 5309 3265 c54f O.E.r…4.S.2e.O
0x00b0: 8d3f 6d67 2035 937c 12f2 1dde 14ef 351d .?mg.5.|……5.
0x00c0: 96da 0ed2 39c1 94aa 4e7a fa2a a8d1 4341 ….9…Nz.*..CA
0x00d0: 3111 d2cc 3fe9 8eb3 a608 1…?…..
Assim você pode fazer uma análise ainda mais detalhada dos pacotes que você capturou. A opção -XX (ou -X, que não imprime alguns cabeçalhos de nível mais baixo) também pode ser utilizada diretamente na linha de comando, não apenas quando se está lendo um arquivo.
O TCPDump é uma ferramenta extremamente útil para analisar tráfego e solucionar problemas de rede, detectar máquinas infectadas por malware, etc. Porém, também pode ser utilizada para funções não tão nobres, como roubar senhas de conexões não cifradas. Tome cuidado quando usá-la.
Se você tem alguma sugestão, encontrou algum erro, etc. deixe um comentário!
5 Comentários
Rodrigo
06|Jun|2011 1muito legal o site tem muitos tutorias .
continue atualizando cara …
Pedro Pereira
25|Jun|2011 2Rodrigo,
Obrigado cara! Fico feliz que tenha gostado. Volte sempre :)
[]‘s
Pedro Pereira
Philipp
28|Sep|2011 3Parabéns pelo artigo.
O que vale são sempre os parâmetros ;), muito bem explicado.
Abrac.
Dk
04|Jan|2012 4Como costumo dizer, show de bola Pedro, tutorial bem detalhado.
Parabéns pelo trabalho.
barataaway
24|Jan|2012 5Fav no blog. Conteúdo muito bom!
Parabéns!
PS: Sobre tcpdump, ferramentas como o wireshark ajudam bastante na hora de interpretar os dados capturados.
Deixe seu comentário!
Acompanhe!
Creative Commons
Esta obra escrita por Pedro Augusto de Oliveira Pereira está licensiada sob a Creative Commons Atribuição-Uso Não-Comercial-Vedada a Criação de Obras Derivadas 3.0 Brasil License.
Mais lidos
Busca
Últimas mensagens no Twitter
Posts recentes
A design creation of Design Disease
Pedro Pereira: Administrador de redes: Linux, Cisco, FreeBSD, OpenBSD. Consultoria e serviços em software livre utilizando Samba, Subversion, Postfix, OpenLDAP, Cacti, Nagios e vários outros!
Copyright © 2007 - Pedro Pereira – Consultoria Linux, Cisco, OpenBSD - is proudly powered by WordPress
InSense 1.0 Theme by Design Disease brought to you by HostGator Web Hosting.
Switch to our mobile site