Skyduino:~#
Articles
Autre, programmation, projet

[Android] Capture/debug réseau à distance avec tcpdump et Wireshark (sur PC)

Bonjour tout le monde !

Hier, j’ai fait face à un bug plutôt sympathique (comprendre « bien casse-pied et aléatoire ») sur une application Android que j’ai développé pour un client. L’application marche, mais par moment, la connexion réseau (WiFi) décide de faire grève et ne répond plus que « ECONNRESET (connection reset by peer) ». Pas cool, surtout quand tout le reste de l’application marche au poil.
C’est un peu comme avoir un joli gâteau à la crème sous les yeux, mais ne pas pouvoir le soulever pour le mettre dans son assiette sans qu’il parte en morceaux. C’est très frustrant.

Du coup, je me suis retrouvé à devoir regarder ce qu’il se passe au niveau de la communication WiFi. Problème : sur Android c’est loin d’être aussi simple à faire que sur PC.

Sur PC, on lance Wireshark, on râle dix minutes parce que le truc ne capture pas le moindre paquet, on fini par ce rendre compte qu’on écoute sur le mauvais interface réseau, on relance la capture et « voilà ». On obtient alors une jolie trace de toutes les trames réseaux, avec décodage et tout ce qui va bien, en temps réel en plus.

Sur Android … c’est compliqué.
Tout d’abord, il faut un téléphone rooté (soit via une ROM custom style CyanogenMod, soit via une bidouille sauce busybox avec tous les outils qui vont bien). Ensuite il faut un logiciel de capture réseau, pour ça il existe TcpDump for Android. Enfin, il faut un logiciel pour lire le fichier de capture, style Wireshark. Mais même avec tous ces beaux logiciels en main, il faut une bonne dose de patience.

Il existe une montagne de tutoriel d’utilisation de TcpDump pour Android avec Wireshark, mais tous ces tutoriels ont un défaut majeur : on doit d’abord capturer les trames, puis les analyser sur PC en passant par une carte SD ou le mode clef USB du smartphone/tablette. Pour la capture en temps réel, on repassera. Or, pour faire du débug de problèmes réseau, le temps réel, c’est obligatoire.

Je me suis donc demandé s’il n’était pas possible de faire un script. Vous savez, le genre de script tout pourri qu’on fait en 20 minutes sur un coin de table mais qui vous sauve des heures de boulot ensuite (en plus de pas mal de prise de tête).
Eh bien oui, c’est possible. En plus, ça marche tellement bien que j’en suis moi-même impressionné. Un clic et hop, on débug le réseau d’une tablette /smartphone en temps réel comme sur PC, mais sur Android, tout en ayant tous les avantages d’être sur PC pour analyser les résultats.


Le script

Pour fonctionner, le script à besoin :
– de l’utilitaire ADB (Android Debug Bridge), disponible dans le SDK Android,
– de netcat, version ARM (pour Android) et version x86 (pour PC),
– de TcpDump pour Android,
– d’un smartphone / tablette Android rooté (la commande « adb root » doit pouvoir fonctionner),
– du débug USB activé au niveau de la tablette / smartphone (et les drivers qui vont bien côté PC).

@echo off

echo Starting Android TCP capture script ...
echo.

echo ----- ADB version
adb version
echo.

echo ----- Connected devices
adb devices -l

echo ----- Waiting for the device to be ready
adb wait-for-device
echo.

echo ----- Run ADB as root  ...
adb root
echo.

echo ----- Remove old TCPDUMP binary ...
adb shell rm /data/local/tcpdump
adb shell rm /data/local/nc
echo.

echo ----- Upload TCPDUMP binary ...
adb push tcpdump /data/local/tcpdump
adb shell chmod 755 /data/local/tcpdump
adb shell ls -l /data/local/tcpdump
echo.

echo ----- Upload NETCAT binary ...
adb push nc /data/local/nc
adb shell chmod 755 /data/local/nc
adb shell ls -l /data/local/nc
echo.

echo ----- Starting the remote TCP capture service ...
start adb shell "/data/local/tcpdump -n -U -w - | /data/local/nc -l -p 12345"
echo.

echo ----- Starting the Wireshark client ...
adb forward tcp:12345 tcp:12345
PING 1.1.1.1 -n 1 -w 2000 >NUL
nc 127.0.0.1 12345 | "C:\Program Files\Wireshark\wireshark" -k -i -
pause

