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 śledzeniasyscalls
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
iseccomp
do ograniczenia zdolności procesów do tworzenia gniazd przez zdefiniowanie odpowiednio restrictedpolicies
i suppressingsyscalls
.
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”.