Code ICMP Raw Packet in Python

Namaste Friends,



In today's tutorial, I am going to tell you about how we can create or write Raw ICMP packet using python struct module.


Introduction

ICMP stands for Internet Control Message Protocol. Icmp protocol is used to provide an error reporting and query management protocol used by various types of Internet Devices like a router.
In simple words, ICMP protocols created to do connection checking, Connection status, Device availability Etc. For Example, With the help of ICMP packet, we can easily find the availability of an IP address into our Network.


How?


Well, To Find The Find the availability of any IP address Into our network. We simply Just need to send an ICMP packet with request codes, IP address and Source IP Address and if that Specific Device contains same IP address will available on our network, it will reply with another ICMP packet that will contain its information. So, With the help of this simple techniques, we can find the availability of any IP in our network but the only condition is, Client need to reply back with ICMP packet. Actually, Almost all device like to reply on ICMP packet but because of security feature, many devices don't reply back.


Format Of ICMP Packet






Requirement


  • Python 2.x Or 3.x
  • Struct Module
  • Pye Project (Only If you want to verify Packet On Wireshark)




Simplest Form Of codes To Make A ICMP Packet


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class ICMPPacket:
    def __init__(self,
        icmp_type = ICMP_ECHO_REQUEST,
        icmp_code = 0,
        icmp_chks = 0,
        icmp_id   = 1,
        icmp_seq  = 1,
        data      ='' ,
        ):

        self.icmp_type = icmp_type
        self.icmp_code = icmp_code
        self.icmp_chks = icmp_chks
        self.icmp_id   = icmp_id
        self.icmp_seq  = icmp_seq
        self.data      = data
        self.raw = None
        self.create_icmp_field()

    def create_icmp_field(self):
        self.raw = struct.pack(ICMP_STRUCTURE_FMT,
            self.icmp_type,
            self.icmp_code,
            self.icmp_chks,
            self.icmp_id,
            self.icmp_seq,
            )

        # calculate checksum
        self.icmp_chks = self.chksum(self.raw+self.data)

        self.raw = struct.pack(ICMP_STRUCTURE_FMT,
            self.icmp_type,
            self.icmp_code,
            self.icmp_chks,
            self.icmp_id,
            self.icmp_seq,
            )

        return 

    def chksum(self, msg):
        s = 0       # Binary Sum

        # loop taking 2 characters at a time
        for i in range(0, len(msg), 2):

            a = ord(msg[i]) 
            b = ord(msg[i+1])
            s = s + (a+(b << 8))
            
        
        # One's Complement
        s = s + (s >> 16)
        s = ~s & 0xffff

        return s


Explanation



  • __init__ function to take inputs.
  • create_icmp_feild function to make an ICMP packet structure
  • check_sum function is to calculate packet checksum value






Another Simplest Form To Make ICMP Packet Extractor


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# ICMP HEADER Extraction
def ext_icmp_header(data):
    icmph=struct.unpack(ICMP_STRUCTURE_FMT, data)
    data={
    'type'  :   icmph[0],
    "code"  :   icmph[1],
    "checksum": icmph[2],
    'id'    :   icmph[3],
    'seq'   :   icmph[4],
    }
    return data


Complete Codes  (Need Pye Project Scripts To Run it Correctly.



  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
# import modules
import struct
import socket
from IP import LoadIP
from Ether import EtherPacket

# Header is type (8), code (8), checksum (16), id (16), sequence (16)
#    header = struct.pack('bbHHh', ICMP_ECHO_REQUEST, 0, 0, id, 1)
ICMP_STRUCTURE_FMT = 'bbHHh'
ICMP_ECHO_REQUEST = 8 # Seems to be the same on Solaris.

ICMP_CODE = socket.getprotobyname('icmp')
ERROR_DESCR = {
    1: ' - Note that ICMP messages can only be '
       'sent from processes running as root.',
    10013: ' - Note that ICMP messages can only be sent by'
           ' users or processes with administrator rights.'
    }


class ICMPPacket:
    def __init__(self,
        icmp_type = ICMP_ECHO_REQUEST,
        icmp_code = 0,
        icmp_chks = 0,
        icmp_id   = 1,
        icmp_seq  = 1,
        data      ='' ,
        ):

        self.icmp_type = icmp_type
        self.icmp_code = icmp_code
        self.icmp_chks = icmp_chks
        self.icmp_id   = icmp_id
        self.icmp_seq  = icmp_seq
        self.data      = data
        self.raw = None
        self.create_icmp_field()

    def create_icmp_field(self):
        self.raw = struct.pack(ICMP_STRUCTURE_FMT,
            self.icmp_type,
            self.icmp_code,
            self.icmp_chks,
            self.icmp_id,
            self.icmp_seq,
            )

        # calculate checksum
        self.icmp_chks = self.chksum(self.raw+self.data)

        self.raw = struct.pack(ICMP_STRUCTURE_FMT,
            self.icmp_type,
            self.icmp_code,
            self.icmp_chks,
            self.icmp_id,
            self.icmp_seq,
            )

        return 

    def chksum(self, msg):
        s = 0       # Binary Sum

        # loop taking 2 characters at a time
        for i in range(0, len(msg), 2):

            a = ord(msg[i]) 
            b = ord(msg[i+1])
            s = s + (a+(b << 8))
            
        
        # One's Complement
        s = s + (s >> 16)
        s = ~s & 0xffff

        return s


# ICMP HEADER Extraction
def ext_icmp_header(data):
    icmph=struct.unpack(ICMP_STRUCTURE_FMT, data)
    data={
    'type'  :   icmph[0],
    "code"  :   icmph[1],
    "checksum": icmph[2],
    'id'    :   icmph[3],
    'seq'   :   icmph[4],
    }
    return data

def main():
    icmp = ICMPPacket()
    print ext_icmp_header(icmp.raw)
    ip = LoadIP(tcp=icmp, ip_proto=socket.IPPROTO_ICMP)
    eth = EtherPacket(data=ip)

    
    try:
        from samples.wsk import ShowPacket
        pkt = eth.raw +ip.raw+icmp.raw
        ShowPacket([pkt], link_type=1)
    except Exception as e:
        print e
        print "[+] Unable To Find pye.samples.wsk script."
    return


if __name__=='__main__':
    main()



I hope you enjoy this tutorial.

Keep Reading and
have a nice day.

Share this

Related Posts

Previous
Next Post »