Crafting Network Packets

Crafting Network Packets

In this project, I will primarily craft network packets using the SCAPY library and create a collection of these packets/frames. My goal is to build a basic traffic generator that is accessible via Python and easy to use for quick project implementation.

Crafting ICMP Packet

from scapy.all import *

# Define the destination IP address and MAC address
destination_ip = "192.168.178.1"

# Optionally define the source MAC address
source_mac = "00:11:22:33:44:55"  # Replace with your source MAC address

# Craft the Ethernet frame with the source and destination MAC addresses
ethernet_frame = Ether(src=source_mac)

# Craft the IP packet
ip_packet = IP(dst=destination_ip) / ICMP() / "Hello, this is a test packet!"

# Combine the Ethernet frame and IP packet
packet = ethernet_frame / ip_packet

# Send the packet
sendp(packet)

print(f"Packet sent to {destination_ip} with source MAC {source_mac} and destination MAC {destination_mac}")

We can play with the frequency of the sent packets with only a simple for loop.

import time
# Define the number of packets to send and the interval between packets (in seconds)
num_packets = 10
interval = 0.5  # 0.5 seconds

# Send the packets in a loop
for i in range(num_packets):
    sendp(packet)
    print(f"Packet {i+1} sent to {destination_ip} with source MAC {source_mac} and destination MAC {destination_mac}")
    time.sleep(interval)

Sending Infinite ICMP packets with higher Payload

from scapy.all import *

# Define the source and destination IP addresses and ports
source_ip = "192.168.178.236"
destination_ip = "192.168.178.33"
source_port = 12345
destination_port = 8091

# Define the payload with 1450 bytes
payload = "A" * 1450  # 1450 bytes of 'A'

# Craft the IP packet with TCP layer and the payload
ip_packet = IP(src=source_ip, dst=destination_ip) / TCP(sport=source_port, dport=destination_port) / payload

# Send the packet
while True:
    send(ip_packet)
    print(f"Packet sent from {source_ip}:{source_port} to {destination_ip}:{destination_port} with 1400 bytes of payload")

After I started the code I have checked the destination device. Here you can see the traffic amount increased

Crafting TCP Packet

from scapy.all import *

# Define the source and destination IP addresses and ports
source_ip = "192.168.178.236"
destination_ip = "192.168.178.1"
source_port = 12345
destination_port = 80

# Craft the IP packet with TCP layer
ip_packet = IP(src=source_ip, dst=destination_ip) / TCP(sport=source_port, dport=destination_port) / "Hello, this is a test packet!"

# Send the packet
send(ip_packet)

print(f"Packet sent from {source_ip}:{source_port} to {destination_ip}:{destination_port}")

Crafting UDP Packets

from scapy.all import *

# Define the source and destination IP addresses and ports
source_ip = "192.168.178.236"
destination_ip = "192.168.178.1"
source_port = 12345
destination_port = 8091

# Define the payload with 1400 bytes
payload = "A" * 1400  # 1400 bytes of 'A'

# Craft the IP packet with UDP layer and the payload
udp_packet = IP(src=source_ip, dst=destination_ip) / UDP(sport=source_port, dport=destination_port) / payload

# Send the packet in a loop
while True:
    send(udp_packet)
    print(f"Packet sent from {source_ip}:{source_port} to {destination_ip}:{destination_port} with 1400 bytes of payload")

Crafting SIP Packet

SIP (Session Initiation Protocol) is a signaling protocol used for initiating, maintaining, and terminating real-time communication sessions. SIP messages are categorized into two main types: requests and responses.

from scapy.all import *
from scapy.layers.inet import IP, UDP

# Define the source and destination IP addresses and ports
source_ip = "192.168.178.236"
destination_ip = "192.168.178.1"
source_port = 5060
destination_port = 5060

# Define the SIP INVITE message
sip_invite = (
    "INVITE sip:bob@192.168.178.1 SIP/2.0\r\n"
    "Via: SIP/2.0/UDP 192.168.178.236:5060;branch=z9hG4bK776asdhds\r\n"
    "Max-Forwards: 70\r\n"
    "To: Bob <sip:bob@192.168.178.1>\r\n"
    "From: Alice <sip:alice@192.168.178.236>;tag=1928301774\r\n"
    "Call-ID: a84b4c76e66710\r\n"
    "CSeq: 314159 INVITE\r\n"
    "Contact: <sip:alice@192.168.178.236>\r\n"
    "Content-Type: application/sdp\r\n"
    "Content-Length: 0\r\n\r\n"
)

# Craft the IP packet with UDP layer and the SIP INVITE message
sip_packet = IP(src=source_ip, dst=destination_ip) / UDP(sport=source_port, dport=destination_port) / sip_invite

# Send the packet
send(sip_packet)

print(f"SIP INVITE packet sent from {source_ip}:{source_port} to {destination_ip}:{destination_port}")

