Jump to content

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


Guest gnoo

Recommended Posts

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)

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...