How to view network traffic requested by a specific app?

Jeśli masz zrootowany telefon, przejdź do nethogs (do monitorowania na żywo) lub iptables (aby uzyskać statystyki) narzędzia wiersza poleceń. Korzystanie z VPN lub Android stats oparte aplikacje jest jedynym możliwym nie-root rozwiązanie. Lub odnieś się do tej odpowiedzi dla logcat/dumpsys opartego rozwiązania.

Po pierwsze, śledzenie UID lub PID strumienia sieciowego nie jest proste, ponieważ nie są to parametry związane z siecią, ale związane z systemem operacyjnym. Propozycje i porzucone projekty istnieją.

Android przypisuje unikalny UID do każdej zainstalowanej aplikacji, tak jak każdy ludzki użytkownik w systemie Linux ma UID. Możemy więc przechwytywać pakiety wysyłane przez konkretne UID przez interfejsy sieciowe, aby śledzić ich użycie.

TCPDUMP:

Jak możemy przechwycić ruch sieciowy? Większość snifferów sieciowych używa do tego celu niezależnych od systemu bibliotek z rodziny libpcap. Obsługuje ona BSD Packet Filter (BPF) do filtrowania pakietów w jądrze. Niektóre popularne narzędzia, które używają libpcap obejmują tcpdump, nmap, tshark/wireshark, dumpcap, nethogs itp. Aplikacja Android Network Utilities i inne również korzystają z tcpdump.

Jednakże informacja UID nie jest propagowana przez kanał AF_PACKET/PF_PACKET, którego pcap używa w warstwie 2 OSI. Więc to, co możemy tutaj zrobić, to wykorzystać gniazda sieciowe (kombinacja IP i portu) tworzone i używane przez aplikację. netstat -tup lub ss -tup pokaże wszystkie gniazda sieciowe z aktywnymi/ustanowionymi połączeniami. Oba narzędzia są dostępne na Androida (lub można uzyskać statyczne binarki), ss jest nowsze. Informacje o Socket vs. UID mogą być również odczytane bezpośrednio z /proc/net/{tcp,udp}. Androidowa aplikacja Netstat Plus działa na tej samej zasadzie. Dostarczy nam adres lokalny (gniazdo) używany przez proces.

Gdy już wiemy jakie gniazda są używane przez aplikację (UID), tcpdump -i wlan0 src <IP> and port <PORT> zrzuci cały ruch pochodzący z tego procesu.
Podobnie zdalne gniazdo (jeśli nie jest połączone przez wiele aplikacji) może być również użyte do filtrowania wyników.

LIMITACJE:

Jednakże istnieją pewne problemy z tym podejściem:

  • Aplikacje androidowe zazwyczaj uruchamiają więcej niż jeden proces na raz równolegle, tj. wiele PID pracujących pod tym samym UID. Więc musimy przechwytywać ruch z wszystkich procesów.
  • Apps zachować na tworzenie i usuwanie gniazd. Śledzenie ciągle zmieniających się gniazd jest prawie niemożliwe, szczególnie gdy istnieje duża liczba aplikacji korzystających z sieci jednocześnie.
  • Istnieje – choć rzadka – możliwość, że lokalne gniazda są współdzielone przez wiele procesów w UNIX-owych systemach operacyjnych. Zdalne współdzielone gniazda, takie jak UDP/53, które jest używane do rozwiązywania DNS, nie mogą być śledzone dla pojedynczego procesu. To dodatkowo osłabia podejście.

NetHogs przemierza procfs i radzi sobie z powyższymi ograniczeniami (choć nie zawsze z powodzeniem):

IPTABLES:

Powyżej opisane niedociągnięcia narzędzia warstwy 2 można złagodzić za pomocą iptables LOG lub NFLOG. Warstwa 2 znajduje się tuż nad warstwą fizyczną, czyli jest ostatnią rzeczą, z którą stykają się pakiety przed opuszczeniem urządzenia. Dlatego też BPF, będąc w warstwie łącza danych i pracując na niższym poziomie stosu sieciowego, jest rodzajem bezstanowego mechanizmu filtrowania pakietów w porównaniu do netfilter / iptables, który pracuje w warstwie 3 OSI (bliżej programów przestrzeni użytkownika). Tak więc iptables może również uzyskać informacje ze stosu TCP/IP (warstwa 4). Filtruje pakiety na podstawie identyfikatorów UID ich twórców za pomocą modułu owner, który współdziała z gniazdami w celu znalezienia własności pakietów.

