Comment visualiser le trafic réseau demandé par une application spécifique?

Si vous avez un téléphone rooté, optez pour les outils de ligne de commande nethogs (pour la surveillance en direct) ou iptables (pour obtenir des statistiques). L’utilisation de VPN ou d’applications Android basées sur les statistiques est la seule solution non rootée possible. Ou consultez cette réponse pour une solution basée sur logcat/dumpsys.

Tout d’abord, le suivi d’un UID ou d’un PID d’un flux réseau n’est pas simple car ce ne sont pas des paramètres liés au réseau mais au système d’exploitation. Les propositions et les projets abandonnés existent.

Android attribue un UID unique à chaque application installée tout comme chaque utilisateur humain sur Linux a un UID. Nous pouvons donc capturer les paquets envoyés par un UID spécifique sur les interfaces réseau pour suivre l’utilisation.

TCPDUMP:

Maintenant comment pouvons-nous capturer le trafic réseau ? La plupart des renifleurs de réseau utilisent la famille libpcap de bibliothèques indépendantes du système à cette fin. Elle prend en charge BSD Packet Filter (BPF) pour le filtrage des paquets dans le noyau. Certains utilitaires populaires qui utilisent libpcap comprennent tcpdump, nmap, tshark/wireshark, dumpcap, nethogs etc. Les utilitaires réseau de l’application Android et d’autres font également usage de tcpdump.

Cependant, l’info UID n’est pas propagée par le canal AF_PACKET/PF_PACKET que pcap utilise à la couche OSI 2. Donc, ce que nous pouvons faire ici est d’utiliser les sockets réseau (combinaison d’IP et de port) créés et utilisés par une application. netstat -tup ou ss -tup montreront toutes les sockets réseau avec des connexions actives/établies. Les deux outils sont disponibles sur Android (ou vous pouvez obtenir un binaire statique), ss est le plus récent. Les informations sur les sockets vs. UID peuvent aussi être lues directement à partir de /proc/net/{tcp,udp}. L’application Android Netstat Plus fonctionne sur le même principe. Cela fournira l’adresse locale (socket) utilisée par un processus.

Une fois que nous savons quels sockets sont utilisés par un processus (UID), tcpdump -i wlan0 src <IP> and port <PORT> déversera l’ensemble du trafic provenant de ce processus.
De même, un socket distant (s’il n’est pas connecté par plusieurs applis) peut également être utilisé pour filtrer les résultats.

LIMITATIONS:

Cependant, il y a quelques problèmes avec cette approche:

  • Les apps Android lancent généralement plus d’un processus à la fois en parallèle, c’est-à-dire plusieurs PID travaillant sous le même UID. Nous devons donc capturer le trafic de tous les processus.
  • Les applications continuent à créer et à supprimer des sockets. Garder la trace des sockets qui changent continuellement est presque impossible en particulier lorsqu’il y a un grand nombre d’apps accédant au réseau simultanément.
  • Il y a – bien que rare – la possibilité que les sockets locaux soient partagés par plusieurs processus sur les OS de type UNIX. Les sockets partagés à distance tels que UDP/53 qui est utilisé pour la résolution DNS ne peuvent pas être suivis pour un seul processus. Cela affaiblit encore plus l’approche.

NetHogs traverse procfs et fait face aux limitations ci-dessus (bien que pas toujours très réussies):

IPTABLES:

Les défauts décrits ci-dessus d’un outil de couche 2 peuvent être atténués en utilisant iptables LOG ou NFLOG. La couche 2 est juste au-dessus de la couche physique c’est-à-dire que c’est la dernière chose que les paquets rencontrent avant de quitter le périphérique. C’est pourquoi, étant à la couche liaison de données et travaillant à un niveau inférieur de la pile du réseau, BPF est une sorte de mécanisme de filtrage de paquets sans état par rapport à netfilter / iptables qui travaille à la couche 3 de l’OSI (plus proche des programmes de l’espace utilisateur). Ainsi, iptables peut également obtenir des informations de la pile TCP/IP (couche 4). Il filtre les paquets en fonction des UID de leurs créateurs en utilisant le module owner qui interagit avec les sockets pour trouver la propriété des paquets.

iptables écrit dans le journal du noyau qui peut être lu en utilisant dmesg ou logcat. L’UID d’une application peut être obtenu en utilisant une certaine application ou lu à partir de /data/system/packages.list ou pm list packages -U.

