J'essaie de résoudre un problème où je n'ai que tcpdump disponible sur une appliance. Je souhaite utiliser tcpdump pour filtrer le trafic Web et n’afficher que le trafic contenant certaines chaînes.
Je fais ce qui suit:
tcpdump -nei eth0 -X | grep "something interesting"
La sortie est une hexview avec 16 octets par ligne. Je ne peux pas grep ces données, car les données sont présentées sur plusieurs lignes.
Existe-t-il un moyen pour tcpdump de présenter les données capturées sur une seule ligne? Cela permettrait d’utiliser grep pour trouver des paquets intéressants.
Pour ceux comme vous qui ne peuvent pas utiliser ngrep
, voici comment utiliser awk
pour rendre la sortie tcpdump
du contenu du paquet grepable.
Quelques exemples de sortie fournis par tcpdump -x
, afin de présenter la tâche à venir:
$ tcpdump -xr dump.pcap 2>/dev/null
12:04:59.590664 IP 10.17.14.93.51009 > 239.194.1.9.51009: UDP, length 370
0x0000: 4500 018e 0000 4000 fa11 7625 0a11 0e5d
0x0010: efc2 0109 c741 c741 017a 6f28 1120 2020
0x0020: 3337 3030 3039 3031 3835 3635 3430 3130
...
Et ceci est le script copier-coller-_awk
auquel vous pouvez diriger le résultat
awk '{ if (match($0, /^[0-9]/, _)) { printf (NR == 1 ? "%s " : "\n%s "), $0; fflush() } else { sub(/^\s+0x[0-9a-z]+:\s+/, " "); gsub(" ", ""); printf "%s", $0 } } END { print ""; fflush() }'
afin d'obtenir la sortie suivante, grepable
12:04:59.590664 IP 10.17.14.93.51009 > 239.194.1.9.51009: UDP, length 370 4500018e00004000fa1176250a...
12:04:59.590798 IP 10.17.14.113.51011 > 239.194.1.11.51011: UDP, length 370 4500018e00004000fa11760f...
...
Voici une version commentée du script ci-dessus:
awk '
{
# if this is a header line
if (match($0, /^[0-9]/, _))
{
# print the header, but:
# except for the first line,
# we need to insert a newline,
# as the preceding data lines
# have been stripped of theirs
# we also append a space to
# separate header info from the
# data that will get appended
printf (NR == 1 ? "%s " : "\n%s "), $0
# enforce line-buffering
fflush()
}
# otherwise it is a data line
else
{
# remove the data address
sub(/^\s+0x[0-9a-z]+:\s+/, " ");
# remove all spaces
gsub(" ", "");
# print w/o newline
printf "%s", $0
}
}
END
{
# print final newline, as
# the preceding data lines
# have been stripped of theirs
print ""
# enforce line-buffering
fflush()
}'
De la page de manuel tcpdump
:
-A Print each packet (minus its link level header) in ASCII. Handy
for capturing web pages.
Assurez-vous également que vous utilisez l'option -s 0
pour vous assurer que tout le paquet est affiché.
Vous voudrez peut-être jeter un coup d’œil à la commande ngrep
:
ngrep -W single -d eth0 'regex to match' 'port 80'
Où:
-W single
spécifie le formatage sur une seule ligneregex to match
signifie uniquement vider les paquets contenant certaines chaînes.'port 80'
est un filtre pcap pour ne renvoyer que les paquets en provenance ou à destination du port 80La raison pour laquelle votre sortie est hexadécimale est l'indicateur -X
. Essayer:
tcpdump -ni eth1 | grep something_interesting
Vous obtiendrez une sortie lisible sauvegardée directement vers la cli.
Je ne pouvais pas obtenir le script awk pour faire ce que je voulais et ngrep ne fonctionnerait pas sur Ethernet sur USB, alors j'ai écrit un petit programme en C pour joindre les lignes sorties par tcpdump afin qu'elles soient grepables. C'est à https://gitlab.com/dargaud/TcpDumpJoin