Capture o tráfego do protocolo X11

15

Como posso capturar o tráfego do protocolo X11 ?

Preciso encontrar uma maneira de capturar o tráfego X11 entre duas máquinas e também entre um servidor X11 e um cliente X11 na máquina local.

zh_
fonte

Respostas:

19

Você pode falar com o X11 sobre TCP ou sobre um soquete de domínio Unix ou (no Linux) em um soquete de domínio Unix no espaço para nome abstrato .

Quando DISPLAY estiver definido como host:4 , abreviação de tcp/host:4, os clientes usam o TCP para se conectar ao servidor. A porta TCP é então 6000 mais o número de exibição (nesse caso, 6004).

Nesse caso, você pode capturar o tráfego com qualquer sniffer de rede como tcpdump ou wiresharkcapturando o tráfego TCP nessa porta.

Quando $DISPLAYé apenas :4(abreviação de unix/:4), os clientes usam um soquete de domínio unix. Um /tmp/.X11-unix/X4ou o mesmo caminho no espaço de nome ABSTRACT (geralmente mostrado como @/tmp/.X11-unix/X4emnetstat saída).

Capturar o tráfego é mais complicado.

Se o seu servidor X ouvir no TCP (mas atualmente não o ouvem mais), o mais fácil é mudar DISPLAYpara em localhost:4vez de:4 capturar o tráfego de rede na porta 6004 na interface de loopback.

Caso contrário, você pode usar socatcomo um homem no meio que aceita conexões como TCP e as encaminha como unix ou abstrato :

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

Você pode então definir $DISPLAYa localhost:4e capturar o tráfego de rede como acima ou dizer socatpara despejá-lo com -x -v.

Agora, se você não pode mudar $DISPLAYe deseja capturar o tráfego de um aplicativo X local já em execução que usa soquetes de domínio unix, é aí que fica complicado.

Uma abordagem poderia ser usar strace(ou o comando equivalente em seu sistema, se não o Linux) para rastrear as chamadas de sistema de envio / recebimento que seu aplicativo faz para se comunicar com o servidor X.

Aqui xterm, observo que sim writev(), recvfrom()e o recvmsg()sistema chama o descritor de arquivo 3 para isso. Então eu posso fazer:

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 -

(ou tshark -Vi -)

A idéia é extrair o carimbo de data e hora enviado / recebido da saída stracee usá-lo text2pcappara convertê-lo em um pcap(adicionando cabeçalhos TCP fictícios na porta 6000 com -T6000,1234) antes de alimentar wireshark. Também dividimos pacotes para evitar o limite de 64 kB no comprimento máximo de um registro pcap.

Observe que, para text2pcapfuncionar corretamente com relação à orientação correta do tráfego, você precisa de uma versão relativamente recente do wireshark.

Stéphane Chazelas
fonte
Você sabe o motivo por trás do padrão para soquetes de domínio unix? O TCP tem algum impacto (significativo) no desempenho ou em outras desvantagens?
inVader 23/03
@inVader, bem, sim, esse é um protocolo TCP / IP inteiro para implementar, passando por várias camadas ... Suponho que o sistema possa usar atalhos (como não implementar o algoritmo usual para evitar congestionamentos) para conexões de loopback, mas ainda assim, em meus testes Eu recebo o dobro da taxa de transferência com um soquete de domínio unix do que com um teste socat de soquete tcp.
Stéphane Chazelas 23/03
14

Se você estiver interessado principalmente no protocolo X11 e não no material TCP / IP e Ethernet subjacente, e se conseguir ajustar as configurações do cliente ou do servidor, poderá usar uma ferramenta projetada especificamente para capturar e decodificar o tráfego entre um X11 cliente e um servidor X11. Ao contrário do wiresharkdissector X11, é improvável que essas ferramentas sejam confundidas pelo tráfego, estando totalmente envolvidas com ele.

O principal é o xscope que, apesar de não estar disponível como um binário para algumas distribuições Unix ou Linux, pode ser facilmente construído a partir do código - fonte .

Como alternativa, também existem xtruss e xtrace, mas não tenho experiência com eles.

Todas essas ferramentas agem como proxies reversos retransmitindo conexões com um servidor X11 real. Os clientes simplesmente usam uma variável DISPLAY diferente (ou argumento -display) para se conectar ao proxy.

por exemplo:

$ 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: Se, por algum motivo, você não puder alterar as configurações dos clientes X11 (vídeo), poderá reconfigurar o servidor para escutar uma porta diferente (normalmente 6001 vs 6000) e, em seguida, configurar xscopepara escutar na porta original (6000).

jlliagre
fonte
Tentei compilar xscope ... "Nenhum pacote 'xproto' encontrado". pls, você pode escrever aqui o despejo do primeiro pacote (12 bytes)?
Massimo
@Massimo Você instalou o pacote que faltava?
Jlliagre
Estou usando uma linux istance na Amazon e yum não sabe xproto. Pls você pode postar o despejo do primeiro pacote? Eu só preciso disso, pessoal.
Massimo
porque o primeiro pacote usual é de 21 bytes, não 12, consulte "Connection Initiation" em x.org/releases/current/doc/xproto/x11protocol.html
Massimo
1
Apenas tentei o xtrace - pode confirmar que também funciona bem; sua saída é mais compacta, com uma linha por mensagem - e também é facilmente aceitável. Corra com, por exemplo. xtrace -D:1 -d:0 -k. (Ou x11trace, como o executável é chamado em algumas distros)
Aleksi Torhamo
4

O X11 usa o TCP como seu protocolo de transporte. O intervalo de portas TCP para o X11 geralmente é de 6000 a 6063, mas provavelmente você verá a porta TCP 6000 sendo usada.

Portanto, você poderá usar qualquer monitor de rede de sua escolha para observar o tráfego filtrando esse intervalo de portas e os hosts em questão. Eu também sei que wireshark, por exemplo, já contém uma predefinição de filtrox11 para monitorar o tráfego no qual você está interessado.

Por exemplo, para monitorar todo o tráfego X11 na máquina local (se estiver usando TCP; consulte a resposta de @ Stéphane Chazelas), use o seguinte filtro:

x11 and ip.src=127.0.0.1 and ip.dst=127.0.0.1
invasor
fonte
As mensagens locais cliente-servidor são transmitidas através de um soquete de domínio unix lsof -U | grep '^X',.
23715 goldilocks