Ed S
Ed S

Reputation: 385

How can I extract TCP SYN flag from pcap file and detect SYN Flood attack using Python (Scapy)?

I'm parsing a PCAP file and I need to extract only TCP flags (SYN) for detect a SYN Flood attack. I use Python and scapy.

The main goal is a way of detecting a SYN flood attack! I need to count a number of TCP flags (SYN) for each IP address and print a list with : {IP: number of SYN flag} sorted by number of SYN flag. Could somebody help me?

# -*- coding: utf-8 -*-
from scapy.all import *
pkts = PcapReader("test.pcap")
dict_ips = dict() 

Upvotes: 2

Views: 3313

Answers (1)

Pierre
Pierre

Reputation: 6237

The best object for what you are trying to do is a Counter (from collections).

The "not-so-Pythonic" (but easier to read if you're not used to Python) way of writing this would be:

from scapy.all import PcapReader, TCP
from collections import Counter
count = Counter()
for pkt in PcapReader("test.pcap"):
    if TCP in pkt and pkt[TCP].flags & 2:  # TCP SYN packet
        src = pkt.sprintf('{IP:%IP.src%}{IPv6:%IPv6.src%}')
        count[src] += 1

It's easy to write this as a comprehension:

from scapy.all import PcapReader, TCP
from collections import Counter
count = Counter(
    pkt.sprintf('{IP:%IP.src%}{IPv6:%IPv6.src%}')
    for pkt in PcapReader('test.pcap')
    if TCP in pkt and pkt[TCP].flags & 2
)

Then, a Counter behaves like a dict object:

>>> count["1.2.3.4"]
12

But a Counter has a handy .most_common() method:

>>> count.most_common(1)
[('1.2.3.4', 12)]
>>> count.most_common()
[('1.2.3.4', 12), [...]]

As a conclusion I have to mention that Scapy has poor performances when it comes to parsing a lot of packets (and if we are talking about flood, that might be the case). If I were you, I would still use a Counter, but I would generate the sources by using a subprocess.Popen() call to tcpdump or tshark instead of Scapy's PcapReader.

Upvotes: 2

Related Questions