Capturez le trafic du protocole X11

15

Comment capturer le trafic du protocole X11 ?

J'ai besoin de trouver un moyen de capturer le trafic X11 entre deux machines et également entre un serveur X11 et un client X11 sur une machine locale.

zh_
la source

Réponses:

19

Vous pouvez parler X11 sur TCP, ou sur un socket de domaine Unix ou (sous Linux) sur un socket de domaine Unix dans l' espace de noms abstrait .

Lorsque DISPLAY est réglé sur host:4, abréviation detcp/host:4 , les clients utilisent TCP pour se connecter au serveur. Le port TCP est alors 6000 plus le numéro d'affichage (dans ce cas 6004).

Dans ce cas, vous pouvez capturer le trafic avec n'importe quel renifleur réseau comme tcpdumpou wiresharken capturant le trafic TCP sur ce port.

Lorsque $DISPLAYest seulement :4(abréviation de unix/:4), les clients utilisent une socket de domaine Unix. Soit /tmp/.X11-unix/X4ou le même chemin dans l' espace de noms ABSTRACT (généralement affiché comme @/tmp/.X11-unix/X4dans la netstatsortie).

La capture du trafic est alors plus délicate.

Si votre serveur X écoute sur TCP (mais ils n'ont plus tendance à le faire de nos jours), le plus simple est de passer DISPLAYà la localhost:4place de :4et de capturer le trafic réseau sur le port 6004 sur l'interface de bouclage.

Si ce n'est pas le cas, vous pouvez utiliser en socattant qu'homme au milieu qui accepte les connexions en TCP et les transfère en tant qu'unix ou abstrait :

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

Vous pouvez ensuite définir $DISPLAYà localhost:4et capturer le trafic réseau comme ci - dessus ou dire socatde vider avec -x -v.

Maintenant, si vous ne pouvez pas changer $DISPLAYet que vous souhaitez capturer le trafic d'une application X locale déjà en cours d'exécution qui utilise des sockets de domaine Unix, c'est là que cela devient difficile.

Une approche pourrait consister à utiliser strace (ou la commande équivalente sur votre système si ce n'est Linux) pour tracer les appels système d'envoi / réception que votre application fait pour communiquer avec le serveur X.

Ici xterm, je le constate writev(), recvfrom()et le recvmsg()système appelle le descripteur de fichier 3 pour cela. Je peux donc faire:

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 -).

L'idée étant d'extraire l'horodatage et les octets envoyés / reçus de la sortie de straceet de les utiliser text2pcappour les convertir en pcap(en ajoutant des en-têtes TCP factices sur le port 6000 avec -T6000,1234) avant de les alimenter wireshark. Nous avons également divisé les paquets pour éviter la limite de 64 Ko sur la longueur maximale d'un enregistrement PCAP.

Notez que pour text2pcapfonctionner correctement en ce qui concerne la bonne direction du trafic, vous avez besoin d'une version relativement récente de Wireshark.

Stéphane Chazelas
la source
Connaissez-vous la raison de la défaillance des sockets de domaine Unix? TCP a-t-il un impact (significatif) sur les performances ou d'autres inconvénients?
inVader
@inVader, eh bien oui, c'est un protocole TCP / IP complet à implémenter, passant par plusieurs couches ... Je suppose que le système peut prendre des raccourcis (comme ne pas implémenter l'algorithme d'évitement de congestion habituel) pour les connexions en boucle, mais quand même, dans mes tests J'obtiens deux fois plus de débit avec un socket de domaine unix simple qu'avec un test socat de socket TCP.
Stéphane Chazelas
14

Si vous êtes principalement intéressé par le protocole X11 et non par les éléments TCP / IP et Ethernet sous-jacents, et si vous êtes en mesure d'ajuster les paramètres du client ou du serveur, vous pouvez utiliser un outil spécialement conçu pour capturer et décoder le trafic entre un X11 client et un serveur X11. Contrairement auwireshark dissecteur X11, il est peu probable que ces outils soient confondus par le trafic, car ils y sont pleinement impliqués.

Le principal est xscope qui, bien qu'il ne soit pas disponible en tant que binaire pour certaines distributions Unix ou Linux, peut facilement être construit à partir des sources .

Alternativement, il existe également xtruss et xtrace mais je n'ai aucune expérience avec eux.

Tous ces outils agissent comme des proxys inverses relayant les connexions à un vrai serveur X11. Les clients utilisent simplement une variable DISPLAY différente (ou argument -display) pour se connecter au proxy.

par exemple:

$ 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

Remarque: Si, pour une raison quelconque, vous ne pouvez pas modifier les paramètres des clients X11 (affichage), vous pourrez peut-être reconfigurer le serveur pour écouter un autre port (généralement 6001 vs 6000), puis configurer xscopepour écouter sur le port d'origine (6000).

jlliagre
la source
J'ai essayé de compiler xscope ... "Aucun package 'xproto' trouvé". pls pouvez-vous écrire ici le vidage du premier paquet (12 octets)?
Massimo
@Massimo Avez-vous installé le package manquant?
jlliagre
J'utilise une distance Linux sur Amazon, et yum ne connaît pas xproto. Pls pouvez-vous poster le vidage du premier paquet? J'ai seulement besoin de ça, thks.
Massimo
beacuse le premier paquet habituel est de 21 octets, pas 12, voir "Connection Initiation" dans x.org/releases/current/doc/xproto/x11protocol.html
Massimo
1
Je viens d'essayer xtrace - peut confirmer qu'il fonctionne également très bien; sa sortie est plus compacte, avec une ligne par message - donc aussi facilement greppable. Exécuter avec par exemple. xtrace -D:1 -d:0 -k. (Ou x11trace, comme l'exécutable est nommé sur certaines distributions)
Aleksi Torhamo
4

X11 utilise TCP comme protocole de transport. La plage de ports TCP pour X11 est généralement de 6000 à 6063, mais vous verrez très probablement le port TCP 6000 utilisé.

Vous devriez donc pouvoir utiliser n'importe quel moniteur réseau de votre choix pour observer le trafic en filtrant cette plage de ports et les hôtes en question. Je sais également que wireshark, par exemple, contient déjà un filtre prédéfini x11pour surveiller le trafic qui vous intéresse.

Par exemple, pour surveiller tout le trafic X11 sur la machine locale (si vous utilisez TCP; reportez-vous à la réponse de @ Stéphane Chazelas) utilisez le filtre suivant:

x11 and ip.src=127.0.0.1 and ip.dst=127.0.0.1
envahisseur
la source
Les messages locaux client-serveur sont transmises via un socket de domaine Unix, lsof -U | grep '^X'.
goldilocks