Aprenda a usar o sniffer Wireshark (Parte IV)

18 Comentários

Ao longo dos anos, fomos apresentando no Pplware as várias versões e respectivas novidades do sniffer mais popular para redes informáticas, o Wireshark. O Wireshark é uma ferramenta de analise protocolar, que permite a captação, em tempo real, de pacotes de dados, e apresenta essa informação num formato legível para os utilizadores. O processo de captura de tráfego é realizado via placa de rede,, funcionando esta num modo especial que é designado de modo promíscuo (possibilidade de capturar todos os pacotes, independentemente do endereço de destino).

Depois de termos apresentado aqui algumas funcionalidades básicas do wireshark, Esquema de cores nas linhas e Follow TCP Stream aqui, e ensinar a detectar tráfego abusivo, hoje vamos ensinar como podem ver o processo de Three-way Handshake, responsável pelo estabelecimento de ligações TCP.

wired_000

O TCP é o protocolo mais usado isto porque fornece garantia na entrega de todos os pacotes entre um PC emissor e um PC receptor. Dentro de um segmento TCP existem vários campos e hoje destacamos os campos  ACK e SYN que são usados no inicio de uma comunicação TCP.

  • SYN – Se activo, indica um pedido de estabelecimento de ligação e a confirmação da ligação;
  • ACK – Se activo, o campo Número de Confirmação deve ser interpretado;
tcp_00
Mas o que é Three Way Handshake?

No estabelecimento de ligação entre emissor e receptor existe um “pré-acordo” denominado de Three Way Handshake (SYN, SYN-ACK, ACK).

  • A sessão entre um cliente e um servidor é sempre iniciada pelo cliente, que envia um pedido de ligação pacote com a flag SYN activada.
  • O cliente envia também um numero sequencial aleatório
  • O servidor responde com um pacote SYN,ACK com o seu próprio numero sequencial aleatório e um numero de confirmação (igual ao numero sequencial do cliente +1)
  • Para finalizar o cliente responde com um pacote ACK com o numero de confirmação (igual ao numero de sequência do servidor +1)

Na prática, temos mais ou menos isto…

way_02

Vamos a um exemplo prático?

Vamos considerar então uma ligação da nossa máquina para o site Pplware.

Primeira Fase (SYN)

O cliente (192.168.1.123) envia um pedido de sincronização (SYN) para o Pplware.com. Tal segmento tem como numero de sequencia 0 (zero).

syn

Segunda Fase (SYN, ACK)

O servidor responde com um pacote SYN,ACK, onde o ACK=1 (igual ao numero sequencial do cliente +1)

syn_ack

Terceira fase (ACK)

Para finalizar o cliente responde com um pacote ACK =1 e envia também o número de sincronização (Seq =1) – igual ao numero de sequência do servidor +1.

ack

Nota: Para facilitar a encontrar os registos, podem usar os seguintes filtros:

  • Filtro 1: tcp.flags.syn == 1 && tcp.flags.ack == 0
  • Filtro 2: tcp.flags.syn == 1 && tcp.flags.ack == 1
  • Filtro 3: tcp.seq == 1 && tcp.ack == 1 && tcp.len == 0 && !(tcp.flags.push == 1)

Nota: Para facilitar, podem também usar a funcionalidade   Follow TCP Stream. Esta funcionalidade permite visualizar streams TCP completas, isto é, com esta opção o utilizador poderá acompanhar toda uma comunicação desde o primeiro SYN até ao FIN­-ACK – ver aqui.

Esperamos que tenham gostado deste terceiro tutorial sobre o Wireshark. Por hoje resta-nos esperar pelo vosso feedback e sugestões para próximos tutoriais.

Comentários

