Code To Create TCP packet header with Python socket module

Namaste Hackers,



Today, In this tutorial I am going to show you how you can easily create a raw TCP packet using python socket module and struct module.


Friend, If You Are New on our Blog, Then Don't Forget To Follow Us On Social Media Because We Create These Types of Tutorials in Every Small Gap of the week and of course, with social media, you can easily get updates of this blog or you can also directly connect with me on facebook.

In today's module basically, we going to play with socket modules. so, To Make you skill more familiar with python and socket module. You Can Also Read Our Other Networking Posts Also.




Or You Can Also Check Our Complete Project List Here


Introduction

As we know, Many times for large networking project we have to write codes for creating raw networking packets without using any external libraries or modules And at that time, to accomplish our work we have to play with binary level data.
By the way, TCP packets are the most important packets to established a secure connection between client and server. Without TCP handshake, a client and server can't establish a secure connection. so this reason also makes more solid pressure to understand TCP concept briefly. So, Basically, In Today's tutorial, I am going to show you how you can easily create TCP header packets with socket and struct module. This tutorial will give you important and structural knowledge of TCP packets and python struct module methods. How we can use python for networking packets analyzing, creating, manipulation etc.


Requirements


1. Python 2.x Or Python 3.x
2. Linux
3. Python Socket and Struct
4. Wireshark (For Verifying Create TCP Packet)


How it's going to work?


As we know, python is not that much compatible with binary number operations if compared to C language but yes, there are some modules that provide us the facilities to play with binary level concepts. well, here struct module is our life-saving module which provides us the facility to play with the binary network packet. I am assuming that you all are already aware of python struct module and python socket module. Basically, we just going to create a TCP packet using struct module and then send it using python socket module.

TCP Packet Structure.

Before Starting Our Example Codes, Take a look at this diagram.



This diagram is a representation of TCP Header Packet Structure. As you can see in this diagram there are various types of field, flags are available in TCP header packet. so, we going to load all these fields into our TCP packet structure to make it real.

Ooh yes, another noticeable topic in TCP packet is its CheckSum field and because Checksum of TCP packet is a very interesting topic. I created a separate post on it. check it here

