forked from noahdavids/packet-analysis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
packet-matcher-faster.sh
executable file
·209 lines (170 loc) · 7.61 KB
/
packet-matcher-faster.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#!/bin/bash
# packer-matcher-faster.sh begins on the previous line
#
# This macro searches for TCP packets in one file that match packets in
# another file. It is useful when NAT has changed the IP addresses and or
# port numbers. It uses the combination of IP ID and absolute sequence
# and ACK numbers as the key.
#
# Output is the matching pairs of tshark output, one from each file. This
# this is a slow process since each file must be searched for each
# id-sequence-number-ack-number key. Since the typical goal is just to
# identify the matching streams you can limit this to just a subset (like 1)
# of matching segments.
#
# Note that the packets are not printed in order. They are sorted by
# id-seq-ack number so typically all the packets from one IP address will
# print out first. Which direction is printed first will be random and if the
# connection goes on for more than 64K packets or a host is very busy and the
# IP ID values cycle the order can change and later packets from one host may
# be printed before ealier packets from the same host.
# If the script finds more than 2 matches per key it assumes some packets
# are duplicated. This would generate false positives so the script prints
# the key values so you can investigate and aborts the matching phase.
# This is packet-matcher-faster because it is faster than packet-matcher. But
# packet-matcher looks at actual data contents so it can match packets
# through proxies or other middleware boxes where the entire TCP header is
# changed.
# Version 1.0 September 10, 2017
# Version 1.1 September 17, 2017
# Cleaned up some comments, added some comments and added a message if
# no matches are found
PACKETMATCHERFASTVERSION="1.1_2017-09-15"
# from https://github.com/noahdavids/packet-analysis.git
# Copyright (C) 2017 Noah Davids
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, version 3, https://www.gnu.org/licenses/gpl-3.0.html
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
if [ $# -ne 4 ]
then echo "Usage:"
echo " packet-match-faster.sh FILE1 FILTER FILE2 COUNT"
echo " FILE1 is the name of one file"
echo " FILTER is a tshark filter used to select packets from"
echo " FILE1"
echo " FILE2 is the name of the other file"
echo " limit the results to COUNT values, 0 implies no limit"
exit
fi
FILE1=$1
FILTER="$2"
FILE2=$3
COUNT=$4
if [ ! -f $FILE1 ]
then echo "Could not find input file $FILE1"
exit
fi
if [ ! -f $FILE2 ]
then echo "Could not find input file $FILE2"
exit
fi
# Figure out if we can use "-Y" as the display filter argument or we need
# "-R". Basically look at the help output and if we do not find the "-Y"
# we use "-R"
DASH="-Y"
if [ $(tshark -help | egrep "\-Y <display filter>" | wc -l) -eq 0 ]
then DASH="-R"
fi
# Extract the IP ID, TCP sequence and ACK numbers from each TCP segment in
# FILE1 that matches the filter. Write the values to a temporary -1 file with
# dashs between the values instead of spaces
rm -f /tmp/packet-matcher-faster-1
tshark -r $FILE1 $DASH "$FILTER" \
-T fields -e ip.id -e tcp.seq -e tcp.ack \
-o tcp.relative_sequence_numbers:FALSE | \
while read id seq ack; do echo $id-$seq-$ack; done > \
/tmp/packet-matcher-faster-1;
# Remove enries with an ID of 0x0. SYN-ACKs and RESETS may not have an IP ID
# and retransmissions of these might therefore trigger a false positive
# for duplicated packets
rm -f /tmp/packet-matcher-faster-2
cat /tmp/packet-matcher-faster-1 | grep -v "0x00000000" | \
sort | uniq -c > /tmp/packet-matcher-faster-2
# If no segments are found report an error and exit
if [ $(cat /tmp/packet-matcher-faster-2 | wc -l) -eq 0 ]
then echo "No segments in $FILE1 match $FILTER"
echo "exiting now"
exit
fi
# If any ID-SEQ-ACK shows up more than once at this point we may have
# duplicated packets so report an error and print the duplicated keys
# for investigation. You can use "editcap -d" to remove the duplicates
rm -f /tmp/packet-matcher-faster-3
cat /tmp/packet-matcher-faster-2 | awk '($1 > 1) {print $0}' > \
/tmp/packet-matcher-faster-3
if [ $(cat /tmp/packet-matcher-faster-3 | wc -l) -gt 0 ]
then echo "Presence of more than 2 matches per id-seq-ack in"
echo $FILE1
echo "possible duplicate packets in trace - remove duplicates"
echo "with \"editcap -d\" before proceeding"
echo "list of duplicated id-seq-ack keys can be found in"
echo "/tmp/packet-matcher-faster-3"
exit
fi
# Extract the IP ID, TCP sequence and ACK numbers from each TCP segment in
# FILE2.
rm -f /tmp/packet-matcher-faster-4
tshark -r $FILE2 $DASH "tcp" -T fields -e ip.id -e tcp.seq -e tcp.ack \
-o tcp.relative_sequence_numbers:FALSE | \
while read id seq ack; do echo $id-$seq-$ack; done >> \
/tmp/packet-matcher-faster-4
# Remove enries with an ID of 0x0 (again)
rm -f /tmp/packet-matcher-faster-5
cat /tmp/packet-matcher-faster-4 | grep -v "0x00000000" | \
sort | uniq -c > /tmp/packet-matcher-faster-5
# If no segments are found report an error and exit
if [ $(cat /tmp/packet-matcher-faster-5 | wc -l) -eq 0 ]
then echo "Nothing to match on in $FILE2"
echo "exiting now"
exit
fi
# test for duplicates again
rm -f /tmp/packet-matcher-faster-6
cat /tmp/packet-matcher-faster-5 | awk '($1 > 1) {print $0}' > \
/tmp/packet-matcher-faster-6
if [ $(cat /tmp/packet-matcher-faster-6 | wc -l) -gt 0 ]
then echo "Presence of more than 2 matches per id-seq-ack in"
echo $FILE2
echo "possible duplicate packets in trace - remove duplicates"
echo "with \"editcap -d\" before proceeding"
echo "list of duplicated id-seq-ack keys can be found in"
echo "/tmp/packet-matcher-faster-6"
exit
fi
# Finally we can do real work. For each IP-SEQ-ACK that occurs twice
# (presumably once in each trace). Print the packet. This part is the slow
# part since each packet trace file is scanned completely for each ID-SEQ-ACK.
# Therefore stop after COUNT segment pairs are displayed. Write the packets
# to the temporary-7 file
SHOWN=0
rm -f /tmp/packet-matcher-faster-7
cat /tmp/packet-matcher-faster-2 /tmp/packet-matcher-faster-5 | sort | \
uniq -c | awk '($1 == 2) {print $3}' | tr "-" " " | while read id seq ack
do
echo ===================================================================
echo $id $seq $ack
echo $FILE1
echo " " $(tshark -r $FILE1 $DASH "ip.id == $id && \
tcp.seq == $seq && tcp.ack == $ack" \
-o tcp.relative_sequence_numbers:FALSE -tad)
echo
echo $FILE2
echo " " $(tshark -r $FILE2 $DASH "ip.id == $id && \
tcp.seq == $seq && tcp.ack == $ack" \
-o tcp.relative_sequence_numbers:FALSE -tad)
echo
SHOWN=$((SHOWN+1))
if [ $SHOWN -eq $COUNT ]
then exit
fi
done > /tmp/packet-matcher-faster-7
# If the previous step produced no output indicate that no matches were
# found otherwise just dump the output file
if [ $(cat /tmp/packet-matcher-faster-7 | wc -l) -eq 0 ]
then
echo No matches found between $FILE1 and $FILE2
else cat /tmp/packet-matcher-faster-7
fi