August 31, 2011

For Rooted Android Device Users: Open Heart Surgery on Your Android CA Store

For Android power users, a rooted Android device can be a gateway to gain full access to the operating system. One thing you can do with rooted Android devices is maintain your Certificate Authorities store, which designates the parties who verify secure sites for your device. There is increasing scrutiny on Certificate Authorities as a weakness of SSL/TLS, and in the last year there have been two specific cases where fraudulent certificates have been traced to compromised CAs. Websites using compromised certificates can take the identity of official sites, even if you are connecting over HTTPS and your web browser will not warn you about the site’s fraudulent certificate. Most recently, an issue was discovered in Iran where people have claimed that the government is performing a Man in the Middle attack on gmail using a fraudulent certificate issued from a Certificate Authority called DigiNotar. DigiNotar has since issued a report on the security incident which can be found on Vasco.

What does all this mean for an Android users? Well, unless you’re on a rooted Android device, you can’t do anything at this point. If you are rooted and not afraid to play with some command line tools, you can remove the suspect Certificate Authority certificates and disallow them from being used on your device. As a warning, this is definitely not for the faint of heart or novice Android user and can be a bit time consuming. This process will require some command line knowledge using the java keytool, ensuring that Bouncy Castle is in your classpath and using adb.

First we need to pull our CA cert bundle which is located in /system/etc/security – I’ll be using the one pulled from a Asus Transformer for this example;

tstrazzere@m0ya:~$ adb pull /system/etc/security/cacerts.bks cacerts.bks
1255 KB/s (142331 bytes in 0.110s)
tstrazzere@m0ya:~$shasum cacerts.bks
47f4789b9d03f7f8b0ff8165fc079125be314eee  cacerts.bks

Before we use the keytool, we need to make sure we have a copy of BouncyCastle in our $JAVA_HOME/jre/lib/ext/ – I used Download http://bouncycastle.org/download/bcprov-jdk16-141.jar and put it in $JAVA_HOME/lib/ext. After this is all set we need to check out whether the cacert.bks has the CA’s we would like to remove. I personally was looking to remove both DigiNotar and Comodo and used the following commands to look for them;

tstrazzere@m0ya:~$ keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -v -list | grep -A 7 -B 4 -i comodo
Alias name: 48
Creation date: Feb 8, 2011
Entry type: trustedCertEntry
Owner: C=GB,ST=Greater Manchester,L=Salford,O=COMODO CA Limited,CN=COMODO Certification Authority
Issuer: C=GB,ST=Greater Manchester,L=Salford,O=COMODO CA Limited,CN=COMODO Certification Authority
Serial number: 4e812d8a8265e00b02ee3e350246e53d
Valid from: Fri Dec 01 00:00:00 UTC 2006 until: Mon Dec 31 23:59:59 UTC 2029
Certificate fingerprints:
MD5:  5C:48:DC:F7:42:72:EC:56:94:6D:1C:CC:71:35:80:75
SHA1: 66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B
Signature algorithm name: SHA1WithRSAEncryption
Version: 3
--
Alias name: 78
Creation date: Feb 8, 2011
Entry type: trustedCertEntry
Owner: C=GB,ST=Greater Manchester,L=Salford,O=COMODO CA Limited,CN=COMODO ECC Certification Authority
Issuer: C=GB,ST=Greater Manchester,L=Salford,O=COMODO CA Limited,CN=COMODO ECC Certification Authority
Serial number: 1f47afaa62007050544c019e9b63992a
Valid from: Thu Mar 06 00:00:00 UTC 2008 until: Mon Jan 18 23:59:59 UTC 2038
Certificate fingerprints:
MD5:  7C:62:FF:74:9D:31:53:5E:68:4A:D5:78:AA:1E:BF:23
SHA1: 9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11
Signature algorithm name: SHA384WITHECDSA
Version: 3


Alias name: 62
Creation date: Feb 8, 2011
Entry type: trustedCertEntry

Owner: C=GB,ST=Greater Manchester,L=Salford,O=Comodo CA Limited,CN=AAA Certificate Services
Issuer: C=GB,ST=Greater Manchester,L=Salford,O=Comodo CA Limited,CN=AAA Certificate Services
Serial number: 1
Valid from: Thu Jan 01 00:00:00 UTC 2004 until: Sun Dec 31 23:59:59 UTC 2028
Certificate fingerprints:
MD5:  49:79:04:B0:EB:87:19:AC:47:B0:BC:11:51:9B:74:D0
SHA1: D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49
Signature algorithm name: SHA1WithRSAEncryption
Version: 3

Make sure the above certificates are in fact the ones you want to remove – then remove them by using the -delete -alias ALIAS_NAME command. After performing a delete on these, make sure you try to grep them again to ensure they are removed;