Le principe de fonctionnement est simple :
1) Le script lance ADB avec les droits root (pour avoir un accès complet au système).
2) Le script envoie sur le téléphone les binaires tcpdump et nc (netcat) pour la suite du script. Les anciens binaires sont supprimés au besoin.
3) Le script lance tcpdump sur le téléphone dans une console séparée et redirige la sortie de tcpdump dans netcat qui tourne mode serveur local.
4) Le script créé une redirection de port virtuel via ADB pour permettre d’accéder au port local sur lequel netcat attend.
5) Le script lance Wireshark qui se connecte sur le port en attente par netcat, qui lui redirige la sortie de tcpdump en temps réel. Le ping sert de délai pour laisser le temps à tcpdump de se lancer sur le téléphone.
6) Voilà

Quand on a fini, il suffit de fermer Wireshark, ce qui ferme netcat, puis tcpdump et pour finir le script. C’est beau, c’est bien, c’est magique.

J’ai fait une archive avec tous les binaires qui vont bien et le script, elle est dispo sur mon dropbox : androidtcpdump.zip
Pour les linuxiens / mackintosien, je vous laisse refaire le script en bash. À part le ping d’attente, il ne devrait pas y avoir beaucoup de modifications à faire 😉

Enjoy 😉

Advertisements

Discussion

