Jump to content
Sign in to follow this  
gnoo

Análise de pacotes na prática [ Parte 7 ] - "ICMP - IPv4" - Raw Sockets python

Recommended Posts

Posted (edited)

Saudações,

Este conteúdo está sujeito a erros de interpretação por parte da minha pessoa, se vires algum erro ou achas que tens algo a acrescentar deixa nos comentários para ser corrigido/adicionado...

Os conceitos de redes aqui apresentados foram retirados desta página:

https://tools.ietf.org/html/rfc792

Para complementar a informação da página acima indicada deve ser lido este ou outro livro da especialidade:

51adpTlV5KL._SY445_QL70_.jpg.fad0bb1aacc0a143d858b86c0f634196.jpg

 

2019-06-15_21-46.png.6ba5566bb34de4317decdcef0a2257b7.png2019-06-15_21-48.thumb.png.08d3aacf7cfcd691fa756d11f9eb10af.png2019-06-15_21-49.png.db970c9074913c23fa2dc89635ad3b41.png

NOTA:  O script em python que aqui é apresentado apenas suporta os seguintes TIPOS de mensagem:

TIPO 8

TIPO 0

TIPO 11

2019-06-15_21-53.png.5e472b66f748e016bca21bc455a943d5.png

 

2019-06-15_21-54.thumb.png.b5e5da70ad4f3a36a1cfbcf5b6e49cff.png

2019-06-15_21-55.png.50b130d0896962082b9d581321805331.png

2019-06-15_21-56.thumb.png.4e759f408c9e7b663be7761891b6e350.png

SCRIPT COM PYTHON 

#coding:utf-8  
#!/usr/bin/env python3

from socket import *
import struct
import binascii

ICMP_TYPE_NUMBERS = {8:'Echo request (8)', 0:'Echo reply (0)', 11:'Time Exceeded (11)'}


def ethernet_frame(raw_dados):
    mac_destino, mac_fonte, protocolo = struct.unpack('! 6s 6s H', raw_dados[:14])

    return byte_to_hex_mac(mac_destino), byte_to_hex_mac(mac_fonte), htons(protocolo), raw_dados[14:]

def byte_to_hex_mac(mac_em_bytes):
    endereco = binascii.hexlify(mac_em_bytes).decode("ascii")
    return ":".join([endereco[i:i+2] for i in range(0,12,2)])


def dados_pacote_ipv4(payload):
    tupla_dados_ipv4 = struct.unpack("!BBHHHBBH4s4s", payload[:20])
    versao_e_HLEN = tupla_dados_ipv4[0]
    tamanho_header = (versao_e_HLEN & 15) * 4
    versao = versao_e_HLEN >> 4
    tipo_servico = tupla_dados_ipv4[1]
    tamanho_total = tupla_dados_ipv4[2]
    identificacao = tupla_dados_ipv4[3]
    offset_fragmento = tupla_dados_ipv4[4]
    tempo_vida_ttl = tupla_dados_ipv4[5]
    protocolos = tupla_dados_ipv4[6]
    checksum_cabecalho = tupla_dados_ipv4[7]
    ip_origem = inet_ntoa(tupla_dados_ipv4[8])
    ip_destino = inet_ntoa(tupla_dados_ipv4[9])
  

    dados_ipv4_header = {'Versão':versao,'Tamanho do Header':tamanho_header, 'Tipo de Serviço': tipo_servico,
           'Tamanho Pacote':tamanho_total, 'Identificação':identificacao, 'Fragmento':offset_fragmento,
           'TTL':tempo_vida_ttl, 'Protocolo':protocolos, 'Checksum':checksum_cabecalho, 'IPv4 Orivgem':ip_origem, 'IPv4 Destino':ip_destino}  
    
    return dados_ipv4_header, payload[20:]

def mensagem_time_exceeded(payload_ipv4):
    tupla_dados_icmp = struct.unpack("!BBHi", payload_ipv4[:8])
    print("Type: {} \nCode: {}\nChecksum: {}\nUnused: {}".format(ICMP_TYPE_NUMBERS[tupla_dados_icmp[0]], \
    tupla_dados_icmp[1], tupla_dados_icmp[2], tupla_dados_icmp[3]))

    header_pacote_ipv4, _ = dados_pacote_ipv4(payload_ipv4[8:29])
    print("{}\n".format(header_pacote_ipv4))


def icmp_header(tupla_dados_icmp):
    print("Type: {} \nCode: {}\nChecksum: {}\nIdentifier (BE): {}\nSequence Number (BE): {}\n".format(ICMP_TYPE_NUMBERS[tupla_dados_icmp[0]], \
    tupla_dados_icmp[1], tupla_dados_icmp[2], tupla_dados_icmp[3], tupla_dados_icmp[4]))

def dados_pacote_icmp(payload_ipv4):
    tupla_dados_icmp = struct.unpack("!BBHHH", payload_ipv4[:8])

    if tupla_dados_icmp[0] == 8 or tupla_dados_icmp[0] == 0:
        icmp_header(tupla_dados_icmp)

    elif tupla_dados_icmp[0] == 11:
        mensagem_time_exceeded(payload_ipv4)
    
    else:
        pass
        
sock = socket(AF_PACKET, SOCK_RAW, ntohs(0x0003))    

while True:
    raw_dados, addr = sock.recvfrom(65536)
    mac_destino, mac_fonte, protocolo, payload = ethernet_frame(raw_dados)

    # A variavel (protocolo) está a referir-se ao
    # tipo de frame
    # Se for 8 vem ai pacote IP \0/
    if protocolo == 8:
        dados_ipv4_header, payload_ipv4 = dados_pacote_ipv4(payload)
        if dados_ipv4_header['Protocolo'] == 1:
            dados_pacote_icmp(payload_ipv4)

 

Edited by gnoo

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...