Below is the tcp header map
So looking at the tcp header map we know that the tcp header map, the syn,ack flags are on byte #13
Remember that the header starts at byte #0, so if we want to catch the communication initialization between a client and a server we need to catch the flags syn, syn-ack, and ack
client ------- Sends Syn ---------Server
Server -----answers syn-ack---client
client ----ansers ack -------------server
------Communication has been established--------
to catch this sequence for any given service, let's say port 22 (where ssh lives) we create the filter
tcpdump -i eth0 -n --tq '(tcp[13] = 2 or tcp[13] = 16 or tcp [13]=18) and ((src host 1.2.3.4 and dst port 22) and (dst host 5.6.7.8 and src port 22))'
This will catch syn, syn-ack and ack
So tcp[13] = 2 means: on byte 13 the following pattern is: syn
cwr=0
ece=0
urg=0 (urgent)
ack=0(acknowledge)
psh=0(push)
rst=0(reset)
syn=1(sync)
fin=0(finish)
The above pattern is binary so 00000010 = 2
so tcp[13] = 18 on byte 13 the following pattern is: syn-ack
cwr=0
ece=0
urg=0 (urgent)
ack=1(acknowledge)
psh=0(push)
rst=0(reset)
syn=1(sync)
fin=0(finish)
The above pattern is binary so 00010010 = 18
o tcp[13] = 16on byte 13 the following pattern is: ack
cwr=0
ece=0
urg=0 (urgent)
ack=1(acknowledge)
psh=0(push)
rst=0(reset)
syn=0(sync)
fin=0(finish)
The above pattern is binary so 00010000 = 16
2nd part of the filter means:
((src host 1.2.3.4 and dst port 22) and (dst host 5.6.7.8 and src port 22))
that my client (src host) is 1.2.3.4 and the destination port must be 22
and that my server (dst host) is 5.6.7.8 and the source port is 22
So pretty much the tcpdump builds a logical table
(tcp[13] = 2 or tcp[13] = 16 or tcp [13]=18) and ((src host 1.2.3.4 and dst port 22) and (dst host 5.6.7.8 and src port 22))'
if this condiftion is true (tcp[13] = 2 or tcp[13] = 16 or tcp [13]=18)
if this condition is true ((src host 1.2.3.4 and dst port 22) and (dst host 5.6.7.8 and src port 22))
the packet will be captured and printed onto the screen
Happy filtering!