tcpdump: comment obtenir une sortie grepable?

13

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 de ligne pr. Je ne peux pas saisir 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.

Chien manger chat monde
la source
1
eh bien, je ne peux pas tester cela pour le moment mais si vous avez plusieurs lignes, vous pouvez le faire | tr -d '\ n' ou grep -C 3 pour obtenir des lignes avant et après
barlop
@barlop, grep -C sorte de travaux, mais peu fiables, car je ne sais jamais combien de lignes l'en-tête sera, et je ne verrai pas les lignes sous la correspondance. La commande tr transcende toute la sortie sur 1 ligne, donc c'est un peu trop.
Dog eat cat world
Ce qui suit ne serait pas grep, mais tcpdump peut faire correspondre les chaînes par hex qui est essentiellement grep sans aucune expression régulière. Vous pouvez spécifier un décalage. Je l'ai noté dans un fichier (fait avec windump mais je ne suis qu'une version Windows de tcpdump alors supposez tcpdump) tcpdump -nXr zfile "tcp [32: 4] = 0x47455420"
barlop
tcpdump -nei eth0 -X | grep --line-buffered "something interesting"fera, pour des raisons non identifiées, ma réponse de travail valide a été supprimée.
sjas

Réponses:

11

Pour ceux comme vous qui ne peuvent pas utiliser ngrep, voici comment utiliser awkpour rendre la tcpdumpsortie du contenu des paquets plus agréable.

D'abord quelques exemples de résultats 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 c'est le script copier-coller que awkvous pouvez diriger la sortie vers

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()
}'
Eugene Beresovsky
la source
2

Depuis la tcpdumppage de manuel:

-A      Print each packet (minus its link level header) in ASCII.  Handy
        for capturing web pages.

Assurez-vous que vous utilisez également l' -s 0option pour vous assurer que le paquet entier est affiché.

Flup
la source
Merci, mais les données sont toujours présentées sur plusieurs lignes - partout où la page Web contient des nouvelles lignes. J'ai du mal à associer l'en-tête (et le reste des données) à la sortie grepped.
Dog eat cat world
Je viens de comprendre pourquoi l'outil s'appelle awk ward
Dog eat cat world
1

Vous voudrez peut-être jeter un œil à la ngrepcommande:

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 pour vider uniquement les paquets contenant certaines chaînes.
  • 'port 80' est un filtre pcap pour renifler uniquement les paquets depuis ou vers le port 80
LatinSuD
la source
1
Voudrait utiliser ngrep, mais il n'y a pas un tel outil - c'est un appareil ...
Dog eat cat world
ngrep est génial. Je cherchais des heures quel hôte génère du trafic HTTP vers mon hôte. Avec un seul sudo ngrep "GET .." réponse trouvée en une minute.
Bartosz Bilicki
0

La raison pour laquelle votre sortie est hexadécimale est le -Xdrapeau. Essayer:

tcpdump -ni eth1 | grep something_interesting

Vous obtiendrez une sortie lisible lue directement sur le cli.

DaveA
la source
Oui, mais il ne contiendra pas le contenu du paquet.
RalfFriedl
0

Je n'ai pas pu obtenir le script awk pour faire ce que je voulais et ngrep ne fonctionnerait pas sur un Ethernet via USB, j'ai donc écrit un petit programme C pour rejoindre les lignes de sortie par tcpdump afin qu'elles soient grepables. C'est à https://gitlab.com/dargaud/TcpDumpJoin

Dargaud
la source