Monday, November 14, 2011

Make the Android Emulator ready for SSL MITM

Then investigating native android apps communication, you'll sometimes need to perform a man-in-the-middle attack on the apps, even though they communicate through SSL. Tools like Charles Webproxy makes this pretty easy.

However Charles "dummy" certificate need to be added to your android instance's cacerts.bks in order to make android apps trust the proxy. If you dont do this, you'll end up with https connection's telling you the certificate cant be trusted. e.g.:
But its actually more problematic then this security warning. If your just looking at the browsers SSL trafic, you'll properly be fine with just clicking Continue, but meny native apps won't communicate with the internet if it can't trust the certificate.

Note: This should work with other proxy/sniffing tools as well, just find their certificate and add that instead.

The good news is this is easily done, you need to perform these steps:

  1. Make sure your android instance's sdcard partition is large enough to hold the entire /system (its ~100M) 200M will do.
  2. Pull out the cacerts.bks file
  3. Add the certificate to it
  4. Push it back
  5. Make it persistent (so it works when the instance reboots)

Note: You'll need to start the emulator with the `emulator` tool found in the android sdk, appending `-partition-size 128` to it, else you cant write to the /system partition, even though remounting it read-write.

So lets walk through the steps

SDcard partition size
This is done in AVD Manager. Open it through Eclipse or by typing
android avd
In your terminal. Dont forget to start the emulator from the commandline with the -partition-size parameter mentioned above. Something like
emulator -avd lille21 -partition-size 128
 Where lille21 is the name of the instance.

Pull out the cacerts.bks file
This is done by issuing adb's pull command
adb pull /system/etc/security/cacerts.bks cacerts.bks
Add your certificate to cacerts.bks
This is done using keytool with the following command

keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -importcert -trustcacerts -alias somealias -file charles-proxy-ssl-proxying-certificate.crt -noprompt
The above command should output something like:
Certificate was added to keystore

Note: On the Mac, you'll maybe get an error about keytool not being able to find bouncycastle, fix this by getting the lastest provider from here and put it in your $JAVA_HOME/jre/lib/ext/. (On the Mac with Lion, thats `/System/Library/Frameworks/JavaVM.framework/Home/lib/ext/`.

Another Note: The charles-proxy-ssl-proxying-certificate.crt is found inside the package, e.g ``.

Third Note: I dont know why the password is changeit, around the internets some have reported it to be "" e.g. nothing.

Push the cacerts.bks file back
First, remount the /system read-write.
adb remount
Second, change the original file's permissions.
adb shell chmod 777 /system/etc/security/cacerts.bks 
Third, push the new cacerts.bks.
adb push cacerts.bks /system/etc/security/
Now the file is in place, but you need to reboot the android instance in order to make it read your new file. (And if you reboot it now, you'll loose your new file, you need to make a new system.img file.

Make it persistent (with a new system.img file)
This is done with a tool called, `mkfs.yaffs2.arm`. Download it here.

 Push the mkfs.yaffs2.arm tool to your android instance.
adb push Downloads/mkfs.yaffs2.arm /data/data/temp/mkfs.yaffs2
Make it executable.
adb shell chmod 777 /data/data/temp/mkfs.yaffs2 

Make a new system.img on the sdcard partition

Jump into the shell with:
adb shell
Inside the shell type:
/data/data/temp/mkfs.yaffs2 /system /sdcard/system.img 
Note: Be sure about the sdcard mount location, on android 2.1 its /sdcard while on android 2.3 its /mnt/sdcard. Check it with the mount command inside the shell

It should output something like this:
mkfs.yaffs2: Android YAFFS2 Tool,Build by PowerGUI
Build Ok.

Quit the shell and download the newly generated system.img.
 adb pull /sdcard/system.img system.img
Note: Again, watch the sdcard's location!

Kill the emulator and boot the new system.img.

Just kill it or exit it in whatever way you see fit, when its closed, you can put your new system.img inside the instances folder.

On the mac its by default ~/.android/avd/<avdname>.avd/ . This is properly also true for linux boxes.
cp system.img .android/avd/lille21.avd/
As far as i know you wont be overwriting anything, the emulator normaly loads a system wide "/system" partition found in your sdk directory, but then it finds the instance has its one, it will load that instead.

Note: My instance is called lille21, you've properly called yours something else.

Now your all ready and set
Boot your instance with
emulator -avd lille21 -http-proxy http://yourinterfaceip:8888
And your ready to monitor all kinds of trafic from webpages and even native android applications!

If your using Charles webproxy remember to enable SSL Proxying.

Ta da! No more certificate trust issues:

Final Note
Ive tried this on android 2.1 and 2.3, not sure if it works on honeycomb (3.0+).
Let me know if you find anything interesting when looking at your favorite app communication :)


  1. Simply getting my head round MITM and all that runs with it,thanks for the article,was a bit over my head at a few points however general the depth was pro addressed a lot of knowledge gaps,thanks… I am beyond any doubt sick be reading it in weeks to come.
    @Evelyn Cox.

  2. Hello! Android Hacking and Penetration Testing course is an exceptionally handy and hands on feature course. The course will concentrate on the instruments and systems for testing the Security of Android Mobile applications. Amid the course, You will learn different subjects, for example, Android structural planning, Android security model, Android Application Pentesting and Exploitation, Reversing Android applications, static and element investigation of android malware and so forth.All the best!!
    Visit apps page

  3. Mobile applications,then again,can't generally be depended on to display such a warning or even perceive when something is amiss.When running an app that is powerless against SSL MITM,you will see complete requests and reactions logged by sslsniff.You Should discover an app that uncovered sensitive data.
    -Kim Martin.

  4. Android Terminal Emulator is incorporated with backing for x86 gadgets, and ought to in this manner have the capacity to keep running on x86 gadgets when x86 gadgets that backing the NDK get to be accessible.