tstrazzere@m0ya:~$ keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -v -delete -alias 48
[Storing cacerts.bks]
tstrazzere@m0ya:~$ keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -v -delete -alias 78
[Storing cacerts.bks]
tstrazzere@m0ya:~$ keytool -keystore cacerts.bks -storetype BKS -provider             org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -v -delete -alias 62
[Storing cacerts.bks]
tstrazzere@m0ya:~$ keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -v -list | grep -A 7 -B 4 -i comodo
tstrazzere@m0ya:~$

Next I wanted to remove the DigiNotar CA cert, so performing the same steps like above for similar results;

tstrazzere@m0ya:~$ keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -v -list | grep -A 7 -B 4 -i diginotar
Alias name: 99
Creation date: Feb 8, 2011
Entry type: trustedCertEntry
Owner: C=NL,O=DigiNotar,CN=DigiNotar Root CA,E=info@diginotar.nl
Issuer: C=NL,O=DigiNotar,CN=DigiNotar Root CA,E=info@diginotar.nl
Serial number: c76da9c910c4e2c9efe15d058933c4c
Valid from: Wed May 16 17:19:36 UTC 2007 until: Mon Mar 31 18:19:21 UTC 2025
Certificate fingerprints:
MD5:  7A:79:54:4D:07:92:3B:5B:FF:41:F0:0E:C7:39:A2:98
SHA1: C0:60:ED:44:CB:D8:81:BD:0E:F8:6C:0B:A2:87:DD:CF:81:67:47:8C
Signature algorithm name: SHA1WithRSAEncryption
Version: 3
tstrazzere@m0ya:~$ keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -v -delete -alias 99
[Storing cacerts.bks]
tstrazzere@m0ya:~$ keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -v -list | grep -A 7 -B 4 -i diginotar
tstrazzere@m0ya:~$
tstrazzere@m0ya:~$ shasum cacerts.bks
0e2a3db5d4fc82688832d2b4433a7acdb4546772  cacerts.bks

Now the last thing to do is to push this new bundle to the Android device. To do this we must have root on the phone, which will allow us to remount the /system partition. If adb is privileged as root, you can do this by simply issuing a remount command;

tstrazzere@m0ya:~$ adb remount
remount succeeded

Otherwise you will need to manually remount inside adb after running ‘su’ with something like the following;

tstrazzere@m0ya:~$ adb shell
$ su
# mount -o remount,rw /dev/block/mmcblk0p25 /system

Once you’ve remounted the /system partition, you can now push the new cacert.bks to the device;

tstrazzere@m0ya:~$ adb push cacerts.bks /system/etc/security/
1255 KB/s (142331 bytes in 0.110s)

Now simply reboot your device and be happy that you no longer have to trust unwanted CA’s!

10 comments
  1. Matt says:

    Question: What about the store password? How do I find it?
    I’m using ArchLinux with Java 7, the jar file copied to $JAVA_HOME/jre/lib/ext and using your command line on a cacert.bks I extracted from my HTC Sense Gingerbread ROM.

    I receive an exception “KeyStore integrity check failed” if using “changeme”, a NullPointerException if I omit it.

    Thank you.
    Kind regards,
    Matt

  2. Dana says:

    I suppose it’d be a bit more hamfisted, but couldn’t you also just go into Settings>Location & Security and clear all the stored credentials?

    Or would the DigiNotar cert simply repropogate as you browse around on the web?

  3. igor says:

    has to be “adb push cacerts.bks /system/etc/security/” – with “s”

    thanks for the howto! greatly appreciated

  4. Matt says:

    Hi there,

    all nice and fine.
    Where do I find the keystore password? :P

    Omitting the storepass variable results in a NullPointerException, using changeit of course results in an Exception that the keystore integrity check failed.

    I’m using a HTC Desire Z with Virtuous 2.0.0, based off the original HTC 2.3.3 ROM, and the linked BouncyCastle class with java 7 on ArchLinux.

    Kind regards,
    Matt

  5. The Guardian Project has an effort going to both create a curated version of the cacerts.bks file that users can use, as well as to build a simple Android app that can do everything described in your post above from the device itself.

    See our github project for more info: https://github.com/guardianproject/cacert/tree/master/app

    We would love help, support, ideas and feedback.

  6. Amy says:

    @Igor, you are correct, it is “adb push cacerts.bks /system/etc/security/” – with “s.” Thank you for pointing this out to us-you’ll see this revised in the blog post. Thank you!

  7. Amy says:

    @Matt, thanks for reaching out. The default password is actually “changeit” not “changeme.” If you try “changeit,” the integrity check shouldn’t fail. If you have any other questions, please feel free to reach us: feedback@mylookout[dot]com. Thanks!

  8. Amy says:

    @Dana, thanks for your question. What you are referring to are stored credentials, not your certificate store. Stored credentials are similar to allowing a site to remember your password, but it doesn’t actually have anything to do with the authentication of the certificates. Thanks!

  9. so much great info on here, : D. Consider a visit to my website . ty!

Leave a comment