Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make ARP request on python

I'm trying to make ARP request on python. My code:

import socket
from struct import pack
from uuid import getnode as get_mac

def main():
    dest_ip = [10, 7, 31, 99]
    local_mac = [int(("%x" % get_mac())[i:i+2], 16) for i in range(0, 12, 2)]
    local_ip = [int(x) for x in socket.gethostbyname(socket.gethostname()).split('.')]

    sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.SOCK_RAW)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.bind(('', 0))

    ARP_FRAME = [
        pack('!H', 0x0001), # HRD
        pack('!H', 0x0800), # PRO
        pack('!B', 0x06), # HLN
        pack('!B', 0x04), # PLN 
        pack('!H', 0x0001), # OP
        pack('!6B', *local_mac), # SHA
        pack('!4B', *local_ip), # SPA
        pack('!6B', *(0x00,)*6), # THA
        pack('!4B', *dest_ip), # TPA
    ]
    print(ARP_FRAME)
    sock.sendto(b''.join(ARP_FRAME), ('255.255.255.255', 0))
    sock.close()

if __name__ == "__main__":
    main()

When I execute this code, Wireshark does not catch any packets. I think problem in socket. When I do socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.SOCK_RAW) I get AttributeError: module 'socket' has no attribute 'AF_PACKET'. What am I doing wrong and how fix it?

OS X 10.11.3

like image 247
0x1337 Avatar asked Feb 11 '16 19:02

0x1337


People also ask

How do I make an ARP request?

Remote internet address (INTNETADR)Specifies the remote IP version 4 internet address to which the ARP requests are sent. Specify the internet address of the remote system. If the internet address is entered from a command line, the address must be enclosed in apostrophes.

What is ARP in Python?

Practical Data Science using Python ARP may be defined as a stateless protocol which is used for mapping Internet Protocol (IP) addresses to a physical machine addresses.

How is an ARP request sent?

ARP broadcasts a request packet to all the machines on the LAN and asks if any of the machines are using that particular IP address. When a machine recognizes the IP address as its own, it sends a reply so ARP can update the cache for future reference and proceed with the communication.


2 Answers

socket.AF_INET is a socket for IP packets. Since ARP is Ethernet, it won't work this way, you need access to the Ethernet layer.

On Linux, you can use:

s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3))

with s being any variable you use to assign the socket to.

To send the packet, you should bind the interface with

s.bind(("eth0", 0))

Where "eth0" is the network-interface name.

After that, you can send the packet with

s.send(packet)

with packet being your payload as bytestring.

The

AttributeError: module 'socket' has no attribute 'AF_PACKET'

is saying, that AF_PACKET is not implemented on your platform. Unfortunately Some platforms don't provide access to the low-level network layer, this is true for windows, and may be true for OS X. At least, even on linux, you need root privileges to access the low-level networking, otherwise you'll get an access denied error.

An Idea to get access to the low-level networking via Python is to use a Virtual Machine, like Virtualbox, and run a linux guest with it.

like image 134
L.S. Avatar answered Sep 28 '22 06:09

L.S.


FTR, to work around this issue you can use Scapy. It will use:

  • AF_PACKET or libpcap on unix
  • BPF on BSD
  • Winpcap/Npcap on Windows

to access the raw layer in each case, which makes it cross platform.

like image 35
Cukic0d Avatar answered Sep 28 '22 05:09

Cukic0d