iptables zapisuje do dziennika jądra, który może być odczytany za pomocą dmesg lub logcat. UID aplikacji może być uzyskany przy użyciu jakiejś aplikacji lub odczytany z /data/system/packages.list lub 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

Wyjście może być zapisane do pliku i sformatowane przy użyciu narzędzi takich jak grep, awk, printf itp. Network Log – choć bardzo przestarzały – działa w podobny sposób. AFWall+ to firewall oparty na iptables, który może rejestrować / powiadamiać o aktywności sieciowej aplikacji, gdy aplikacja jest zablokowana.

Jedynym minusem tego podejścia jest to, że nie można go użyć do sniffowania ruchu z jednego procesu, gdy istnieje wiele procesów działających z tym samym UID. iptables nie może przechwytywać pakietów na podstawie PID. Zdecydowano się nie używać iptables z procesami, ponieważ proces jest uruchamiany zanim zostanie zablokowany/sniffowany, a program mógłby łatwo utworzyć proces potomny z nowym PID, który nie zostałby zablokowany/sniffowany. Również PIDy są tworzone i niszczone tak szybko jak gniazda. Więc zawsze jest miejsce na wyciek ruchu.

QTAGUID:

owner Moduł nie będzie działał dla ruchu przychodzącego lub przekazywanego, ponieważ pakiety IP nie niosą informacji o własności. Aby zmierzyć przychodzące / wychodzące użycie sieci przez aplikację, Android załatał jądro tak, aby zawierało moduł qtaguid. Możemy odczytać statystyki z /proc/net/xt_qtaguid/stats. Z niektórych skryptów powłoki uzyskać na żywo wykorzystanie danych od czasu restartu:

Jednakże na Android 9+, qtaguid jest zastępowany przez rozszerzony BPF (który jest również planowany do zastąpienia netfilter ramy w jądrze Linux). Powiązane: Which process is responsible for capturing data usage?

IPTABLES + TCPDUMP:

An alternate is to put the outgoing traffic from an app in an NFLOG group and later tcpdump captures packets from that group:

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

This is to ensure that we get closer to physical layer when sniffing outgoing traffic. Ale nadal może to dawać fałszywe wyniki, np. jeśli pakiety są porzucane / gubione w tablicach routingu. Dlatego właśnie sniffery pracują na warstwie 2 OSI. Albo jeszcze lepszym rozwiązaniem jest obserwacja z zewnątrz, np. za pomocą serwera proxy / VPN lub na podłączonym komputerze lub routerze. Ale to nie przechwyci ruchu na bazie per UID/PID.

INNE OPCJE:

  • Użyj narzędzi diagnostycznych takich jak strace do śledzenia syscalls związanych z aktywnością sieciową procesu. force_bind i tracedump również działają na tej samej zasadzie. Do tego samego celu można użyć podsystemu audytu jądra Linux.
  • Użyj klasyfikatora sieciowego cgroup z iptables NETFILTER_XT_MATCH_CGROUP do sniffowania ruchu z określonego procesu(ów).
  • Użyj Network Namespaces do izolowania procesów i odczytywania wykorzystania danych na podstawie interfejsu. nstrace działa na tej samej zasadzie.
  • Jeśli intencją jest całkowite zablokowanie ruchu pochodzącego z pewnych procesów, można użyć SELinux i seccomp do ograniczenia zdolności procesów do tworzenia gniazd przez zdefiniowanie odpowiednio restricted policies i suppressing syscalls.

Większość z tych opcji nie jest bezpośrednio wykonalna dla Androida i wymaga zaawansowanych konfiguracji.

APARATY API ANDROIDA (OPCJE NON-ROOT):

Niektóre aplikacje takie jak NetGuard używają API VpnService Androida do blokowania ruchu w warstwie 3 (interfejs TUN). Aplikacja może „powiadomić, gdy aplikacja uzyskuje dostęp do Internetu”. Per app przechwytywania i śledzenia (1, 2) jest możliwe przy użyciu VPN API jako Android korzysta z UIDs i SOcket_MARKs (1, 2) do kontroli ruchu w sieci Routing Policy (RPDB), tuż przed opuszczeniem urządzenia.

Niektóre aplikacje, takie jak NetLive korzystać z NetworkStatsManager, ale opóźnia wykorzystanie w czasie rzeczywistym i „nie aktualizuje się wystarczająco szybko”, to „ma na celu zapewnienie danych historycznych”.

Some aplikacje, takie jak NetLive korzystać z NetworkStatsManager, ale to opóźnia wykorzystanie w czasie rzeczywistym i „nie aktualizuje się wystarczająco szybko”, to „ma na celu zapewnienie danych historycznych”.