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()
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
.