12 réflexions sur “[Android] Capture/debug réseau à distance avec tcpdump et Wireshark (sur PC)

  1. Et pourquoi ne pas faire passer le trafic Wifi du smartphone via un équipement capable de faire un wireshark en live ?

    Par exemple un PC sous windows ou Linux configuré en AP sur le Wifi, et connecté à Internet via le port ethernet. Le smartphone se connecte en Wifi à l’AP du PC, le trafic est routé vers l’ethernet, et on lance un Wireshark sur le PC en sniffant l’interface Wifi.

    Cela a l’avantage de ne pas devoir rooter le smartphone et donc de pouvoir fonctionner avec tout smartphone…

    PS: je viens de découvrir ton site: super intéressant, merci 😉

    Publié par xavierluthi | 4 décembre 2015, 13 h 49 min
    • > Et pourquoi ne pas faire passer le trafic Wifi du smartphone via un équipement capable de faire un wireshark en live ?

      Tout simplement parce que c’est ultra chiant et que ça n’aide en rien pour du debug « in situ ».

      La capture passive en Wifi requière une carte réseau compatible (dans mon cas j’utilise des cartes Wifi Alfa Network), ce qui est déjà très chiant à trouver vu que les constructeurs ne donne aucune info sur le mode « monitor ».

      Ensuite, même avec une carte compatible ça ne marche que très moyennement sous Windows, donc linux quasi obligatoire. Avec les problèmes habituels de drivers et de droits qui vont avec.

      Une fois la partie hardware ok, il faut paramétrer le software et passer la carte en mode « monitor ».

      A partir de là il y a deux possibilités :
      – le wifi est protégé.
      – le wifi est ouvert.

      Si le wifi est ouvert, c’est bon, on peut de suite voir les trames 802.11 et les paquets TCP/UDP qu’ils transportent.

      Si le wifi est protégé, il faut d’abord connaitre la clef de chiffrement et le mode de chiffrement. Il faut ensuite paramétrer manuellement Wireshark pour qu’il déchiffre les communications.

      SAUF QUE. Pour déchiffrer les communications, il faut que Wireshark intercepte les quatre paquets EAPOL qui sont émis lors de la connexion à la borne Wifi. Ces paquets contiennent la clef aléatoire de chiffrement dérivée de la clef principale connue.

      Il faut donc être en écoute au moment de la connexion au réseau wifi et prier pour que les quatre paquets soit interceptés (ce qui n’est pas toujours le cas). En cas d’échec, il faut recommencer la capture et relancer une connexion au wifi. C’est long, c’est chiant, et c’est impossible à faire sur le terrain.

      Le pire, c’est que même si tu arrives à déchiffrer le trafic, tu te retrouves avec des trames 802.11 (du wifi cible mais aussi du reste qui passe à proximité) mélangées avec des paquets utiles (TCP, UDP, ICMP, ARP, etc). Donc filtrage obligatoire pour ne pas voir défiler des centaines de paquets par seconde.

      Perso je préfère écouter directement à la source 😉

      > Par exemple un PC sous windows ou Linux configuré en AP sur le Wifi, et connecté à Internet via le port ethernet. Le smartphone se connecte en Wifi à l’AP du PC, le trafic est routé vers l’ethernet, et on lance un Wireshark sur le PC en sniffant l’interface Wifi.

      Pour faire de la capture active (contrairement à de la capture passive), le plus simple c’est d’avoir un routeur avec une option « port miroir » qui copie tout le trafic vers un port ethernet de debug (tout les routeurs pro le font).

      Passer un PC en mode AP … mouai, ça marche, certes, mais pour du debug tu risques d’ajouter des bugs en plus à cause d’un mauvais routage ou autre. En plus ça ne t’ais d’aucune aide si le bug est du côté AP et non du côté tablette (ce qui était mon cas).

      Je ne l’ai pas précisé dans l’article (ce n’était pas le sujet) : je travaille avec en face un module Wifi embarqué (RN171 pour les intimes), en mode AP. Après investigation, il s’est avéré qu’il ne gérait tout simplement pas les paquets TCP RST. Une fermeture de socket malheureuse ou une déconnexion et pan, plus de Wifi.

      Quand on suspect un problème réseau, il faut tester « in situ ». Et pour ça, la capture active n’a absolument aucun intérêt 😉
      Du reste … la capture active avec un AP logiciel sur PC n’a pas grand intérêt tout court. A moins qu’on fasse un Rogue AP, ce qui n’est généralement par pour des usages très légaux.

      > Cela a l’avantage de ne pas devoir rooter le smartphone et donc de pouvoir fonctionner avec tout smartphone…

      Quand on dév sur smartphone / tablette, on a généralement un smartphone / tablette orienté développeurs, en plus d’une montagne d’autre smartphone / tablette grand public pour les tests. La possibilité d’accès root c’est presque un prérequis pour faire du dév sur Android.

      Publié par Skywodd | 4 décembre 2015, 14 h 35 min
  2. je sais pas qui c’est ce Peer mais il fait chier a reseter tout le temps les connexions.

    (badum)

    Publié par f4grx | 10 décembre 2015, 11 h 44 min
  3. « Quand on a fini, il suffit de fermer Wireshark, ce qui ferme netcat, puis tcpdump et pour finir le script. C’est beau, c’est bien, c’est magique. » What ? a première vue fermer Wireshark ne fermera que le netcat cote PC via un broken pipe. Comment ça peut fermer le netcat android ?

    Publié par SigSig | 27 janvier 2016, 17 h 02 min
    • Netcat est routé par ADB depuis Android vers le PC et inversement. Il n’y a pas de netcat côté PC.

      Publié par Skywodd | 27 janvier 2016, 17 h 11 min
      • hmm ok, pour moi avec « nc 127.0.0.1 12345 | « C:\Program Files\Wireshark\wireshark » la commande nc, ne s’exécutant pas via un adb shell, se lançait depuis windows.

        Publié par SigSig | 27 janvier 2016, 18 h 06 min
      • My bad, j’avais en tête une autre version du script.

        Oui oui, cette version là utilise bien netcat côté PC.
        Le broken pipe côté PC remonte au netcat Android avec la fermeture du socket réseau.

        Publié par Skywodd | 27 janvier 2016, 18 h 18 min
      • np
        interessant je pensais pas que le client nc en ‘plantant’ pouvait tout faire exploser 🙂

        Publié par SigSig | 27 janvier 2016, 18 h 32 min
      • Ce n’est pas un plantage. C’est une fermeture de socket tout ce qu’il y a de plus normale.

        La fermeture du socket Wireshark/netcat PC se propage au netcat côté PC qui ferme le socket côté netcat Android, qui lui même ferme le pipe côté Android et stoppe Tcpdump avec un broken pipe.

        Publié par Skywodd | 27 janvier 2016, 19 h 15 min
      • Sauf que le netcat en mode serveur (-l) n’est pas censé se fermer parce que son client se deco

        Publié par SigSig | 27 janvier 2016, 22 h 52 min
      • >> Sauf que le netcat en mode serveur (-l) n’est pas censé se fermer parce que son client se deco

        Faux 😉
        Pour que netcat reste en écoute, il faut ajouter l’option -k en plus de -l.

        Publié par Skywodd | 28 janvier 2016, 20 h 14 min
      • hannn, ok 🙂

        Publié par SigSig | 28 janvier 2016, 21 h 11 min

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Skyduino devient Carnet du Maker

Le site Carnet du Maker remplace désormais le blog Skyduino pour tout ce qui touche à l'Arduino, l'informatique et au DIY.