Make ARP request on python

0x1337 picture 0x1337 · Feb 11, 2016 · Viewed 16.9k times · Source

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

Answer

L.S. picture L.S. · May 30, 2017

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.