Hogyan lehet megtekinteni egy adott alkalmazás által igényelt hálózati forgalmat?
Ha rootolt telefonod van, válaszd a nethogs
(élő megfigyeléshez) vagy a iptables
(statisztikákhoz) parancssori eszközöket. A VPN vagy az Android statisztikákon alapuló alkalmazások használata az egyetlen lehetséges nem gyökeres megoldás. Vagy tekintse meg ezt a választ egy logcat
/dumpsys
alapú megoldáshoz.
Először is, egy hálózati folyam UID-jének vagy PID-jének nyomon követése nem egyszerű, mivel ezek nem hálózathoz, hanem operációs rendszerhez kapcsolódó paraméterek. Javaslatok és elhagyott projektek léteznek.
Android minden telepített alkalmazáshoz egyedi UID-t rendel, ahogy Linuxon minden emberi felhasználónak van UID-je. Így egy adott UID által a hálózati interfészeken keresztül küldött csomagokat rögzíthetünk, hogy nyomon követhessük a használatot.
TCPDUMP:
Most hogyan tudjuk rögzíteni a hálózati forgalmat? A legtöbb hálózati szimatoló erre a célra a libpcap rendszerfüggetlen könyvtárcsaládot használja. Ez támogatja a BSD Packet Filtert (BPF) a rendszermagon belüli csomagszűréshez. Néhány népszerű segédprogram, amely a libpcap
-t használja: tcpdump
, nmap
, tshark/wireshark
, dumpcap
, nethogs
stb. Az Android alkalmazás hálózati segédprogramjai és mások is használják a tcpdump
-t.
Az UID-információ azonban nem terjed a AF_PACKET
/PF_PACKET
csatornán keresztül, amelyet a pcap
az OSI 2. rétegben használ. Tehát itt azt tehetjük, hogy kihasználjuk az alkalmazás által létrehozott és használt hálózati aljzatokat (IP és port kombinációja). A netstat -tup
vagy ss -tup
megmutatja az összes aktív/létrehozott kapcsolattal rendelkező hálózati aljzatot. Mindkét eszköz elérhető Androidon (vagy beszerezhetsz egy statikus bináris fájlt), a ss
az újabb. A /proc/net/{tcp,udp}
-ból közvetlenül is kiolvasható a socket vs. UID információ. Az Android alkalmazás Netstat Plus ugyanezen az elven működik. Ez megadja a folyamat által használt helyi címet (socket).
Ha már tudjuk, hogy egy alkalmazás milyen socketeket használ (UID), a tcpdump -i wlan0 src <IP> and port <PORT>
ki fogja dobni az adott folyamatból származó teljes forgalmat.
Hasonlóképpen egy távoli socket (ha nem több alkalmazás kapcsolódik hozzá) is használható az eredmények szűrésére.
KORLÁTOZÁSOK:
Valamint van néhány probléma ezzel a megközelítéssel:
- Android alkalmazások általában egyszerre több folyamatot indítanak párhuzamosan, azaz több PID dolgozik ugyanazon UID alatt. Tehát az összes folyamat forgalmát rögzítenünk kell.
- Az alkalmazások folyamatosan létrehozzák és törlik az aljzatokat. A folyamatosan változó aljzatok nyomon követése szinte lehetetlen, különösen akkor, ha egyszerre nagyszámú alkalmazás fér hozzá a hálózathoz.
- Létezik – bár ritka – lehetőség arra, hogy a UNIX-szerű operációs rendszerekben a helyi aljzatokat több folyamat osztja meg egymással. A távoli megosztott aljzatok, mint például a DNS-feloldáshoz használt UDP/53, nem követhetők egyetlen folyamat esetében. Ez tovább gyengíti a megközelítést.
ANetHogs átjárja a procfs
-t és megbirkózik a fenti korlátozásokkal (bár nem mindig sikeresen):
IPTABLES:
A Layer 2 eszköz fent leírt hiányosságait az iptables LOG
vagy NFLOG
használatával lehet enyhíteni. A 2. réteg közvetlenül a fizikai réteg felett van, azaz ez az utolsó dolog, amivel a csomagok találkoznak, mielőtt elhagyják az eszközt. Ezért, mivel az adatkapcsolati rétegben van és a hálózati verem alacsonyabb szintjén működik, a BPF egyfajta állapot nélküli csomagszűrő mechanizmus, szemben a netfilter
/ iptables
-val, amely az OSI 3. rétegben működik (közelebb a felhasználói programokhoz). A iptables
tehát a TCP/IP veremből (4. réteg) is kaphat információt. A csomagokat a létrehozójuk UID-ja alapján szűri a owner
modul segítségével, amely kölcsönhatásba lép a socketekkel, hogy megtalálja a csomagok tulajdonjogát.
iptables
a kernelnaplóba ír, amely a dmesg
vagy logcat
segítségével olvasható. Egy alkalmazás UID-jét meg lehet szerezni valamilyen alkalmazással, vagy ki lehet olvasni a /data/system/packages.list
vagy pm list packages -U
segítségével.
# iptables -I OUTPUT -m owner --uid-owner <UID> -j LOG --log-level 7 --log-prefix 'SNIFFER: ' --log-uid# dmesg -w | grep SNIFFER
A kimenet elmenthető egy fájlba és formázható olyan eszközökkel, mint grep
, awk
, printf
stb. A Network Log – bár nagyon elavult – hasonló módon működik. Az AFWall+ egy iptables
alapú tűzfal, amely képes naplózni / értesíteni egy alkalmazás hálózati tevékenységét, ha az alkalmazás blokkolva van.
Az egyetlen hátránya ennek a megközelítésnek, hogy nem használható egy folyamat forgalmának kiszimatolására, ha több folyamat fut ugyanazzal az UID-vel. iptables
Nem tud PID-ek alapján csomagokat rögzíteni. Úgy döntöttek, hogy nem használják a iptables
-t a folyamatokkal, mert a folyamat elindul, mielőtt blokkolnák/szimatolnák, és a program könnyen létrehozhatna egy gyermekfolyamatot új PID-vel, amelyet nem blokkolnának/szimatolnának. A PID-ket is olyan gyorsan hozzák létre és semmisítik meg, mint a socketeket. Így mindig van lehetőség a forgalom kiszivárgására.
QTAGUID:
owner
A modul nem működik a bejövő vagy továbbított forgalomra, mivel az IP csomagok nem hordoznak tulajdonosi információt. Az alkalmazásonkénti bejövő/kimenő hálózati használat méréséhez az Android javította a kernelt, hogy tartalmazza a qtaguid
modult. A statisztikákat a /proc/net/xt_qtaguid/stats
modulból tudjuk kiolvasni. Némi shell scriptinggel élő adatfelhasználást kapunk az újraindítás óta:
Az Android 9+ rendszeren azonban a qtaguid
helyettesítve lesz a kiterjesztett BPF-fel (amely a tervek szerint a netfilter
keretrendszert is felváltja a Linux kernelben). Kapcsolódó cikkek: Melyik folyamat felelős az adatfelhasználás rögzítéséért?
IPTABLES + TCPDUMP:
Egy másik lehetőség, hogy egy alkalmazás kimenő forgalmát egy NFLOG
csoportba tesszük, és később a tcpdump ebből a csoportból rögzíti a csomagokat:
# iptables -I OUTPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30# tcpdump -i nflog:30
Ez biztosítja, hogy a kimenő forgalom szimatolásakor közelebb kerüljünk a fizikai réteghez. De ez még mindig adhat hamis pozitív eredményeket, pl. ha a csomagok elvesztek / elvesznek az útválasztási táblázatokban. Ezért működnek a szimatolók az OSI 2. rétegén. Vagy még jobb, ha kívülről figyeljük pl. egy proxy / VPN szerver segítségével, vagy egy tethered PC-n vagy router-en. De ez nem fogja rögzíteni a forgalmat UID/PID alapon.
MÁS OPCIÓK:
- Az olyan diagnosztikai eszközök, mint a
strace
, a folyamat hálózati tevékenységével kapcsolatossyscalls
nyomon követésére szolgálnak. force_bind és tracedump is ugyanazon az elven működik. A Linux kernel audit alrendszere ugyanerre használható. - Hálózati osztályozó cgroup
iptables
NETFILTER_XT_MATCH_CGROUP
használatával bizonyos folyamat(ok) forgalmának kiszimatolására. - Az
Network Namespaces
segítségével elszigetelhetjük a folyamatokat és interfészenként leolvashatjuk az adatfelhasználást. nstrace ugyanezen az elven működik. - Ha teljes egészében bizonyos folyamatokból származó forgalom blokkolása a cél, akkor a
SELinux
ésseccomp
segítségével korlátozható a folyamatok lehetősége a socketek létrehozására a restrictedpolicies
, illetve a suppressingsyscalls
meghatározásával.
Ezek többsége nem egyenesen életképes lehetőség Android esetén, és fejlett konfigurációkat igényel.
ANDROID API-i (NON-ROOT OPCIÓK):
Egyes alkalmazások, mint például a NetGuard, az Android VpnService API-ját használják a forgalom blokkolására a 3. rétegben (TUN interfész). Az alkalmazás képes “értesíteni, ha egy alkalmazás hozzáfér az internethez”. Az alkalmazásonkénti rögzítés és nyomon követés (1, 2) lehetséges a VPN API használatával, mivel az Android a UIDs
és SOcket_MARKs
(1, 2) funkciót használja a forgalom ellenőrzésére a hálózati útválasztási szabályzatban (RPDB), közvetlenül az eszköz elhagyása előtt.
Egyes alkalmazások, mint a NetLive, a NetworkStatsManager-t használják, de az elmarad a valós idejű használathoz képest, és “nem frissül elég gyorsan”, “historikus adatok szolgáltatására szolgál”.