# iptables -I OUTPUT -m owner --uid-owner <UID> -j LOG --log-level 7 --log-prefix 'SNIFFER: ' --log-uid# dmesg -w | grep SNIFFER

La sortie peut être enregistrée dans un fichier et formatée en utilisant des outils comme grep, awk, printf etc. Network Log – bien que très obsolète – fonctionne de manière similaire. AFWall+ est un pare-feu basé sur iptables qui peut enregistrer / notifier l’activité réseau d’une app lorsque celle-ci est bloquée.

Le seul inconvénient de cette approche est qu’elle ne peut pas être utilisée pour renifler le trafic d’un processus lorsqu’il y a plusieurs processus en cours d’exécution avec le même UID. iptables ne peut pas capturer les paquets basés sur les PIDs. Ils ont décidé de ne pas utiliser iptables avec les processus car le processus est démarré avant d’être bloqué/reniflé, et le programme pourrait facilement engendrer un processus enfant avec un nouveau PID qui ne serait pas bloqué/reniflé. De plus, les PIDs sont créés et détruits aussi rapidement que les sockets. Il y a donc toujours de la place pour que le trafic soit fui.

QTAGUID:

owner module ne fonctionnera pas pour le trafic entrant ou transféré parce que les paquets IP ne portent aucune information de propriété. Pour mesurer l’utilisation du réseau entrant / sortant par application, Android a patché le noyau pour inclure le module qtaguid. Nous pouvons lire les statistiques de /proc/net/xt_qtaguid/stats. Avec quelques scripts shell obtenir l’utilisation des données en direct depuis le redémarrage:

Mais sur Android 9+, qtaguid est remplacé par le BPF étendu (qui est également prévu pour remplacer netfilter framework dans le noyau Linux). Relié : Quel processus est responsable de la capture de l’utilisation des données ?

IPTABLES + TCPDUMP:

Une alternative est de mettre le trafic sortant d’une app dans un groupe NFLOG et plus tard tcpdump capture les paquets de ce groupe:

# iptables -I OUTPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30# tcpdump -i nflog:30

C’est pour s’assurer que nous nous rapprochons de la couche physique lorsque nous reniflons le trafic sortant. Mais cela peut toujours donner de faux positifs, par exemple si les paquets sont abandonnés / perdus dans les tables de routage. C’est pourquoi les renifleurs fonctionnent à la couche OSI 2. Ou encore mieux, vous pouvez observer depuis l’extérieur, par exemple en utilisant un serveur proxy / VPN ou sur un PC branché ou sur un routeur. Mais cela ne capturera pas le trafic sur une base par UID/PID.

AUTRES OPTIONS:

  • Utiliser des outils de diagnostic comme strace pour suivre syscalls liés à l’activité réseau d’un processus. force_bind et tracedump fonctionnent également sur le même principe. Le sous-système d’audit du noyau Linux peut être utilisé pour la même chose.
  • Utiliser le classificateur réseau cgroup avec iptables NETFILTER_XT_MATCH_CGROUP pour renifler le trafic de certains processus.
  • Utiliser Network Namespaces pour isoler les processus et lire l’utilisation des données sur une base par interface. nstrace fonctionne sur le même principe.
  • Si l’intention est entièrement de bloquer le trafic provenant de certains processus, SELinux et seccomp peuvent être utilisés pour restreindre la capacité des processus à créer des sockets en définissant respectivement restricted policies et suppressing syscalls.

La plupart de ces options ne sont pas directement viables pour Android et nécessitent des configurations avancées.

Les API d’Android (OPTIONS NON-ROOT):

Certaines applications comme NetGuard utilisent l’API VpnService d’Android pour bloquer le trafic à la couche 3 (interface TUN). L’app peut « notifier quand une application accède à l’internet ». La capture et le suivi par application (1, 2) sont possibles en utilisant l’API VPN car Android fait usage de UIDs et SOcket_MARKs (1, 2) pour contrôler le trafic dans la politique de routage du réseau (RPDB), juste avant de quitter l’appareil.

Certaines apps comme NetLive font usage de NetworkStatsManager, mais il est en retard sur l’utilisation en temps réel et « ne se met pas à jour assez rapidement », il est « censé fournir des données historiques ».