Skip to content

Instantly share code, notes, and snippets.

@pocc
Last active April 10, 2019 18:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pocc/3835bbefbf1e0e96052ebc57a57a3911 to your computer and use it in GitHub Desktop.
Save pocc/3835bbefbf1e0e96052ebc57a57a3911 to your computer and use it in GitHub Desktop.
Filters packets by a regex applied to a display filter
#!/usr/bin/env python3
# Desc:
# Create a pcap where the output of a display filter matches
# a given regex. Generates a file named re_<pcap in name>
# tshark MUST be on the path for this to work
#
# Usage:
# Using the `arp-storm.pcap` from https://wiki.wireshark.org/SampleCaptures
# To match all packets whose seconds part of the timestamp ends in 3:
#
# $ python reshark.py arp-storm.pcap frame.time "Oct 5, 2004 \d{2}:\d{2}:\d3"
# => 68 / 622 matching packets
# => Saving to re_arp-storm.pcap
#
# Equivalent to bash/perl:
# filter=$(tshark -r arp-storm.pcap -T fields -e frame.number -e frame.time | \
# perl -ne 'print "frame.number==$1 || " if /(?:\n|^)(\d+)\s+Oct 5, 2004 \d{2}:\d{2}:\d3/' | head --bytes=-4)
# tshark -r arp-storm.pcap -w re_arp-storm.pcap -Y "$filter"
#
# Copyright 2019 Ross Jacobs
import re
import subprocess as sp
import sys
def reshark(sysargs):
pcap_in, field, regex_str = sysargs
field_regex = re.compile(regex_str)
# Output will be in two columns: Frame number and 2nd field
tshark_cmd = ["tshark", "-r", pcap_in,
"-T", "fields", "-e", "frame.number", "-e", field]
output = sp.check_output(tshark_cmd).decode('utf-8')
# Structure: [(frame, field), ...]
tshark_output_regex = re.compile(r'(?:\n|^)(\d+)\s(.+)')
frame_fields = re.findall(tshark_output_regex, output)
matching_frame_nums = []
for frame in frame_fields:
field_of_interest = frame[1]
if re.search(field_regex, field_of_interest):
matching_frame_nums.append(frame[0])
if matching_frame_nums:
print(len(matching_frame_nums), "/", len(frame_fields), "matching packets\n"
" Saving to re_" + pcap_in + '\n')
else:
print("No packets match your regex.\nChange the field or double check"
"your regex with a tester like regex101.com\n")
# "frame.number == <num> || frame.number == ... "
filter_parts = ['frame.number==' + num for num in matching_frame_nums]
out_filter = ' || '.join(filter_parts)
tshark_cmd = ["tshark", "-r", pcap_in, "-Y", out_filter,
"-w", "re_" + pcap_in]
sp.Popen(tshark_cmd)
if len(sys.argv) != 4:
print("Please use `python reshark.py <pcap path> <pcap filter> <regex>`")
reshark(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment