Capture el tráfico del protocolo X11

15

¿Cómo puedo capturar el tráfico del protocolo X11 ?

Necesito encontrar una manera de capturar el tráfico X11 entre dos máquinas y también entre un servidor X11 y un cliente X11 en una máquina local.

Z h_
fuente

Respuestas:

19

Puede hablar X11 sobre TCP, o sobre un socket de dominio Unix o (en Linux) en un socket de dominio Unix en el espacio de nombres abstracto .

Cuando DISPLAY se establece en host:4, abreviatura de tcp/host:4, los clientes usan TCP para conectarse al servidor. El puerto TCP es entonces 6000 más el número de pantalla (en ese caso 6004).

En ese caso, puede capturar el tráfico con cualquier sniffer de red como tcpdumpo wiresharkcapturando el tráfico TCP en ese puerto.

Cuando $DISPLAYes solo :4(abreviatura de unix/:4), los clientes usan un socket de dominio unix. Cualquiera /tmp/.X11-unix/X4o la misma ruta en el espacio de nombres ABSTRACT (generalmente se muestra como @/tmp/.X11-unix/X4en la netstatsalida).

Capturar el tráfico es más complicado.

Si sus escuchas servidor X en TCP (pero no tienden a más hoy en día), lo más fácil es cambiar DISPLAYde localhost:4lugar de :4y capturar el tráfico de red en el puerto 6004 en la interfaz de bucle de retorno.

Si no es así, puede usarlo socatcomo un hombre en el medio que acepta conexiones como TCP y las reenvía como unix o abstracto :

socat tcp-listen:6004,reuseaddr,fork unix:/tmp/.X11-unix/X4

A continuación, puede establecer $DISPLAYa localhost:4y capturar el tráfico de red que el anterior o decirle socata volcar con -x -v.

Ahora, si no puede cambiar $DISPLAYy desea capturar el tráfico de una aplicación X local que ya se está ejecutando y que utiliza sockets de dominio Unix, es difícil.

Un enfoque podría ser usar strace(o el comando equivalente en su sistema si no es Linux) para rastrear las llamadas del sistema de envío / recepción que su aplicación hace para comunicarse con el servidor X.

Aquí xterm, observo que sí writev(), recvfrom()y el recvmsg()sistema llama al descriptor de archivo 3 para eso. Entonces puedo hacer:

strace -qqxxttts9999999 -e writev,recvmsg,recvfrom -p "$xterm_pid" 2>&1 |
  perl -lne '
    if (($t,$f,$p) = /^([\d.]+) (writev|recvmsg|recvfrom)\(3, (.*)/) {
      @p = ($p =~ /\\x(..)/g);
      $dir = $f eq "writev" ? "O" : "I";
      while (@p) {print "$dir $t 0000 " . join(" ", splice @p,0,64000)}
    }' | text2pcap -T6000,1234 -Dqt %s. - - | wireshark -ki -

(o tshark -Vi -)

La idea es extraer la marca de tiempo y los bytes enviados / recibidos de la salida stracey usar text2pcappara convertirlos en un pcap(agregando encabezados TCP falsos en el puerto 6000 con -T6000,1234) antes de alimentarlos wireshark. También dividimos los paquetes para evitar el límite de 64 KB en la longitud máxima de un registro pcap.

Tenga en cuenta que para text2pcapque funcione correctamente con respecto a la dirección correcta del tráfico, necesita una versión relativamente reciente de wireshark.

Stéphane Chazelas
fuente
¿Conoces la razón detrás de la configuración predeterminada de los sockets de dominio Unix? ¿TCP tiene algún impacto (significativo) en el rendimiento u otros inconvenientes?
inVader
@inVader, bueno, sí, ese es un protocolo TCP / IP completo para implementar, pasando por varias capas ... Supongo que el sistema puede tomar atajos (como no implementar el algoritmo habitual para evitar la congestión) para las conexiones de bucle invertido, pero aún así, en mis pruebas Obtengo el doble de rendimiento con un simple con socket de dominio unix que con una prueba de soc de socket tcp.
Stéphane Chazelas
14

Si está interesado principalmente en el protocolo X11 y no en las cosas subyacentes de TCP / IP y Ethernet, y si puede ajustar la configuración del cliente o del servidor, puede usar una herramienta específicamente diseñada para capturar y decodificar el tráfico entre un X11 cliente y un servidor X11. A diferencia del wiresharkdisector X11, es poco probable que estas herramientas se confundan con el tráfico, ya que están completamente involucradas con él.

El principal es xscope que, a pesar de no estar disponible como binario para algunas distribuciones de Unix o Linux, puede construirse fácilmente desde la fuente .

Alternativamente, también hay xtruss y xtrace pero no tengo experiencia con ellos.

Todas estas herramientas actúan como servidores proxy inversos que transmiten conexiones a un servidor X11 real. Los clientes simplemente usan una variable DISPLAY diferente (o argumento de visualización) para conectarse al proxy.

p.ej:

$ wget http://xorg.freedesktop.org/archive/individual/app/xscope-1.4.1.tar.gz
..
$ tar xzf xscope-1.4.1.tar.gz
..
$ cd xscope-1.4.1
$ ./configure && ./make
..
$ ./xscope & sleep 5; xclock -display :1
...
 0.00: Client -->   12 bytes
              byte-order: LSB first
           major-version: 000b
           minor-version: 0000
 0.00:                   692 bytes <-- X11 Server
                    protocol-major-version: 000b
                    protocol-minor-version: 0000
                          release-number: 00adfef8
                        resource-id-base: 04c00000
                        resource-id-mask: 001fffff
                      motion-buffer-size: 00000100
                        image-byte-order: LSB first
                    bitmap-format-bit-order: LSB first
                    bitmap-format-scanline-unit: 20
                    bitmap-format-scanline-pad: 20
                             min-keycode: 8 (^H)
                             max-keycode: 255 (\377)
                                  vendor: "The X.Org Foundation"
                          pixmap-formats: (7)
                                   roots: (1)
 0.00: Client -->   20 bytes
     ............REQUEST: QueryExtension
                    name: "BIG-REQUESTS"
 0.00:                    32 bytes <-- X11 Server
                     ..............REPLY: QueryExtension
                                 present: True
                            major-opcode: 85

Nota: Si por alguna razón no puede cambiar la configuración de los clientes X11 (pantalla), es posible que pueda volver a configurar el servidor para escuchar un puerto diferente (típicamente 6001 vs 6000) y luego configurarlo xscopepara escuchar en el puerto original (6000).

jlliagre
fuente
Traté de compilar xscope ... "No se encontró el paquete 'xproto'". pls, ¿puedes escribir aquí el volcado del primer paquete (12 bytes)?
Massimo
@ Massimo ¿Instalaste el paquete que falta?
jlliagre
Estoy usando una instalación Linux en Amazon, y yum no sabe xproto. Por favor, ¿puedes publicar el volcado del primer paquete? Solo necesito eso, gracias.
Massimo
debido a que el primer paquete habitual es de 21 bytes, no 12, consulte "Iniciación de conexión" en x.org/releases/current/doc/xproto/x11protocol.html
Massimo
1
Acabo de probar xtrace: puedo confirmar que también funciona bien; su salida es más compacta, con una línea por mensaje, por lo que también es fácilmente identificable. Ejecutar con, por ejemplo. xtrace -D:1 -d:0 -k. (O x11trace, ya que el ejecutable se nombra en algunas distribuciones)
Aleksi Torhamo
4

X11 usa TCP como su protocolo de transporte. El rango de puertos TCP para X11 suele ser 6000-6063, pero lo más probable es que vea el puerto TCP 6000 en uso.

Por lo tanto, debe poder utilizar cualquier monitor de red de su elección para observar el tráfico filtrando por este rango de puertos y los hosts en cuestión. También sé que wireshark, por ejemplo, ya contiene un filtro preestablecidox11 para monitorear el tráfico que le interesa.

Por ejemplo, para monitorear todo el tráfico X11 en la máquina local (si usa TCP; consulte la respuesta de @ Stéphane Chazelas) use el siguiente filtro:

x11 and ip.src=127.0.0.1 and ip.dst=127.0.0.1
invasor
fuente
Los mensajes de cliente-servidor local se pasan a través de un socket de dominio Unix, lsof -U | grep '^X'.
Ricitos