Jump to content
Sign in to follow this  
gnoo

[RESOLVIDO] ARP request sem reply ??? com python Raw sockets

Recommended Posts

Saudações,

tenho andado aqui a tentar fazer um código que que faz requisições ARP e espera por um reply do host para onde foi enviado o pacote mas, nunca vem esse reply...

 

#!/usr/bin/env python3

import struct
import socket


raw = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0806))
raw.bind(("wlp3s0", socket.htons(0x0806)))


mac_local = "ff:ff:ff:ff:ff:ff"  # mac de quem envia request
ip_local = "192.168.1.7"         # ip de quem envia request
mac_dest = "ff:ff:ff:ff:ff:ff"   # mac de quem recebe request
ip_dest = "192.168.1.6"          # ip de quem recebe request

# Ethernet Header
protocolo = 0x0806             # 0x0806 protocolo  para ARP
ethernet_header = struct.pack("!6s6sH", mac_dest.encode(), mac_local.encode(), protocolo)


# ARP header

tipo_hardware = 1
tipo_protocolo = 0x0800        # IPV4
tamanho_endereco_hardware = 6   # Refere ao tamanho do endereço do MAC que é 48 bits  == 6 bytes 
tamanho_endereço_protocolo = 4  # Refere ao tamanho do endereço do ipv4 que é 32 bits == 4 bytes
operacao = 1                   # 1 = request / 2 = Reply 

envia_ip = socket.inet_aton(ip_local)
destino_ip = socket.inet_aton(ip_dest)


arp_addr = struct.pack("!HHBBH6s4s6s4s",tipo_hardware, tipo_protocolo, tamanho_endereco_hardware, tamanho_endereço_protocolo, operacao, mac_local.encode(), envia_ip, mac_dest.encode(), destino_ip)


pacote = ethernet_header + arp_addr

cont = 0
while cont < 6:
    raw.send(pacote)
    cont +=1

Resultado do wireshark

475418113_Capturadeecr_2018-08-08_17-51-21.png.7dfcd0b7005b1ec7fe1768a5fc9a00aa.png

Edited by gnoo

Share this post


Link to post
Share on other sites

Qualquer coisa que não está bem com o meu MAC e o MAC do destinatário, provavelmente não está a ser devidamente empacotado e eu não percebo porquê, apesar de eu estar a passar o meu mac correto o wireshark, o MAC do destinatário que vai no pacote deveria ser ff:ff:ff:ff:ff:ff:ff e não 30:30:3a:30:30:3a.

 

1006175437_Capturadeecr_2018-08-10_15-39-51.png.61f1b517ba65ffb2283c9a56e7c5f876.png

Edited by gnoo

Share this post


Link to post
Share on other sites

Saudações,

após vários momentos de   sangue, suor e lágrimas ,  e um pouquinho de Stack Overflow finalmente resolvi o meu problema...

 

habemus.jpg.fd91b012869ef1c40eb5d438370b3686.jpg

 

No código acima o que não estava a funcionar era o formato em que o meu mac_local e o mac_dest não estavam a ser bem empacotados, dai o resultado apresentado pelo pelo wireshark ser completamente diferente do meu MAC real. Isso acontecia porque estava a empacotar um endereço mac com 6 bytes quando na realidade o tamanho da string era 17 bytes (salvo erro), então só apanhava esses 6 bytes logo o mac não era empacotado na totalidade, e como o mac não estava correto ele não fazia o broadcast para a rede, sem broadcast não há resposta.

Para resolver isso tive que passar os endereço mac para byte order.

Como fazer isso?

1255201675_Capturadeecr_2018-08-11_18-45-25.png.7b1c4ef767344753be7b5c9115ea9759.png

 

O código pouco ou até mesmo nada mudou mas deixo o resultado final...

Para ver o comportamento dos pacotes enviados deve ser feito através do wireshark ou outra ferramenta que cumpra a mesma função, com filtro "arp".

 

#!/usr/bin/env python3

import struct
import socket



raw = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0806))
raw.bind(("wlp3s0", socket.htons(0x0806)))


mac_local = b'\xff\xff\xff\xff\xff\xff'        # mac de quem envia request
ip_local = "192.168.1.7"                                          # ip de quem envia request
mac_dest = b'\xff\xff\xff\xff\xff\xff'        # Endereço broadcast para que seja enviado um reply
ip_dest = "192.168.1.2"                                          # ip de quem recebe request




# Ethernet Header
protocolo = 0x0806                                                 # 0x0806 protocol to ARP
ethernet_header = struct.pack("!6s6sH", mac_dest, mac_local, protocolo)


# ARP header

tipo_hardware = 1
tipo_protocolo = 0x0800                               # IPV4
tamanho_endereco_hardware = 6            # Refere ao tamanho do endereço do MAC que é 48 bits  == 6 bytes 
tamanho_endereco_protocolo = 4            # Refere ao tamanho do endereço do ipv4 que é 32 bits == 4 bytes
operacao = 1                                                        # 1 = request / 2 = Reply 

envia_ip = socket.inet_aton(ip_local)
destino_ip = socket.inet_aton(ip_dest)


arp_addr = struct.pack("!HHBBH6s4s6s4s",tipo_hardware, tipo_protocolo, tamanho_endereco_hardware, tamanho_endereco_protocolo, operacao, mac_local, envia_ip, mac_dest, destino_ip)
pacote = ethernet_header + arp_addr


# Ciclo de repetição while é opcional 
cont = 0
while cont < 6:
    raw.send(pacote)
    cont +=1

 

Edited by gnoo
  • Haha 1

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...