2

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() 
Ed S
  • 385
  • 8
  • 31

1 Answers1

2

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.

Pierre
  • 6,047
  • 1
  • 30
  • 49