Wie kann man den von einer bestimmten App angeforderten Netzwerkverkehr anzeigen?
Wenn Sie ein verwurzeltes Telefon haben, verwenden Sie nethogs
(für Live-Überwachung) oder iptables
(um Statistiken zu erhalten) Kommandozeilen-Tools. Die Verwendung von VPN oder auf Android-Statistiken basierenden Apps ist die einzig mögliche Lösung ohne Root. Oder lesen Sie diese Antwort für eine logcat
/dumpsys
-basierte Lösung.
Zunächst einmal ist die Verfolgung einer UID oder PID eines Netzwerkstreams nicht einfach, da diese Parameter nicht netzwerkbezogen, sondern betriebssystembezogen sind. Es gibt Vorschläge und aufgegebene Projekte.
Android weist jeder installierten App eine eindeutige UID zu, so wie jeder menschliche Benutzer unter Linux eine UID hat. So können wir Pakete erfassen, die von einer bestimmten UID über die Netzwerkschnittstellen gesendet werden, um die Nutzung zu verfolgen.
TCPDUMP:
Wie können wir nun den Netzwerkverkehr erfassen? Die meisten Netzwerk-Sniffer verwenden zu diesem Zweck die systemunabhängigen Bibliotheken der libpcap-Familie. Sie unterstützt BSD Packet Filter (BPF) zur Filterung von Paketen im Kernel. Einige beliebte Dienstprogramme, die libpcap
verwenden, sind tcpdump
, nmap
, tshark/wireshark
, dumpcap
, nethogs
usw. Die Android-App Network Utilities und andere nutzen ebenfalls tcpdump
.
Die UID-Informationen werden jedoch nicht über den AF_PACKET
/PF_PACKET
-Kanal weitergegeben, den pcap
auf OSI-Schicht 2 verwendet. Was wir hier also tun können, ist die Verwendung von Netzwerk-Sockets (Kombination aus IP und Port), die von einer Anwendung erstellt und verwendet werden. netstat -tup
oder ss -tup
zeigt alle Netzwerk-Sockets mit aktiven/aufgebauten Verbindungen an. Beide Tools sind unter Android verfügbar (oder Sie können eine statische Binärdatei erhalten), ss
ist die neuere Version. Socket vs. UID Informationen können auch direkt von /proc/net/{tcp,udp}
gelesen werden. Die Android-App Netstat Plus funktioniert nach demselben Prinzip. Sie liefert die lokale Adresse (Socket), die von einem Prozess verwendet wird.
Sobald wir wissen, welche Sockets von einer App (UID) verwendet werden, gibt tcpdump -i wlan0 src <IP> and port <PORT>
den gesamten von diesem Prozess stammenden Datenverkehr aus.
Auch ein entfernter Socket (wenn er nicht von mehreren Apps verwendet wird) kann zum Filtern der Ergebnisse verwendet werden.
Einschränkungen:
Es gibt jedoch einige Probleme mit diesem Ansatz:
- Android-Apps starten in der Regel mehr als einen Prozess gleichzeitig und parallel, d.h. mehrere PIDs arbeiten unter derselben UID. Wir müssen also den Datenverkehr von allen Prozessen erfassen.
- Apps erstellen und löschen ständig Sockets. Es ist fast unmöglich, den Überblick über die sich ständig ändernden Sockets zu behalten, insbesondere wenn eine große Anzahl von Anwendungen gleichzeitig auf das Netzwerk zugreift.
- Es besteht die – wenn auch seltene – Möglichkeit, dass lokale Sockets von mehreren Prozessen auf UNIX-ähnlichen Betriebssystemen gemeinsam genutzt werden. Entfernte gemeinsam genutzte Sockets wie UDP/53, das für die DNS-Auflösung verwendet wird, können nicht für einen einzelnen Prozess verfolgt werden. Dies schwächt den Ansatz weiter.
NetHogs durchläuft procfs
und kommt mit den oben genannten Einschränkungen zurecht (wenn auch nicht immer sehr erfolgreich):
IPTABLES:
Die oben beschriebenen Unzulänglichkeiten eines Layer-2-Tools können mit iptables LOG
oder NFLOG
gemildert werden. Layer 2 liegt direkt über dem Physical Layer, d.h. es ist das letzte, was die Pakete durchlaufen, bevor sie das Gerät verlassen. Deshalb ist BPF, da es sich auf der Datenverbindungsschicht befindet und auf einer niedrigeren Ebene des Netzstapels arbeitet, eine Art zustandsloser Paketfiltermechanismus im Vergleich zu netfilter
/ iptables
, der auf der OSI-Schicht 3 (näher an den Benutzerprogrammen) arbeitet. So kann iptables
auch Informationen vom TCP/IP-Stack (Schicht 4) erhalten. Es filtert Pakete auf der Grundlage ihrer Ersteller-UIDs mit Hilfe des Moduls owner
, das mit Sockets interagiert, um die Eigentümerschaft von Paketen zu ermitteln.
iptables
schreibt in das Kernel-Log, das mit dmesg
oder logcat
gelesen werden kann. Die UID einer App kann mit einer App ermittelt oder von /data/system/packages.list
oder pm list packages -U
gelesen werden.
# iptables -I OUTPUT -m owner --uid-owner <UID> -j LOG --log-level 7 --log-prefix 'SNIFFER: ' --log-uid# dmesg -w | grep SNIFFER
Der Output kann in einer Datei gespeichert und mit Tools wie grep
, awk
, printf
usw. formatiert werden. Network Log – obwohl sehr veraltet – funktioniert auf ähnliche Weise. AFWall+ ist eine auf iptables
basierende Firewall, die die Netzwerkaktivität einer App protokollieren / melden kann, wenn die App blockiert ist.
Der einzige Nachteil dieses Ansatzes ist, dass er nicht verwendet werden kann, um den Datenverkehr eines Prozesses auszuspähen, wenn mehrere Prozesse mit derselben UID laufen. iptables
kann keine Pakete auf der Basis von PIDs erfassen. Es wurde beschlossen, iptables
nicht mit Prozessen zu verwenden, da der Prozess gestartet wird, bevor er blockiert/gesnifft wird, und das Programm leicht einen Kindprozess mit neuer PID erzeugen könnte, der nicht blockiert/gesnifft würde. Außerdem werden PIDs genauso schnell erstellt und zerstört wie Sockets. Das Modul
QTAGUID:
owner
funktioniert nicht für eingehenden oder weitergeleiteten Verkehr, da IP-Pakete keine Eigentumsinformationen enthalten. Um die eingehende/ausgehende Netzwerknutzung pro App zu messen, hat Android den Kernel gepatcht, um das Modul qtaguid
aufzunehmen. Wir können Statistiken von /proc/net/xt_qtaguid/stats
lesen. Mit etwas Shell-Skripting kann man die Datennutzung seit dem Neustart live abrufen:
Allerdings wird qtaguid
unter Android 9+ durch das erweiterte BPF ersetzt (das auch das netfilter
-Framework im Linux-Kernel ersetzen soll). Verwandt: Welcher Prozess ist für die Erfassung der Datennutzung verantwortlich?
IPTABLES + TCPDUMP:
Eine Alternative ist es, den ausgehenden Datenverkehr einer App in eine NFLOG
Gruppe zu packen und später mit tcpdump Pakete aus dieser Gruppe zu erfassen:
# iptables -I OUTPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30# tcpdump -i nflog:30
Damit wird sichergestellt, dass wir beim Sniffing des ausgehenden Datenverkehrs näher an die physikalische Schicht herankommen. Aber es kann immer noch falsch-positive Ergebnisse liefern, z.B. wenn Pakete in Routing-Tabellen verworfen werden/verloren gehen. Deshalb arbeiten Sniffer auf OSI-Schicht 2. Noch besser ist es, den Datenverkehr von außen zu beobachten, z. B. über einen Proxy-/VPN-Server oder auf einem angebundenen PC oder am Router. Aber das wird den Verkehr nicht auf UID/PID-Basis erfassen.
Weitere Optionen:
- Verwenden Sie Diagnosewerkzeuge wie
strace
, umsyscalls
in Bezug auf die Netzwerkaktivität eines Prozesses zu verfolgen. force_bind und tracedump arbeiten auch nach dem gleichen Prinzip. Das Audit-Subsystem des Linux-Kernels kann für dasselbe verwendet werden. - Verwenden Sie den Netzwerkklassifizierer cgroup mit
iptables
NETFILTER_XT_MATCH_CGROUP
, um den Datenverkehr von bestimmten Prozessen zu erschnüffeln. - Verwenden Sie
Network Namespaces
, um Prozesse zu isolieren und die Datennutzung pro Schnittstelle zu lesen. nstrace funktioniert nach demselben Prinzip. - Wenn die Absicht ist, den von bestimmten Prozessen ausgehenden Verkehr vollständig zu blockieren, können
SELinux
undseccomp
verwendet werden, um die Fähigkeit der Prozesse, Sockets zu erstellen, einzuschränken, indem man restrictedpolicies
bzw. suppressingsyscalls
definiert.
Die meisten dieser Optionen sind für Android nicht ohne Weiteres realisierbar und erfordern fortgeschrittene Konfigurationen.
ANDROID’S APIs (NON-ROOT OPTIONS):
Einige Apps wie NetGuard nutzen die VpnService API von Android, um den Datenverkehr auf Layer 3 (TUN-Schnittstelle) zu blockieren. Die App kann „benachrichtigen, wenn eine Anwendung auf das Internet zugreift“. Die Erfassung und Verfolgung pro App (1, 2) ist mit der VPN-API möglich, da Android UIDs
und SOcket_MARKs
(1, 2) nutzt, um den Verkehr in der Netzwerk-Routing-Richtlinie (RPDB) zu kontrollieren, kurz bevor er das Gerät verlässt.
Einige Apps wie NetLive nutzen den NetworkStatsManager, aber er hinkt der Echtzeitnutzung hinterher und „aktualisiert nicht schnell genug“, er ist „dafür gedacht, historische Daten zu liefern“.