web-dev-qa-db-fra.com

tcpdump: comment obtenir une sortie grepable?

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.

13
Dog eat cat world

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()
}'
11

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é.

2
Flup

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 ligne
  • regex 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 80
1
LatinSuD

La 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.

0
DaveA

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

0
dargaud