Try sending a SYN packet in Python

Python script that sends SYN packets

This is a memo because I wrote a Python script that sends a SYN packet that is sent when establishing a connection with TCP.

syn.py


import socket, struct
from ctypes import *


SRC_IP = "127.0.0.1"
DST_IP = "127.0.0.1"

SRC_PORT = 1234
DST_PORT = 5678

WINDOWSIZE = 512


class tcphdr(Structure):
    _fields_ = [
            ("src_port", c_uint16),
            ("dst_port", c_uint16),
            ("seq", c_uint32),
            ("ack_seq", c_uint32),
            ("res1", c_uint16, 4),#little endian. from here 
            ("doff", c_uint16, 4),
            ("fin", c_uint16, 1),
            ("syn", c_uint16, 1),
            ("rst", c_uint16, 1),
            ("psh", c_uint16, 1),
            ("ack", c_uint16, 1),
            ("urg", c_uint16, 1),
            ("ece", c_uint16, 1),
            ("cwr", c_uint16, 1),#to here

            #("doff", c_uint16, 4),#big endian. from here
            #("res1", c_uint16, 4),
            #("cwr", c_uint16, 1),
            #("ece", c_uint16, 1),
            #("urg", c_uint16, 1),
            #("ack", c_uint16, 1),
            #("psh", c_uint16, 1),
            #("rst", c_uint16, 1),
            #("syn", c_uint16, 1),
            #("fin", c_uint16, 1),#to here

            ("window", c_uint16),
            ("check", c_uint16),
            ("urg_ptr", c_uint16),
            ]

    def pack(self):
        return buffer(self)[:]


class dummy_iphdr(Structure):
    _fields_ = [
            ("src_ip", c_uint32),
            ("dst_ip", c_uint32),
            ("pad", c_uint8),
            ("protocol", c_uint8),
            ("len", c_uint16),
            ]

    def pack(self):
        return buffer(self)[:]


def ip2int(ip_addr):
    #return struct.unpack("!I", socket.inet_aton(ip_addr))[0]
    #inet_aton returns ip_addr in network byte order. so the '!' above is not required.
    return struct.unpack("I", socket.inet_aton(ip_addr))[0]


def calc_checksum(TCPheader):
    IPheader = dummy_iphdr()
    IPheader.src_ip = ip2int(SRC_IP)
    IPheader.dst_ip = ip2int(DST_IP)
    IPheader.pad = 0
    IPheader.protocol = 6
    IPheader.len = socket.htons(20)
    IPheader_packed = IPheader.pack()

    checksum = 0

    for i in xrange(len(IPheader_packed) / 2):
        temp = struct.unpack("H", IPheader_packed[:2])[0]
        checksum += temp
        IPheader_packed = IPheader_packed[2:]

    TCPheader_packed = TCPheader.pack()

    for i in xrange(len(TCPheader_packed) / 2):
        temp = struct.unpack("H", TCPheader_packed[:2])[0]
        checksum += temp
        TCPheader_packed = TCPheader_packed[2:]

    carry = (checksum >> 16) & 0xffff

    checksum = ~((checksum & 0xffff) + carry)

    return checksum


def build_tcp_syn_packet():
    TCPheader = tcphdr()

    TCPheader.src_port = socket.htons(SRC_PORT)
    TCPheader.dst_port = socket.htons(DST_PORT)

    TCPheader.seq = 1#a random number mihgt be better
    TCPheader.doff = len(TCPheader.pack()) / 4

    TCPheader.fin = 0
    TCPheader.syn = 1
    TCPheader.rst = 0
    TCPheader.psh = 0
    TCPheader.ack = 0
    TCPheader.urg = 0
    TCPheader.ece = 0
    TCPheader.cwr = 0

    TCPheader.check = 0
    TCPheader.window = socket.htons(WINDOWSIZE)
    TCPheader.urg_ptr = 0

    TCPheader.check = calc_checksum(TCPheader)

    return TCPheader


def send_syn_packet():
    syn_packet = build_tcp_syn_packet().pack()

    sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)

    sock.sendto(syn_packet, (DST_IP, DST_PORT))

    sock.close()


def main():
    send_syn_packet()


if __name__ == "__main__":
    main()

Where I was addicted

socket automatically sets the protocol number of the IP packet to TCP even if you specify 0 for the protocol number when SOCK_STREAM is specified for the socket type, but explicitly when SOCK_RAW is specified. It seems that you need to specify IPPROTO_TCP.

I was addicted to the part that calculates the checksum. It didn't work because inet_aton returned the network byte order, but unpacked it again to the network byte order (was it the native byte order after all?).

Finally

After I finished writing, I found a cooler Python script (http://www.binarytides.com/python-syn-flood-program-raw-sockets-linux/).

reference

http://telracsmoratori.blog.fc2.com/blog-entry-116.html https://ja.wikipedia.org/wiki/Transmission_Control_Protocol

Recommended Posts

Try sending a SYN packet in Python
Try drawing a simple animation in Python
Try a functional programming pipe in Python
Try gRPC in Python
Try 9 slices in Python
Try to calculate a statistical problem in Python
Take a screenshot in Python
Try to make a Python module in C language
Create a dictionary in Python
Try searching for a million character profile in Python
Try embedding Python in a C ++ program with pybind11
Try LINE Notify in Python
Make a bookmarklet in Python
Try implementing Yubaba in Python 3
Draw a heart in Python
Try running python in a Django environment created with pipenv
Try creating a Deep Zoom file format .DZI in Python
Try building a neural network in Python without using a library
Try running a function written in Python using Fn Project
Just try to receive a webhook in ngrok and python
Write a binary search in Python
Hit a command in Python (Windows)
Try throwing a query in Redash
Create a DI Container in Python
Draw a scatterplot matrix in python
Try implementing extension method in python
ABC166 in Python A ~ C problem
Write A * (A-star) algorithm in Python
Try using LevelDB in Python (plyvel)
Let's try Fizz Buzz in Python
Create a binary file in Python
Try to calculate Trace in Python
Try PLC register access in Python
Solve ABC036 A ~ C in Python
Write a pie chart in Python
Write a vim plugin in Python
Write a depth-first search in Python
Implementing a simple algorithm in Python 2
Create a Kubernetes Operator in Python
Solve ABC037 A ~ C in Python
Run a simple algorithm in Python
Draw a CNN diagram in Python
Create a random string in Python
Try using Leap Motion in Python
Schedule a Zoom meeting in Python
When writing a program in Python
Try to get a list of breaking news threads in Python.
Try python
Generate a first class collection in Python
Spiral book in Python! Python with a spiral book! (Chapter 14 ~)
Solve ABC175 A, B, C in Python
Try logging in to qiita with Python
Try using the Wunderlist API in Python
A simple HTTP client implemented in Python
Do a non-recursive Euler Tour in Python
Try using the Kraken API in Python
I made a payroll program in Python!
Precautions when pickling a function in python
Write the test in a python docstring
Try working with binary data in Python
Display a list of alphabets in Python 3