Monday, January 16, 2012

Capturing raw 802.11 on android

Short answer: It's not really possible, definitely not on an unrooted device, if you're using the built-in nic.  The drivers and firmware aren't monitor mode friendly, and you'd need to root the device (and give the app root) to be able to even attempt.

Giving android apps root terrifies me - it places 100% trust in the developer to not be malicious, and the market to have not presented you with a cloned project that IS malicious, and in the developers systems to make sure no-one can ever push an update using their keys that becomes malicious... it's bad news all around.

Fortunately, in Honeycomb and in ICS, they've added USB host mode.  Unfortunately, in honeycomb something seems to not be quite right with it (but honeycomb is a dead end anyhow, most devices with it should be seeing an ICS update very soon), and there's only one official ICS phone right now.

The android USB API is very similar to libusb.  It's possible to compile libusb on android in the NDK.  Unfortunately, claiming a device via the android USB api does NOT make the endpoints directly writeable to the app uid.  There is a method to shunt the USB file descriptor to a native segment, which may prove useful in the future.

Even without using native code, it's possible to bit-bang a USB device directly using the Android java API; a simple example is the Wi-Spy, which has a pleasantly simple hardware interface...

There's nothing innately special about a wifi device, in USB terms, other than general complexity.  Having crazy ideas sometimes, I took chunks of the Serialmonkey rtl8187 driver, the macusbwifi port of it to mac userspace, and the linux kernel driver for rtl8187, and mangled them into a 2500 line pure-java implementation of the driver, with IO shunted through the android USB API:

I/ActivityManager(  206): Start proc for activity pid=1965 uid=10072 gids={}
D/rtl8187card( 1965): device interface count: 1
D/rtl8187card( 1965): open SUCCESS
D/rtl8187card( 1965): hwaddr 0:c0:ca:21:9d:ef RTL8187BvB V1+RTL8225
E/rtl8187card( 1965): 8187z2 rf calibration failed: e6
D/rtl8187card( 1965): rtl8225z2 set tx power
D/rtl8187card( 1965): Initialized card hardware
D/rtl8187card( 1965): Started rtl8187
D/rtl8187card( 1965): Successfully calibrated & started hw
D/rtl8187card( 1965): Set channel 11
D/rtl8187card( 1965): Initializing URB request for max 512

I'm honestly not sure at the moment why the rf calibration code is getting a failure bit set, that will be a problem to look at in the future.

The result?

D/rtl8187card( 1965): Packetdata 2...
  Data 80 00 00 00 ff ff ff ff ff ff 00 24 6c a7 87 70     ...........$l..p
  Data 00 24 6c a7 87 70 b0 11 81 d1 fb 01 00 00 00 00     .$l..p..........
  Data 64 00 31 04 00 10 65 74 68 65 72 73 70 68 65 72     d.1...etherspher
  Data 65 2d 77 70 61 32 01 08 82 84 0b 16 0c 12 18 24     e-wpa2.........$
  Data 03 01 0b 05 04 00 01 00 00 2a 01 00 32 04 30 48     .........*..2.0H
  Data 60 6c 30 14 01 00 00 0f ac 04 01 00 00 0f ac 04     `l0.............
  Data 01 00 00 0f ac 01 00 00 dd 18 00 50 f2 02 01 01     ...........P....

The post mangles the formatting a little, but it's clearly a beacon packet (0x80), the SSID is visible, we're in good shape!

The code currently needs a lot of care and feeding before a release, though hopefully by Shmoocon I can show some basic results.

In theory there shouldn't be much trouble porting the Kismet core over to the phone and shunting the packets through the JNI interface to that, and letting the existing code to the decoding and logging, but I haven't started on that yet.

The battery drain on the phone is pretty significant - I'm kind of amazed it can handle it at all, considering some netbooks can't drive these Alfa nics.  A hard-drive power Y cable offsets it to some extent, someone suggested making a custom cable which severs VCC from the device and uses the aux connector exclusively, this seems like a pretty good idea to me.


  1. Great work! This will be pretty fun to play with once I get ICS

  2. Yeah I'm excited to get it a bit more polished & get the kismet engine running underneath it. Right now it's pretty fragile - while it works with 2 cards I've tested, it throws some spurious errors, and currently crashes when you unplug the device, and other such nastiness.

  3. The most Wireless chipsets that are build into the phones use opensource driver that are into the kernel.
    For example my phone uses wl12xx_mac80211. So monitor mode + injection should work.
    Where is the problem? If its not active in the mac80211, then it can be activated and the kernel could be recompiled.

  4. Great work man, any plan to make the source available?

  5. Lubomir: The goal is to not require rooting the phone or custom kernels. For people who want to do that, fine - and actually, kismet runs on android built as a binary w/ the ndk with no problems at all, so you can just port over a binary and fire it off in a terminal.

    I think it's generally bad for the android ecosystem to tell users to run arbitrary root code - the markets aren't secure enough against spoofed similar-named apps, and third party is even worse. I'd prefer to not contribute to that if possible, plus having a support model where it starts with "root your phone..." might drive me insane.

    Wizche: Absolutely, doubly so since it uses gpl driver components, it's just not really to the level that anyone would benefit from. A couple of weeks probably - when I post a test APK I'll make the source available, either as a tgz or I'll throw it in a branch on the kismet svn server.

  6. Can you comment on how you got WiSpy software running on Android? I have a tablet that has USB Host capability (Transformer) and would LOVE to be able to run this on it... Thanks.

  7. tbackus: I ported the Spectools code to android. It's super clunky and not something I'm going to release, but Metageek may have something in the works, stay tuned.

  8. So when are we going to get Kismet for Android ICS? I have gnex and alfa awus036h and keep trying to get them together.

  9. Can you comment on whether getting monitor mode/packet injection working on an Android phone's built-in Wi-Fi chip would require a custom driver, or would it require custom firmware? I realize that for your own work you're interested in *not* requiring rooting a phone, but I am thinking about the use case of a dedicated rooted Android device for pen-testing, rather than something someone wants to double as a day-to-day phone.

  10. Can you provide any information on how to set up the NDK for native compiling for use on a rooted phone?