SIP Request Methods:

  • INVITE: Initiates a call or session.
  • ACK: Confirms that the client has received a final response to an INVITE request.
  • BYE: Terminates a call or session.
  • CANCEL: Cancels a pending request.
  • REGISTER: Registers the user's location with a SIP server.
  • OPTIONS: Queries the capabilities of servers.
  • PRACK: Provisional acknowledgment for reliable provisional responses.
  • SUBSCRIBE: Subscribes to an event notification.
  • NOTIFY: Notifies the subscriber of a new event.
  • PUBLISH: Publishes event state.
  • INFO: Sends mid-session information that does not modify the session state.
  • REFER: Asks the recipient to issue a SIP request (often used to transfer calls).
  • MESSAGE: Transports instant messages.
  • UPDATE: Modifies the state of a session without changing the dialog state.

Crafting Layer2 Frame with CoS modification

Class of Service (CoS) is a parameter used in Ethernet frames to differentiate and prioritize network traffic. CoS is implemented using the 802.1Q VLAN tagging standard, which includes a 3-bit field called the Priority Code Point (PCP) in the VLAN tag header. These 3 bits allow for 8 different priority levels (0-7).

CoS Priority Levels:

  • 0: Best Effort (default)
  • 1: Background
  • 2: Excellent Effort
  • 3: Critical Applications
  • 4: Video, < 100 ms latency
  • 5: Voice, < 10 ms latency
  • 6: Internetwork Control
  • 7: Network Control

CoS is used primarily in Layer 2 (Data Link Layer) to provide Quality of Service (QoS) by prioritizing certain types of traffic over others.

from scapy.all import *

# Define the source and destination MAC addresses
source_mac = "00:11:22:33:44:55"
#destination_mac = "ff:ff:ff:ff:ff:ff"  # Broadcast MAC address for demonstration

# Define the CoS value (0-7)
cos_value = 6  # Example CoS value

# Define the payload
payload = "Hello, this is a test frame with CoS value."

# Craft the Ethernet frame with 802.1Q VLAN tag and the specified CoS value
ethernet_frame = (
    Ether(src=source_mac, dst=destination_mac) /
    Dot1Q(prio=cos_value, vlan=15) /  # Set the CoS value in the prio field
    payload
)

# Send the Ethernet frame
sendp(ethernet_frame)

print(f"Ethernet frame sent with source MAC {source_mac}, destination MAC {destination_mac}, and CoS value {cos_value}")

Crafting Layer3 Packet with ToS modification

from scapy.all import *

# Define the source and destination IP addresses
source_ip = "192.168.178.236"
destination_ip = "192.168.178.1"

# Define the ToS value (0-255)
tos_value = 0x10  # Example ToS value (16 in decimal)

# Define the payload
payload = "Hello, this is a test packet with ToS value."

# Craft the IP packet with the specified ToS value and payload
ip_packet = IP(src=source_ip, dst=destination_ip, tos=tos_value) / payload

# Send the IP packet
send(ip_packet)

print(f"IP packet sent from {source_ip} to {destination_ip} with ToS value {tos_value}")

Creating CMD2 CLI Application

import cmd2
from scapy.all import *
import time

class PacketSenderCLI(cmd2.Cmd):
    prompt = "packet-sender> "

    def do_send_icmp(self, args):
        """Send ICMP packets.
        Usage: send_icmp <destination_ip> <source_mac> <num_packets> <interval>
        Example: send_icmp 192.168.178.1 00:11:22:33:44:55 10 0.5
        """
        try:
            args = args.split()
            destination_ip = args[0]
            source_mac = args[1]
            num_packets = int(args[2])
            interval = float(args[3])

            # Craft the Ethernet frame with the source MAC address
            ethernet_frame = Ether(src=source_mac)

            # Craft the IP packet
            ip_packet = IP(dst=destination_ip) / ICMP() / "Hello, this is a test packet!"

            # Combine the Ethernet frame and IP packet
            packet = ethernet_frame / ip_packet

            # Send the packets in a loop
            for i in range(num_packets):
                sendp(packet)
                print(f"Packet {i+1} sent to {destination_ip} with source MAC {source_mac}")
                time.sleep(interval)
        except Exception as e:
            print(f"Error: {e}")

    def do_send_tcp(self, args):
        """Send TCP packets.
        Usage: send_tcp <source_ip> <destination_ip> <source_port> <destination_port>
        Example: send_tcp 192.168.178.236 192.168.178.1 12345 80
        """
        try:
            args = args.split()
            source_ip = args[0]
            destination_ip = args[1]
            source_port = int(args[2])
            destination_port = int(args[3])

            # Craft the IP packet with TCP layer
            ip_packet = IP(src=source_ip, dst=destination_ip) / TCP(sport=source_port, dport=destination_port) / "Hello, this is a test packet!"

            # Send the packet
            send(ip_packet)

            print(f"Packet sent from {source_ip}:{source_port} to {destination_ip}:{destination_port}")
        except Exception as e:
            print(f"Error: {e}")

if __name__ == '__main__':
    app = PacketSenderCLI()
    app.cmdloop()