2

There are lots of discussion on how to see which app is requesting network connection. I have tried the following apps:

tcapturepacket
wifi monitor
connection tracker

However, none of them was useful. For example, for a short period of time, I uploaded a 30KB pcap file which can be viewed here. Still I haven't find out which app is requesting connection and to where it is trying to connect.

I also tried to look at adb logcat, but didn't find useful information. Maybe something has been missed here. Any guess?

2

If you have rooted phone, go for nethogs (for live monitoring) or iptables (to get statistics) commandline tools. Using VPN based apps is the only possible non-root solution. Or refer to this answer for a logcat/dumpsys based solution.


First of all, tracking a UID or PID of a network stream isn't straight forward because these aren't network related but OS related parameters. Such features has been proposed but not so simple to implement.

Android assigns a unique UID to every installed app just like every human user on Linux has a UID. So we can capture packets sent by a specific UID over the network interfaces to track the usage.

TCPDUMP:

Now how we can capture network traffic? Most of the network sniffers use libpcap family of system-independent libraries for this purpose. It supports BSD Packet Filter (BPF) for in-kernel packet filtering. Some popular utilities that use libpcap include tcpdump, nmap, tshark/wireshark, dumpcap, nethogs etc. Android app Network Utilities and others also make use of tcpdump.

However UID info is not propagated through the AF_PACKET/PF_PACKET channel that pcap uses at OSI Layer 2. So what we can do here is to make use of network sockets (combination of IP and port) being created and used by an app. netstat -tup or ss -tup will show all network sockets with active/established connections. Both tools are available on Android, ss is the newer one. Local Port vs UID information can also be directly read from /proc/net/{tcp,udp}. Android app Netstat Plus works on same principle. This will provide Local Address (socket) being used by a process.

Once we know what sockets are being used by a process, tcpdump -i wlan0 src <IP> and port <PORT> will dump the whole traffic originated from that process.
Similarly a remote socket (if not connected to by multiple apps) can also be used for filtering results.

Limitations:

However there are some issues with this approach:

  • Android apps usually launch more than one process at a time in parallel i.e. multiple PIDs working under same UID. So we have to capture traffic from all processes.
  • Apps keep on creating and deleting sockets. Keeping track of continuously changing sockets is almost impossible particularly when there are a large number of apps accessing network simultaneously.

nethogs copes with both above described limitations, not always very successful.

  • There is - though rare - possibility that local sockets are being shared by multiple processes on UNIX-like OS's. Remote shared sockets such as UDP/53 which is used for DNS resolution cannot be tracked for a single process. This further weakens the approach.

IPTABLES:

These shortcomings of a Layer 2 tool can be mitigated using iptables LOG or NFLOG. Layer 2 is just above the Physical Layer i.e. it's the last thing packets encounter before leaving the device. That's why, being at Data Link Layerand working at lower level of net stack, BPF is a kind of stateless packet filtering mechanism as compared to netfilter/iptables which works at OSI Layer 3 (nearer to userspace programs). Iptables can also get information from TCP/IP stack (Layer 4). It filters packets based on their creator UIDs using module owner that interacts with sockets to find packet ownership. However this won't work for incoming or forwarded traffic because IP packets carry no ownership information. BPF is going to replace iptables in Linux kernel. It's also being injected to Android. But for the time being using iptables takes precedence over BPF for our use case.

Iptables can do kernel logging of outgoing traffic from an app based on its UID. Later kernel log can simply be read using dmesg or logcat.
UID of an app can be obtained using some app or read from /data/system/packages.list.

# iptables -A OUTPUT -m owner --uid-owner <UID> -j LOG --log-level 7 --log-prefix 'SNIFFER: ' --log-uid
# dmesg -w | grep SNIFFER

Output can be saved to a file and formatted using tools like grep, awk, printf etc. Network Log - though very outdated - works in similar way. AFWall+ is a firewall based on iptables that can be used to find out what IP addresses an app tries to connect by blocking outgoing traffic of that particular app.

The only limitation with this approach is when there are multiple processes running with same UID and the requirement is to sniff traffic from one process. iptables can't capture packets based on PIDs. They decided not to use iptables with processes because the process is started before it is blocked/sniffed, and program could easily spawn a child process with new PID which would not be blocked/sniffed. So there was always room for traffic being leaked.

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 -A 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. But it can still give false positives e.g. if packets are dropped/lost in routing tables.

That's why sniffers work at OSI layer 2. Or even better is to watch from outside e.g. using a proxy/VPN server or on a tethered PC or at router. But this won't capture traffic on per UID/PID basis.

OTHER OPTIONS:

  • Use diagnostic tools like strace to track syscalls related to network activity of a process. force_bind and tracedump also work on same principle.

    Linux kernel's audit subsystem can be used for the same.

  • Use Network classifier cgroup with iptables NETFILTER_XT_MATCH_CGROUP to sniff traffic from certain process(es).
  • Use Network Namespaces to isolate process (interfaces, sockets etc.) nstrace works on same principle. iptables SNAT is required for traffic to flow.
  • If the intention is entirely to block traffic originating from certain processes, SELinux and seccomp can be used to restrict the processes' ability to create sockets by defining restricted policies and suppressing syscalls respectively.

Most of these are not straightforwardly viable options for Android and require advanced configurations.


Android's VpnService API:

Some apps like Packet Capture and tPacketCapture use VpnService API of Android to capture traffic at Layer 3 (TUN interface), though Google has considered this a misuse of VPN and removed them from PlayStore. Per app tracking (1, 2) is possible using VPN API as it makes use of UIDs and SOcket_MARKs (1, 2) to control traffic in Routing Table / RPDB, just before leaving the device.

Additionally using man-in-the-middle technique breaks security certificates of https traffic causing traffic to be interrupted.

RELATED:

0

If you only want to track which app performs connections to which server I recommend the app
Net Monitor
to you. It acts as a local VPN and is therefore able to detect all network traffic. Furthermore it shows which app has performed the network request (including remote host, ports, and even if the connection is plain or SSL/TLS).

Therefore if you use this app in combination with the capture tools you already mentioned in your question you should able to trace back each and every network connection.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.