18

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *

  1. Avatar de Nuno
    Nuno

    Muito bom e muito obrigado pela partilha 😉

    O Wireshark é uma ferramenta muito poderosa e com grande utilidade.

    Venham mais posts destes.

    Cumps

  2. Avatar de João Mário
    João Mário

    ppinto vou seguindo os teus tutoriais (seja do wireshark ou outro) e são sempre muito interessantes – parabéns
    ah, e já agora, este é o 4º tutorial, não o 3º
    (como bem colocaste no título)
    😉

  3. Avatar de Daniel Mendonça
    Daniel Mendonça

    Aulas de RCOM na FEUP. Bastante útil o software.

  4. Avatar de int3
    int3

    Eu acho mesmo interessante, é que em 10 posts no pplware apenas me interesso em 3/4 e são sempre do Pedro Pinto. É o que é mais detalhado e tem sempre algum objetivo.

    Gostei 😉

    Eu uso wireshark para throuble shooting, e por acaso já tive que aprender tudo acerca de redes a nível de Pacotes, etc etc etc, quando tirei o CCNA1 (5.0), e neste momento vou a meio do CCNA2 ! 😀

    Ah uma coisa, não sei se tenho razão.
    Quando se envia a flag SYN, o ACK que recebemos, vai ter o numero de BYTES que o ‘sender’ envia. Não sei a que refere esses bytes, não sei se é o tamanho do pacote ou outra coisa (lembro-me disto porque saíu num exame acho)

    1. Avatar de Pedro Pinto

      Boas int3

      Obrigado pelos elogios 🙂 Na verdade a área das redes é que é “algo” diferente. Escrever estas coisas dá-me um gozo tremendo…dá para partilhar o know how e também para aprender com vocês.

      Abraço Ping…reply reply

  5. Avatar de NullPointer
    NullPointer

    Muito bom. Uso este programa nas aulas de Redes de Internet no ISEL.

    1. Avatar de int3
      int3

      void* nullpointer; // 😀

  6. Avatar de Abílio
    Abílio

    Gostei, thanks

  7. Avatar de lmx
    lmx

    parabéns pelo artigo,

    esta muito bom mesmo 😉

    Já há algum tempo que não tocava nas especificidades to tcp…ainda criei em tempos um snifer em C, mas nada a ver com isto, mas mesmo nada 😀

    1. Avatar de int3
      int3

      http://i.imgur.com/l752GCd.png
      Acho que vou ficar vidrado no C++ com API do Qt 😀
      Isto é super facil, e tem parte gráfica e é drag and drop. Finalmente encontrei algo melhor que o C# da M$.

      1. Avatar de lmx
        lmx

        é muito fixe sim 😛

        Não que eu conheça a API do Qt,já dei uma olhadela, mas nunca avancei pelos meandros(pequenos excertos de código)…mas confesso que quando acabar o meu programa(Lypus Flasher ;)), e se não avançar logo para a parte gráfica, vou avançar para Qt, muito provavelmente(a parte gráfica tem que ser feita em Gtk(vai ser um plugin para o faboloso Geany), também posso usar c++, mas vou usar C, isto se avançar…prevê-jo uns próximos 6 meses apertados…)

        Eles fizeram um trabalho notável no Qt…isso é de longe superior a C#, mas de longe…a C# a java, a Visual basic(nem se fala…as possibilidades são brutais e as interfaces Gráficas lindas de morrer)!

        È um estado de arte…o Qt é mais lento que gtk a fazer o load da aplicação gráfica(mas não por ser lento…presumo que seja porque ele aguarda a renderização completa da aplicação para a mostrar completa e linda no final 😉 )….mas é muito mais consistente, e a aplicação quando é renderizada no ecran é renderizada toda de uma vez, no gtk, se a aplicação for grande…nota-se que parece que se parte toda , antes de renderizar por completo…por ser feito em C…

        Mas em aplicações opengl, nada bate o Qt a nível de frameworks 😉 o gtk fica muito para trás, talvez(quase de certeza) por causa dos massivos callbacks…

        Qt tem uma velocidade incrível…não é ao acaso que é usada no qnx aka BB10 da blackberry por exemplo, ou era usada na nokia, nos symbian(mas versões antigas)e no MEEGO(o grande SO movel que nunca avançou a sério), ou no Jolla OS, e o ubuntu salvo erro também vai avançar por ai…embora que inicialmente vão apostar num desenvolvimento mais rápido e para isso escolheram Qml, uma das linguagens do mundo Qt, para rápido desenvolvimento…mas Qt mesmo nativo 😛 é um LUXO.

        Com Qt produzes aplicações bonitas, extremamente rápidas, com um aspecto consistente, excelentes em renderização, etc, ocupando poucos recursos(c++), um luxo!!

        NÂO HÀ nada melhor actualmente!! 😉

        estes nórdicos são tramados…é quase um ano inteiro de mau tempo, etc…e eles ocupam-se de outra forma…é difícil batê-los…não há 3 ou 4 meses de praia, outros tantos de festas e fins de semana a curtir…
        isso dá-lhes uma vantagem tremenda!
        (sabias que até os novos vazes de guerra americanos são nórdicos…pois é 😀 salvo erro Noruega)

        Quando fizeres a validação das caixas de texto, valida primeiro, antes de instanciares o socket 😉 (linha 42|43|48),

        Assim se houver erros, trata-os primeiros, ou matas logo a app ou que seja, evitando teres que perder tempo a instanciares um socket para esses casos, pois estas a processar info que não vai servir para nada, estando os campos errados(por exemplo com strings, ou que seja) 😉

        torna-te a tua app mais eficiente quer a nível energético quer a nível de performance…pois esse processo pode saltar fora do processador(mesmo não acamando o seu time slice ou quantum time, ou …no mundo linux tick time) mais cedo, porque terminou….e o processador pode logo ser ocupado com outro processo 😉

        Estas a pensar em produzir uma app para o ubuntu?
        Eu ando a pensar no caso, mas se fizer, vai ser mesmo em Qt, não quero em Qml, para ser “mesmo ao puder” 😛

        Força ai 😉

        1. Avatar de int3
          int3

          respondendo à tua pergunta, esqueci-me, apenas ando a brincar com sockets. 🙂
          Mas se tivesse ideias boas fazia para ubuntu ou qualquer plataforma que suportasse libqt 🙂

      2. Avatar de int3
        int3

        ehehe deste-te trabalho a ver o meu código 😀
        e sim, fazer validações primeiro antes de começar a usar memoria a instanciar objetos para nada, é uma das formas de optimização. Por acaso não estou atento a isso, e sei que no ISEP, existe uma cadeira em programação, que tem como objetivo optimizar o código.

        O mais rápido que me vem à cabeça (visto que sou adepto das linguagens de baixo nivel) é o alinhamento da stack.
        Por exemplo:
        //struct 1
        typdef struct Pessoa{
        unsigned short int idade;
        unsigned int OutraCenaQqr;
        unsigned float peso;
        unsigned long long Horas_de_Vida; //lol xD
        char nome_completo[64];
        long int Array_Enorme[1500];
        };
        //se fizeres sizeof da estruta de cima vai-te dar
        //um tamanho diferente se primeiro declarares os
        //maiores e depois os mais pequenos, só por causa
        //do K do CPU (numero de BYTES que ‘come’ cada vez
        //que vai à memoria e é um valor fixo)
        typdef struct Pessoa{
        long int Array_Enorme[1500];
        char nome_completo[64];
        unsigned long long Horas_de_Vida; //lol xD
        unsigned float peso;
        unsigned int OutraCenaQqr;
        unsigned short int idade;
        };

        Ve aqui: http://i.stack.imgur.com/75W29.png
        Existe sempre algum espaço desperdiçado na RAM e para diminuir isso, alinha-se sempre no inicio das frames (aka funções).

        acho que deves saber do que estou a falar 😀

        E espero que o wordpress não me estrague a sintaxe do código de cima x)

        Eu em VB.NET para a escola onde eu estudei, fiz um simulador de assembly. nunca ficou completo porque terminei o curso e fui mais para a area de redes e administração de sistemas.
        Mas digo-te, que em VB só para inicializar 32MB de RAM para usar para o programa (emular-la) demorava uns 6 segundos. 64 o dobro. Mas graças a optimização cheguei a ter esses valore, porque antes disso, 32MB de RAM demorava minutos a inicializar. Até tenho um video que cheguei a mostrar a um orientador meu na altura por causa das limitaçoes do VB a gerir a memoria: https://www.youtube.com/watch?v=1ralB9zlSbI
        aqui está! 😀

        cumprs!

        1. Avatar de lmx
          lmx

          boas..

          cuidado…nem todos os processadores funcionam igual!!

          Mesmo dentro dos x86, podes encontrar algumas diferenças, com o alinhamento da memoria 😉

          http://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/

          tudo depende do processador+ a forma como o SO organiza os bancos de memoria…

          No caso acima e dado o tamanho…na minha maquina:
          sizeof(pessoa) = 12088(primeiro…desordenado)
          sizeof((PESSOA) = 12088(ordenado por ordem )

          nestes casos é muito complicado fazer analises, porque tens tamanhos brutais, e no fim de contas pode dar no mesmo 😉 …é difícil.

          Para estes casos e para garantires uma homogeneidade entre maquinas… é melhor dizer ao compilador que queres a memoria alinhada a X de bytes…
          #pragma pack(push)
          #pragma pack(4)


          Estructuras

          #pragma pack(pop)(volta ao normal da organização cpu+SO)

          No caso acima alinhado a 4 bytes…mas mesmo assim não me safo muito…
          sizeof(pessoa) = 12084
          sizeof((PESSOA) = 12084

          com alinhamento a 1 byte
          sizeof(pessoa) = 12082
          sizeof((PESSOA) = 12082

          mas aqui o compilador fica meio marado acho eu…no entanto não vou comparar tamanhos tão grandes a mão 😀 …dá uma trabalheira lol

          Mas para tipos “primitivos”(…esta palavra é meio extrangeira no C mas…), é verdade a analogia que fazes, porque começas logo com tipos alinhados de inicio, a facilidade de saires com tudo alinhado é maior 😉

          Eu também sigo essa regra, quando a ordem não me interessa…mas quando tem que andar a incrementar pointers, pode ser mais vantajoso não mexer na ordem, e nesse caso uso as directivas do compilador…na prática usuas sempre lol xD

          O tipo com maior tamanho, normalmente define o alinhamento que vai ser feito…mas mesmo aqui, existem diferenças…nesse site…tens um caso o structc_t, que deveria ser de 24 em todas as maquinas, e nos últimos processadores é de 16 :S

          Existe uma maior organização dos bancos de memória, e como existe mais optimização…acabas com menor tamanho…está lá explicado…na minha maquina sem fazer packing da-me 24…

          Ele faz uma coisa diferente…(verifica o alinhamento a 4 bytes…mesmo sabendo que a maior estructura tem 8 😉 é mais eficiente)

          sizeof(char)+padding(3 bytes e não 7!!)+ sizeof(double)+ sizeof(int)+(mais nada, porque não faz padding de 4 bytes aqui 😉 …poupa mais ram)=16 bytes
          4+8+4=16

          Em processadores mais antigos…o meu incluído fica…(neste caso, esquece..a maior tem 8 logo…todas as outras teem 8 :S independentemente do alinhamento a 4 bytes…)
          sizeof(char)+padding(7 bytes sim 7 bytes!! :S)+ sizeof(double)+ sizeof(int)+(padding de 4 bytes :S)=24 bytes
          8+8+8+8=24

          claro que se eu lhe disser(no meu caso…24bytes) para fazer um pack e alinha4 a 4 bytes(blockos de ram alinhados a 4 bytes), obtenho o mesmo resultado de procs mais recentes(16bytes) 😉

  8. Avatar de VC
    VC

    É uma excelente aplicação sem dúvida, muito útil 🙂

  9. Avatar de André
    André

    Muito bom, estou começando a user o Wireshark e esses 4 posts já me ajudaram bastante, já estou esperando os próximos.