Jak zobrazit síťový provoz požadovaný konkrétní aplikací?

Pokud máte rootnutý telefon, použijte nástroje příkazového řádku nethogs (pro živé sledování) nebo iptables (pro získání statistik). Použití VPN nebo aplikací založených na statistikách Androidu je jediným možným řešením bez rootu. Nebo se podívejte na tuto odpověď pro řešení založené na logcat/dumpsys.

Především, sledování UID nebo PID síťového streamu není jednoduché, protože to nejsou parametry související se sítí, ale s operačním systémem. Návrhy a opuštěné projekty existují.

Android přiřazuje jedinečné UID každé nainstalované aplikaci, stejně jako má UID každý lidský uživatel v Linuxu. Můžeme tedy zachytávat pakety odesílané konkrétním UID přes síťová rozhraní a sledovat jejich používání.

TCPDUMP:

Jak tedy můžeme zachytávat síťový provoz? Většina síťových snifferů používá k tomuto účelu rodinu knihoven libpcap, které jsou nezávislé na systému. Podporuje BSD Packet Filter (BPF) pro filtrování paketů v jádře. Mezi oblíbené nástroje, které používají libpcap, patří tcpdump, nmap, tshark/wireshark, dumpcap, nethogs atd. Síťové nástroje aplikace Android a další také využívají tcpdump.

Informace UID se však nešíří kanálem AF_PACKET/PF_PACKET, který používá pcap na 2. vrstvě OSI. Co zde tedy můžeme udělat, je využít síťové sokety (kombinace IP a portu), které jsou vytvářeny a používány aplikací. netstat -tup nebo ss -tup zobrazí všechny síťové zásuvky s aktivními/zavedenými spojeními. Oba nástroje jsou k dispozici v systému Android (nebo si můžete pořídit statickou binárku), ss je novější. Informace o soketu vs. UID lze také přímo vyčíst z /proc/net/{tcp,udp}. Na stejném principu funguje i aplikace Netstat Plus pro Android. Ta poskytne lokální adresu (socket) používanou procesem.

Jakmile víme, jaké sockety používá aplikace (UID), tcpdump -i wlan0 src <IP> and port <PORT> vypíše celý provoz pocházející z tohoto procesu.
Podobně lze pro filtrování výsledků použít i vzdálený socket (pokud k němu není připojeno více aplikací).

Omezení:

U tohoto přístupu však existují určité problémy:

  • Aplikace pro Android obvykle paralelně spouštějí více procesů najednou, tj. pod stejným UID pracuje více PID. Musíme tedy zachytávat provoz ze všech procesů.
  • Aplikace neustále vytvářejí a mažou zásuvky. Sledovat neustále se měnící zásuvky je téměř nemožné, zejména pokud k síti přistupuje velké množství aplikací současně.
  • V operačních systémech typu UNIX existuje – i když vzácná – možnost, že místní zásuvky jsou sdíleny více procesy. Vzdálené sdílené zásuvky, jako je UDP/53, který se používá pro překlad DNS, nelze sledovat pro jeden proces. To tento přístup dále oslabuje.

NetHogs prochází procfs a s výše uvedenými omezeními se vyrovnává (i když ne vždy příliš úspěšně):

IPTABLES:

Výše popsané nedostatky nástroje 2. vrstvy lze zmírnit pomocí iptables LOG nebo NFLOG. Vrstva 2 je těsně nad fyzickou vrstvou, tj. je to poslední věc, se kterou se pakety setkají, než opustí zařízení. Proto, protože se nachází na vrstvě Data Link Layer a pracuje na nižší úrovni síťového zásobníku, je BPF jakýmsi bezstavovým mechanismem filtrování paketů ve srovnání s netfilter / iptables, který pracuje na vrstvě OSI 3 (blíže k programům v uživatelském prostoru). Takže iptables může také získávat informace ze zásobníku TCP/IP (vrstva 4). Filtruje pakety na základě UID jejich tvůrců pomocí modulu owner, který komunikuje se sokety a zjišťuje vlastnictví paketů.

