web-dev-qa-db-fra.com

Obtenir TCP Drapeaux avec Scapy

J'analyse un fichier PCAP et je dois extraire TCP flags (SYN, ACK, PSH, URG, ...). J'utilise la valeur packet['TCP'].flags pour obtenir tous les drapeaux à la fois.

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

Existe-t-il un moyen d’obtenir un seul indicateur TCP sans l'extraire manuellement de la valeur packet['TCP'].flags?

11
auino

Normalement, la manière habituelle de gérer FLAGS consiste à utiliser des opérateurs bitmap et bitwise. Si votre classe Packet ne dispose pas d'une méthode spécifique pour tester les indicateurs, la meilleure chose à faire à mon humble avis est de:

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

Et testez-les comme ceci:

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

Malheureusement, python n'a pas d'instruction switch pour la rendre plus élégante, mais cela n'a pas beaucoup d'importance.

J'espère que cela t'aides!

11
Paulo Bu

Vous pouvez utiliser la méthode Packet.sprintf():

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

Si vous voulez les noms "longs", utilisez une dict au lieu d'une longue if...Elif... expression (dict sont souvent utilisés en Python lorsque vous utiliseriez une switch dans d'autres langues):

>>> 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']
12
Pierre

Une autre option, pour le compte rendu, qui n’existait pas au moment où cette question a été posée. Cela fonctionne avec la version de développement actuelle de Scapy (la première version incluant cette modification sera 2.4.0; 2.4.0rc * l'inclura également).

Vous pouvez maintenant utiliser str() sur la valeur du drapeau:

>>> p = IP()/TCP(flags=18)
>>> p[TCP].flags
<Flag 18 (SA)>
>>> str(p[TCP].flags)
'SA'
2
Pierre

Cela fonctionne aussi.

if packet[TCP].flags.F:
    print('FIN received')
1
Dragonborn