Basically, To calculate the Checksum of TCP packet first we have to assemble all the data of TCP packet where set checksum value equal to Zero. then, create a pseudo packet that contains various pieces of information from all over the packet header after that follow checksum algorithms to find the correct hash value. (Don't know about Pseudo Concept. Check it here)

 Now, let's move to practical codes that will provide you more understanding of today's concept


Step 1

Let's try to understand with a simple example. Basically Here In preview codes, first import modules and then, I created a simple starting structure for python class object. In it's initialized function, we will take five arguments from the user, arguments are destination Port, destination IP address, source IP address, source port and TCP Raw Data to calculate correct checksum.


#!/usr/bin/python
import socket
import struct


class TCPPacket:
 def __init__(self, dport = 80, sport = 65535, dst='127.0.0.1', src='192.168.1.101', data = 'Nothing'):
  self.dport = dport
  self.sport = sport
  self.src_ip = src
  self.dst_ip = dst
  self.data   = data
  self.raw = None
  self.create_tcp_feilds()


Step 2

As I already mention TCP Diagram above, here in this function we are going to create all required fields with possible Default values and store it in the self container so that in next function we can directly access this data to assemble and create TCP packet structure.

To make my codes more easy to understand I tried to use maximum comments in codes to make it more simple for you.
I hope now you all are getting what I have done in these codes.


 def create_tcp_feilds(self):

  # ---- [ Source Port ]
  self.tcp_src = self.sport

  # ---- [ Destination Port ]
  self.tcp_dst = self.dport

  # ---- [ TCP Sequence Number]
  self.tcp_seq = 0

  # ---- [ TCP Acknowledgement Number]
  self.tcp_ack_seq = 0

  # ---- [ Header Length ]
  self.tcp_hdr_len = 80

  # ---- [ TCP Flags ]
  tcp_flags_rsv = (0 << 9)
  tcp_flags_noc = (0 << 8)
  tcp_flags_cwr = (0 << 7)
  tcp_flags_ecn = (0 << 6)
  tcp_flags_urg = (0 << 5)
  tcp_flags_ack = (0 << 4)
  tcp_flags_psh = (0 << 3)
  tcp_flags_rst = (0 << 2)
  tcp_flags_syn = (1 << 1)
  tcp_flags_fin = (0)

  self.tcp_flags = tcp_flags_rsv + tcp_flags_noc + tcp_flags_cwr + \
        tcp_flags_ecn + tcp_flags_urg + tcp_flags_ack + \
        tcp_flags_psh + tcp_flags_rst + tcp_flags_syn + tcp_flags_fin

  # ---- [ TCP Window Size ]
  self.tcp_wdw = socket.htons (5840)

  # ---- [ TCP CheckSum ]
  self.tcp_chksum = 0

  # ---- [ TCP Urgent Pointer ]
  self.tcp_urg_ptr = 0


  return



Step  3

Assemble All Feilds with the help of struct module and create a TCP Binary Packet Structure. I hope my comments are providing you hints to understand these codes. (if struct module looks hard to you, comment below I will make a tutorial on it.)
Basically, In current function, we just creating a temporarily TCP packet with Checksum value 0 so that in next functions we can calculate right checksum value with the help of pseudo concept and then reassemble all this data to make a valid TCP packet structure.


 def assemble_tcp_feilds(self):
  self.raw = struct.pack('!HHLLBBHHH', # Data Structure Representation
   self.tcp_src,   # Source IP
   self.tcp_dst,    # Destination IP
   self.tcp_seq,    # Sequence
   self.tcp_ack_seq,  # Acknownlegment Sequence
   self.tcp_hdr_len,   # Header Length
   self.tcp_flags ,    # TCP Flags
   self.tcp_wdw,   # TCP Windows
   self.tcp_chksum,  # TCP cheksum
   self.tcp_urg_ptr # TCP Urgent Pointer
   )

  self.calculate_chksum() # Call Calculate CheckSum
  return



Step 4

In this function, we going to create a pseudo frame that will help us to calculate right checksum value. For more detail about Pseudo Concept. Check it here


 def calculate_chksum(self):
  src_addr     = socket.inet_aton( self.src_ip )
  dest_addr    = socket.inet_aton( self.dst_ip )
  placeholder  = 0
  protocol     = socket.IPPROTO_TCP
  tcp_len      = len(self.raw) + len(self.data)
 
  psh = struct.pack('!4s4sBBH' , 
   src_addr ,    # Source Address  
   dest_addr ,   # Destination Address 
   placeholder , # Placeholder
   protocol ,    # Protocol 
   tcp_len       # Length of pseudo + Demo TCP header + Data 
   )

  psh = psh + self.raw + self.data

  self.tcp_chksum = self.chksum(psh) # call CheckSum calculation function
  
  self.reassemble_tcp_feilds()       # finally, reassemble all peice of information
  
  return 



Step 5

Algorithms to Calculate The Checksum of TCP header Packet. For Details check it here


 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


Step 6

After finding the correct checksum value of the pseudo header, it's time to again reassemble all piece of information into a binary packet structure to make a valid TCP packet. Of course, below function is responsible for it.

 def reassemble_tcp_feilds(self):
  self.raw = struct.pack('!HHLLBBH', 
   self.tcp_src, 
   self.tcp_dst, 
   self.tcp_seq, 
   self.tcp_ack_seq, 
   self.tcp_hdr_len, 
   self.tcp_flags , 
   self.tcp_wdw
   )+
  struct.pack("H", 
   self.tcp_chksum
   )+
  struct.pack('!H', 
   self.tcp_urg_ptr
   )
  return



Finally

Final Preview To Understand Actually How Our Class Object Code looks like


#!/usr/bin/python
import socket
import struct


class TCPPacket:
 def __init__(self, dport = 80, sport = 65535, dst='127.0.0.1', src='192.168.1.101', data = 'Nothing'):
  self.dport = dport
  self.sport = sport
  self.src_ip = src
  self.dst_ip = dst
  self.data   = data
  self.raw = None
  self.create_tcp_feilds()

 def assemble_tcp_feilds(self):
  self.raw = struct.pack('!HHLLBBHHH', # Data Structure Representation
   self.tcp_src,   # Source IP
   self.tcp_dst,    # Destination IP
   self.tcp_seq,    # Sequence
   self.tcp_ack_seq,  # Acknownlegment Sequence
   self.tcp_hdr_len,   # Header Length
   self.tcp_flags ,    # TCP Flags
   self.tcp_wdw,   # TCP Windows
   self.tcp_chksum,  # TCP cheksum
   self.tcp_urg_ptr # TCP Urgent Pointer
   )

  self.calculate_chksum() # Call Calculate CheckSum
  return


 def reassemble_tcp_feilds(self):
  self.raw = struct.pack('!HHLLBBH', 
   self.tcp_src, 
   self.tcp_dst, 
   self.tcp_seq, 
   self.tcp_ack_seq, 
   self.tcp_hdr_len, 
   self.tcp_flags , 
   self.tcp_wdw
   )+
  struct.pack("H", 
   self.tcp_chksum
   )+
  struct.pack('!H', 
   self.tcp_urg_ptr
   )
  return

 def calculate_chksum(self):
  src_addr     = socket.inet_aton( self.src_ip )
  dest_addr    = socket.inet_aton( self.dst_ip )
  placeholder  = 0
  protocol     = socket.IPPROTO_TCP
  tcp_len      = len(self.raw) + len(self.data)
 
  psh = struct.pack('!4s4sBBH' , 
   src_addr , 
   dest_addr , 
   placeholder , 
   protocol , 
   tcp_len
   )

  psh = psh + self.raw + self.data

  self.tcp_chksum = self.chksum(psh)
  
  self.reassemble_tcp_feilds()
  
  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

 def create_tcp_feilds(self):

  # ---- [ Source Port ]
  self.tcp_src = self.sport

  # ---- [ Destination Port ]
  self.tcp_dst = self.dport

  # ---- [ TCP Sequence Number]
  self.tcp_seq = 0

  # ---- [ TCP Acknowledgement Number]
  self.tcp_ack_seq = 0

  # ---- [ Header Length ]
  self.tcp_hdr_len = 80

  # ---- [ TCP Flags ]
  tcp_flags_rsv = (0 << 9)
  tcp_flags_noc = (0 << 8)
  tcp_flags_cwr = (0 << 7)
  tcp_flags_ecn = (0 << 6)
  tcp_flags_urg = (0 << 5)
  tcp_flags_ack = (0 << 4)
  tcp_flags_psh = (0 << 3)
  tcp_flags_rst = (0 << 2)
  tcp_flags_syn = (1 << 1)
  tcp_flags_fin = (0)

  self.tcp_flags = tcp_flags_rsv + tcp_flags_noc + tcp_flags_cwr + \
        tcp_flags_ecn + tcp_flags_urg + tcp_flags_ack + \
        tcp_flags_psh + tcp_flags_rst + tcp_flags_syn + tcp_flags_fin

  # ---- [ TCP Window Size ]
  self.tcp_wdw = socket.htons (5840)

  # ---- [ TCP CheckSum ]
  self.tcp_chksum = 0

  # ---- [ TCP Urgent Pointer ]
  self.tcp_urg_ptr = 0


  return




Run


To Run Above, Just Copy These Code In The End Of script.


if __name__=='__main__':
        # Create Raw Socket
 s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)

 tcp = TCPPacket()
 tcp.assemble_tcp_feilds()

 s.sendto(tcp.raw, ('127.0.0.1' , 0 ))
 

Run it With Sudo permission.

In Linux:

:~# sudo script/name/path.py


I hope you enjoyed this tutorial.
for any suggestion or query
comment below.


have a nice day.

Share this

Related Posts

Previous
Next Post »