Recently I wanted to poke around with the API packets to and from an app on my Android cell phone. Sounds simple right?
My first thought was to use Wireshark. After all, packets aren’t beamed directly to the router with a laser or something right? They’re broadcast everywhere at once. My computer should be able to pick them up too. It turns out many devices by default filter out these excess packets that are not addressed to them. This filter-out-excess mode is called managed mode:
In contrast, the “give me everything you hear” mode is called monitor mode:
Promiscuous mode is sort of between the two – it just requires you to be connected to the network on which you are eavesdropping.
The Linux tools I used to switch the networking mode were
ifconfig is a tool that gives you control over your network interfaces, which (if you know your 5-layer TCP/IP stack well) correspond to the data link layer, connecting the physical device and the network layer.
iwconfig is similar but specializes in wireless interfaces, giving control over things like the frequency, essid, and most importantly for us, the networking mode.
First, let’s look at what our card’s state is currently:
matic@scriabin:~$ ifconfig wlan0 wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.1.91 netmask 255.255.255.0 broadcast 192.168.1.255 inet6 fe80::626c:66ff:fe9e:6272 prefixlen 64 scopeid 0x20 ether **:**:**:**:**:** txqueuelen 1000 (Ethernet) RX packets 1426332 bytes 2003652624 (1.8 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 636524 bytes 73588446 (70.1 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 matic@scriabin:~$ iwconfig wlan0 wlan0 IEEE 802.11bgn ESSID:"********" Mode:Managed Frequency:2.437 GHz Access Point: **:**:**:**:**:** Bit Rate=28.9 Mb/s Tx-Power=16 dBm Retry short limit:7 RTS thr:off Fragment thr:off Power Management:off Link Quality=43/70 Signal level=-67 dBm Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:3 Invalid misc:918 Missed beacon:0
As we can see, the card is up and running, and iwconfig tells us that it is currently in managed mode. To change this, first we bring the interface down:
ifconfig wlan0 down
Now, we can make the changes we want to make using
iwconfig wlan0 mode monitor
We can finally bring the interface back up:
ifconfig wlan0 up
I also had some troubles with NetworkManager, so I used
service NetworkManager stop and
service NetworkManager start to start and stop that service as appropriate.
Seems simple, right? Well, wireshark still fed me nothing but probe and broadcast packets, which were more or less worthless to me, since I wanted those valuable TCP packets. So, after a long while of vigorous searching, I made the unfortunate discovery that my particular card doesn’t support monitor mode. It turns out my card actually filters out packets not destined for itself in the hardware, as in, at the physical layer – nothing I did at the data link layer would have any effect.
So, next I tried following this impressive blog post on how to use my computer as a hotspot – the hope being that I would end up connecting my phone to my computer and sniffing the connection from there. I followed the whole post and it worked swimmingly, but then I realized that though I had created a hotspot, I couldn’t connect to the internet with it… then it struck me that I had hijacked my wlan0 interface (the one using the network card resource) to be a hotspot, leaving no wireless card to be connected to the internet. My one wireless card obviously can’t run two interfaces at once
I could of course have gone to my basement and used an ethernet cable to actually get network connectivity. Or bought a second USB wireless card. I suppose while I was at it, I could have bought a card that supported monitor mode too… but I’m a cheap mf so I decided to go an alternate route and just install Android in a VM on my machine. Works like a charm, though I had to use the slightly dated 5.1 release instead of the shiny new 6.0. To make things even easier, it turns out VirtualBox supports pcap logging of all packets in or out of a VM, so there’s not even any need to use Wireshark.
In conclusion: I found three separate ways to capture network packets coming from an Android app:
- sniff the packets directly in monitor/promiscuous mode
- redirect all wifi packets in and out of the phone through your computer
- run the app in a VM instead.
All three of the ways work in theory, though there may always be unforseen limitations, as there were in my case.
Do you know a method not mentioned here? Feel free to comment below!