Formato legible para humanos para encabezados http con tcpdump

69

Me gustaría ver los encabezados HTTP enviados desde Apache (escuchando en el puerto 80) a Tomcat (en el puerto 4080) en una máquina Linux.

De acuerdo con Wikipedia ,

Los campos de encabezado son pares de nombre-valor separados por dos puntos en formato de cadena de texto sin cifrar.

He intentado algunas variaciones del siguiente 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?

El resultado fue siempre el mismo: una extraña mezcla de galimatías y palabras en inglés (por ejemplo HEAD).

¿Cómo puedo ver los encabezados en un formato legible para humanos?

Adam Matan
fuente
Tcpdump muestra el paquete completo. Esto incluye los encabezados IP y TCP. AFAIK, no puede mostrar solo la carga útil de TCP.
Zoredache

Respuestas:

93

Aquí hay una frase que se me ocurrió para mostrar los encabezados HTTP de solicitud y respuesta usando tcpdump(que también debería funcionar para su 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 los cortes del paquete a 10Kb y solo conoce los comandos GET, POST y HEAD, pero eso debería ser suficiente en la mayoría de los casos.

EDITAR : lo modificó para deshacerse de los búferes en cada paso para que sea más receptivo. Sin embargo, ahora necesita Perl y stdbuf, así que use la versión original si no los tiene: EDITAR : Se cambiaron los objetivos del puerto de script de 80 a 4080, para realmente escuchar el tráfico que ya pasó por Apache, en lugar del tráfico externo directo que llega al puerto 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 }'

Algunas explicaciones:

  • sudo stdbuf -oL -eL hace que tcpdump se ejecute con buffer de línea
  • El filtro mágico tcpdump se explica en detalle aquí: https://stackoverflow.com/questions/11757477/understanding-tcpdump-filter-bit-masking
  • grep está buscando líneas con GET, HTTP / o POST; o cualquier línea que parezca un encabezado (letras y números seguidos de dos puntos)
  • COMIENZO {$ | = 1} hace que Perl ejecute el buffer de línea
  • s /.*? (GET | HTTP / [0-9.] * | POST) / \ n $ 1 / g agrega una nueva línea antes del comienzo de cada nueva solicitud o respuesta
Kibber
fuente
1
Funciona genial. ¿Podría agregar más detalles sobre cómo funciona esa expresión tcpdump?
Vivek Thomas el
1
aquí se explica la parte 'ip' en parens, por ejemplo: stackoverflow.com/questions/11757477/…
Kibber
Me acabas de salvar tanto dolor de cabeza. Es una pena que solo pueda hacer +1.
Aaron Dobbing
19

Puede obtener algo cercano a lo que desea mediante -A, por ejemplo,

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

Recuerde usar -s 0para asegurarse de obtener el paquete completo.

Alternativamente, puede usar wiresharkpara ver los encabezados de forma interactiva.

Flup
fuente
1
Intenté -Ay -s 0obtuve el mismo resultado.
Adam Matan
2
Intenta sin -X.
Flup
tcpdump -s 0 -A dst port 4080da E..e..@.?.$bb...b....:......w........Q.....G..1.b..HEAD /dapper_serving/AdMonkey?ping=1 HTTP/1.0.
Adam Matan
... que es algo cercano a lo que quieres. Lea desde 'HEAD': esta es la carga de HTTP. Si definitivamente ha utilizado -s 0y no hay nada después HTTP/1.0, no hay encabezados HTTP en la solicitud.
Flup
Gracias. ¿Hay alguna forma de imprimir solo los encabezados de texto, sin la carga útil binaria?
Adam Matan
-1

Intente usar http://justniffer.sourceforge.net/ Es mejor herramienta o Wireshark con la opción "Seguir TCP Flow", solo hay muchas mejores opciones que tcpdump para ver encabezados (solicitudes / respuestas)

Danila Ladner
fuente
1
Quizás también agregue un ejemplo de cómo hacer que esto funcione
vikas027
¿Quizás puedas leer una página de manual? justniffer.sourceforge.net/#!/man_page
Danila Ladner