iptables zapisuje do protokolu jádra, který lze číst pomocí dmesg nebo logcat. UID aplikace lze zjistit pomocí některé aplikace nebo přečíst z /data/system/packages.list nebo 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

Výstup lze uložit do souboru a formátovat pomocí nástrojů jako grep, awk, printf atd. Síťový protokol – ačkoli je velmi zastaralý – funguje podobně. AFWall+ je brána firewall založená na iptables, která může zaznamenávat / upozorňovat na síťovou aktivitu aplikace, když je aplikace blokována.

Jedinou nevýhodou tohoto přístupu je, že jej nelze použít k odposlouchávání provozu z jednoho procesu, pokud běží více procesů se stejným UID. iptables Nelze zachytávat pakety na základě PID. Rozhodli se nepoužívat iptables u procesů, protože proces je spuštěn dříve, než je blokován/sniffován, a program by mohl snadno vytvořit podřízený proces s novým PID, který by nebyl blokován/sniffován. Také PID jsou vytvářeny a ničeny stejně rychle jako sockety. Takže vždy existuje prostor pro únik provozu.

QTAGUID:

owner Modul nebude fungovat pro příchozí nebo předávaný provoz, protože pakety IP nenesou žádné informace o vlastnictví. Aby bylo možné měřit využití příchozí/odchozí sítě pro jednotlivé aplikace, Android opravil jádro tak, aby obsahovalo modul qtaguid. Statistiky můžeme číst z modulu /proc/net/xt_qtaguid/stats. Pomocí nějakého shellového skriptu získáme živé využití dat od restartu:

V systému Android 9+ je však modul qtaguid nahrazen rozšířeným modulem BPF (který má rovněž nahradit rámec netfilter v linuxovém jádře). Související:

IPTABLES + TCPDUMP:

Alternativou je umístit odchozí provoz z aplikace do skupiny NFLOG a později tcpdump zachycuje pakety z této skupiny:

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

Tím se zajistí, že se při sniffování odchozího provozu dostaneme blíže k fyzické vrstvě. Ale i tak to může dávat falešně pozitivní výsledky, např. pokud jsou pakety zahozeny / ztraceny ve směrovacích tabulkách. Proto sniffery pracují na druhé vrstvě OSI. Nebo ještě lepší je sledovat zvenčí, např. pomocí proxy serveru / VPN serveru nebo na tethered PC nebo na routeru. Tím ale nezachytíte provoz na základě jednotlivých UID/PID.

Další možnosti:

  • Pro sledování syscalls související se síťovou aktivitou procesu použijte diagnostické nástroje jako strace. na stejném principu fungují také force_bind a tracedump. K témuž lze použít auditní subsystém linuxového jádra.
  • Pomocí síťového klasifikátoru cgroup s iptables NETFILTER_XT_MATCH_CGROUP lze odposlouchávat provoz určitých procesů.
  • Pomocí Network Namespaces lze izolovat procesy a číst využití dat na základě jednotlivých rozhraní. nstrace funguje na stejném principu.
  • Pokud je záměrem zcela zablokovat provoz pocházející z určitých procesů, lze pomocí SELinux a seccomp omezit schopnost procesů vytvářet sokety definováním omezeného policies, resp. potlačeného syscalls.

Většina z těchto možností není pro systém Android přímo proveditelná a vyžaduje pokročilou konfiguraci.

Aplikace API systému Android (možnosti bez rootování):

Některé aplikace, například NetGuard, používají rozhraní API VpnService systému Android k blokování provozu na 3. vrstvě (rozhraní TUN). Aplikace může „upozornit, když aplikace přistupuje k internetu“. Zachycení a sledování (1, 2) na aplikaci je možné pomocí VPN API, protože Android využívá UIDs a SOcket_MARKs (1, 2) ke kontrole provozu v síťové politice směrování (RPDB), těsně před opuštěním zařízení.

Některé aplikace, jako je NetLive, využívají NetworkStatsManager, ale ten zaostává za využitím v reálném čase a „neaktualizuje se dostatečně rychle“, je „určen k poskytování historických dat“.