Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get TCP Flags with Scapy

I'm parsing a PCAP file and I need to extract TCP flags (SYN, ACK, PSH, URG, ...). I'm using the packet['TCP'].flags value to obtain all the flags at once.

pkts = PcapReader(infile)
for p in pkts:
        F = bin(p['TCP'].flags)
        print F, bin(F), p.summary()
        # manual flags extraction from F

Is there a way to obtain a single TCP flag without manually extract it from packet['TCP'].flags value?

like image 626
auino Avatar asked Dec 06 '13 17:12

auino


People also ask

How do I send a TCP SYN packet in Scapy?

Step I - Send the client's SYN to a listening server (SYN)Craft an IP header with the source and destination IP addresses. Craft a TCP header where we generate the TCP source port, assign the destination port that the server listens on, set the TCP flags to turn the SYN bit on, and generate the client's ISN.

How do I create a TCP packet in Scapy?

Creating a packet In scapy, packets are constructed by defining packet headers for each protocol at different layers of TCP/IP and then stacking these layers in order. To create a DNS query, you need to build Ether(sometimes optional), IP,UDP headers and stack them using / operator.

How do you sniff packets with Scapy?

Sniffing packets using scapy: To sniff the packets use the sniff() function. The sniff() function returns information about all the packets that has been sniffed. To see the summary of packet responses, use summary(). The sniff() function listens for an infinite period of time until the user interrupts.

Does Scapy use Libpcap?

Scapy runs natively on Linux, Windows, OSX and on most Unixes with libpcap (see scapy's installation page).


2 Answers

Normally, the usual way to handle FLAGS is with a bitmap and bitwise operators. If your Packet class doesn't have specific method to test for flags, the best thing you can do IMHO is to:

FIN = 0x01
SYN = 0x02
RST = 0x04
PSH = 0x08
ACK = 0x10
URG = 0x20
ECE = 0x40
CWR = 0x80

And test them like this:

F = p['TCP'].flags    # this should give you an integer
if F & FIN:
    # FIN flag activated
if F & SYN:
    # SYN flag activated
# rest of the flags here

Sadly, python doesn't have a switch statement to make this more elegant but it doesn't really matter much.

Hope this helps!

like image 195
Paulo Bu Avatar answered Sep 17 '22 01:09

Paulo Bu


You can use the Packet.sprintf() method:

>>> p = IP()/TCP(flags=18)
>>> p.sprintf('%TCP.flags%')
'SA'

If you want the "long" names, use a dict instead of a long if...elif... expression (dict are often used in Python when you would use a switch in other languages):

>>> flags = {
    'F': 'FIN',
    'S': 'SYN',
    'R': 'RST',
    'P': 'PSH',
    'A': 'ACK',
    'U': 'URG',
    'E': 'ECE',
    'C': 'CWR',
}
>>> [flags[x] for x in p.sprintf('%TCP.flags%')]
['SYN', 'ACK']
like image 39
Pierre Avatar answered Sep 20 '22 01:09

Pierre