Vom Menschen lesbares Format für http-Header mit tcpdump

69

Ich möchte die HTTP-Header anzeigen, die von Apache (auf Port 80 abhörend) an Tomcat (auf Port 4080) in einem Linux-Computer gesendet wurden.

Laut Wikipedia ,

Header-Felder sind durch Doppelpunkte getrennte Name-Wert-Paare im Klartext-Format.

Ich habe einige Variationen des folgenden tcpdumpBefehls ausprobiert :

$ sudo tcpdump -lnX dst port 4080 -c 10

11:29:28.605894 IP SOME_IP.33273 > SOME_IP.4080: P 0:49(49) ack 1 win 23 <nop,nop,timestamp 1191760962 509391143>
    0x0000:  4500 0065 3a9f 4000 3f06 0084 628a 9ec4  E..e:.@.?...b...
    0x0010:  628a 9c97 81f9 0ff0 9e87 eee0 144b 90e1  b............K..
    0x0020:  8018 0017 fb43 0000 0101 080a 4708 d442  .....C......G..B
    0x0030:  1e5c b127 4845 4144 202f 6461 7070 6572  .\.'HEAD./dapper
    0x0040:  5f73 6572 7669 6e67 2f41 644d 6f6e 6b65  _serving/AdMonke
    0x0050:  793f                                     y?

Das Ergebnis war immer dasselbe - eine seltsame Mischung aus Kauderwelsch und englischen Wörtern (z HEAD. B. ).

Wie kann ich die Header in einem für Menschen lesbaren Format anzeigen?

Adam Matan
quelle
Tcpdump zeigt das gesamte Paket. Dies umfasst die IP- und TCP-Header. AFAIK, Sie können nicht nur die TCP-Nutzdaten anzeigen.
Zoredache

Antworten:

93

Hier ist ein Einzeiler, den ich mir ausgedacht habe, um HTTP-Header für Anfragen und Antworten anzuzeigen tcpdump(was auch für Ihren Fall funktionieren sollte):

sudo tcpdump -A -s 10240 'tcp port 4080 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' | egrep --line-buffered "^........(GET |HTTP\/|POST |HEAD )|^[A-Za-z0-9-]+: " | sed -r 's/^........(GET |HTTP\/|POST |HEAD )/\n\1/g'

Es begrenzt das Paket auf 10 KB und kennt nur die Befehle GET, POST und HEAD, aber das sollte in den meisten Fällen ausreichen.

BEARBEITEN : Es wurde modifiziert, um die Puffer bei jedem Schritt zu entfernen und das Reaktionsverhalten zu verbessern. Benötigt jedoch Perl und stdbuf. Verwenden Sie die Originalversion, wenn Sie diese nicht haben: BEARBEITEN : Die Skriptportziele wurden von 80 auf 4080 geändert, um tatsächlich auf Datenverkehr zu warten, der bereits Apache durchlief, anstatt direkten Datenverkehr von außen, der an Port ankommt 80

sudo stdbuf -oL -eL /usr/sbin/tcpdump -A -s 10240 "tcp port 4080 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)" | egrep -a --line-buffered ".+(GET |HTTP\/|POST )|^[A-Za-z0-9-]+: " | perl -nle 'BEGIN{$|=1} { s/.*?(GET |HTTP\/[0-9.]* |POST )/\n$1/g; print }'

Einige Erklärungen:

  • Mit sudo stdbuf -oL -eL wird tcpdump zeilengepuffert ausgeführt
  • Der Tcpdump Magic Filter wird hier im Detail erklärt: https://stackoverflow.com/questions/11757477/understanding-tcpdump-filter-bit-masking
  • grep sucht nach Zeilen mit GET, HTTP / oder POST; oder alle Zeilen, die wie eine Kopfzeile aussehen (Buchstaben und Zahlen, gefolgt von einem Doppelpunkt)
  • BEGIN {$ | = 1} bewirkt, dass Perl zeilengepuffert ausgeführt wird
  • s /.*? (GET | HTTP / [0-9.] * | POST) / \ n $ 1 / g fügt vor dem Beginn jeder neuen Anfrage oder Antwort eine neue Zeile hinzu
Kibber
quelle
1
Funktioniert super. Könnten Sie bitte weitere Details hinzufügen, wie dieser tcpdump-Ausdruck funktioniert?
Vivek Thomas
1
die ‚ip‘ Teil in Pars wird hier erklärt, zum Beispiel: stackoverflow.com/questions/11757477/...
Kibber
Du hast mir so viele Kopfschmerzen erspart. Schade, ich kann nur +1.
Aaron Dobbing
19

Sie können etwas erreichen, was Sie möchten, indem Sie -Az

E....c@.@...
.....Ng.d.P..Ch.).....s.......
.A...u.BHEAD / HTTP/1.1
User-Agent: curl/7.29.0
Host: www.google.com
Accept: */*

Denken -s 0Sie daran, zu verwenden , um sicherzustellen, dass Sie das gesamte Paket erhalten.

Alternativ können Sie wiresharkdie Header auch interaktiv anzeigen.

Flup
quelle
1
Versuchte -Aund -s 0bekam die gleiche Ausgabe.
Adam Matan
2
Versuchen Sie es ohne -X.
Flup
tcpdump -s 0 -A dst port 4080gibt E..e..@.?.$bb...b....:......w........Q.....G..1.b..HEAD /dapper_serving/AdMonkey?ping=1 HTTP/1.0.
Adam Matan
... was in etwa dem entspricht, was Sie wollen. Aus 'HEAD' lesen - das ist die HTTP-Payload. Wenn Sie definitiv verwendet haben -s 0und nichts danach ist HTTP/1.0, enthält die Anfrage keine HTTP-Header.
Flup
Vielen Dank. Gibt es eine Möglichkeit, nur die Textheader ohne die binären Nutzdaten zu drucken?
Adam Matan
-1

Versuchen Sie, http://justniffer.sourceforge.net/ zu verwenden. Es ist ein besseres Tool oder Wireshark mit der Option "Follow TCP Flow". Es gibt nur viele bessere Optionen als tcpdump, um Header (Anfragen / Antworten) anzuzeigen.

Danila Ladner
quelle
1
Vielleicht fügen Sie noch ein Beispiel hinzu, wie dies funktioniert
vikas027
Vielleicht können Sie eine Manpage lesen? justniffer.sourceforge.net/#!/man_page
Danila Ladner