Formato leggibile dall'uomo per le intestazioni http con tcpdump


69

Vorrei visualizzare le intestazioni HTTP inviate da Apache (in ascolto sulla porta 80) a Tomcat (sulla porta 4080) in una macchina Linux.

Secondo Wikipedia ,

I campi di intestazione sono coppie nome-valore separate da due punti in formato stringa in chiaro.

Ho provato alcune varianti del seguente tcpdumpcomando:

$ 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?

Il risultato è sempre stato lo stesso: uno strano mix di parole incomprensibili e inglesi (ad es HEAD.).

Come posso visualizzare le intestazioni in un formato leggibile dall'uomo?


Tcpdump mostra l'intero pacchetto. Ciò include le intestazioni IP e TCP. AFAIK, non puoi visualizzare solo il payload TCP.
— Zoredache,

Risposte:


93

Ecco un esempio che ho ideato per visualizzare le intestazioni HTTP di richiesta e risposta tcpdump(che dovrebbe funzionare anche nel tuo caso):

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'

Limita taglia il pacchetto a 10Kb e conosce solo i comandi GET, POST e HEAD, ma dovrebbe essere sufficiente nella maggior parte dei casi.

EDIT : modificato per eliminare i buffer in ogni fase per renderlo più reattivo. Ora ha bisogno di Perl e stdbuf, quindi usa la versione originale se non li possiedi: EDIT : destinazioni della porta dello script modificate da 80 a 4080, per ascoltare effettivamente il traffico che ha già attraversato apache, anziché il traffico esterno diretto che arriva alla porta 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 }'

Alcune spiegazioni:

  • sudo stdbuf -oL -eL fa funzionare tcpdump con buffer di linea
  • il filtro magico tcpdump è spiegato in dettaglio qui: https://stackoverflow.com/questions/11757477/understanding-tcpdump-filter-bit-masking
  • grep sta cercando qualsiasi linea con GET, HTTP / o POST; o qualsiasi riga che assomigli a un'intestazione (lettere e numeri seguiti da due punti)
  • BEGIN {$ | = 1} fa eseguire perl al buffer di linea
  • s /.*? (GET | HTTP / [0-9.] * | POST) / \ n $ 1 / g aggiunge una nuova riga prima dell'inizio di ogni nuova richiesta o risposta

1
Funziona alla grande. Potresti aggiungere ulteriori dettagli su come funziona l'espressione tcpdump?
— Vivek Thomas,

1
la parte 'ip' in parentesi è spiegato qui, per esempio: stackoverflow.com/questions/11757477/...
— Kibber

Mi hai appena salvato così tanto mal di testa. Peccato che posso solo +1.
— Aaron Dobbing,

19

Puoi ottenere qualcosa di simile a ciò che desideri utilizzando -A, ad es

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

Ricordati di usare -s 0per assicurarti di ottenere l'intero pacchetto.

In alternativa, è possibile utilizzare wiresharkper visualizzare le intestazioni in modo interattivo.


1
Ho provato -Ae -s 0ottenuto lo stesso risultato.
— Adam Matan,

2
Prova senza -X.
— Flup,

tcpdump -s 0 -A dst port 4080dà E..e..@.?.$bb...b....:......w........Q.....G..1.b..HEAD /dapper_serving/AdMonkey?ping=1 HTTP/1.0.
— Adam Matan,

... che è qualcosa di simile a quello che vuoi. Leggi da 'HEAD' - questo è il payload HTTP. Se hai sicuramente usato -s 0e non c'è niente dopo HTTP/1.0, non ci sono intestazioni HTTP nella richiesta.
— Flup,

Grazie. C'è un modo per stampare solo le intestazioni di testo, senza il payload binario?
— Adam Matan,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.