2012-02-25

Twitter Android et vos Contacts bis !

Le 21 février 2012, les devs de Twitter annonçaient sur le blog qu'ils allaient vers plus de transparence en ce qui concerne la recherche d'amis :

“Find friends”: We’ve added a confirmation alert when you select “Find friends”. This notification more clearly and explicitly messages the fact that when you upload your contacts’ email addresses and phone numbers, you can quickly find which of your friends are on Twitter (that is, if they’ve chosen to be discoverable by email or phone number).

Pas d'entourloupe, ce qui est dit est fait et ce qui est fait est dit. C'est en cherchant à le vérifier que j'ai pu constater que le client Android avait significativement amélioré sa sécurité.

Certificats hardcodés ?

Mon certificat maison pour mes interceptions SSL ne semblait plus fonctionner. A priori un problème dans le handshake SSL sans en savoir plus. L'application Twitter ne fait plus confiance aux certificats d'Android que l'utilisateur peut modifier à sa guise.

Les notes légales du client Android précisent l'utilisation de Bouncy Castle Crypto. Bingo. On est confirmé dans notre intuition de l'utilisation d'une liste restreintes de certificats codée en dur dans l'application ET on va pouvoir accéder au trousseau !

Chasse au keychain

Comme j'ai un terminal rooté, il m'est très simple de récupérer /data/app/com.twitter.android-1.apk et de le manipuler depuis mon ordinateur.
$ unzip com.twitter.android-1.apk
$ find . -iname '*cert*'
./res/raw/cacerts
Oh /res/raw/  ... et Bouncy Castle ... ça me rappelle un article de Antoine HAUCK sur la crypto android dans mes bookmark. Brillant article.

Lecture du keychain:

Il vous faut le jar bcprov pour la manipulation
$ keytool -list -keystore res/raw/cacerts \
 -provider org.bouncycastle.jce.provider.BouncyCastleProvider \
 -providerpath ./bcprov-jdk15-146.jar -storetype BKS
Tapez le mot de passe du Keystore : _
Bon c'est protégé ... A vous de vous débrouiller avec les 2 conseils suivants:
  • Le mot de passe est dans un dictionnaire
  • Utilisez un des exemples du site BouncyCastle plutôt que des boucles bash...

Une fois le mot de passe trouvé :
$ keytool -list -keystore res/raw/cacerts \
 -provider org.bouncycastle.jce.provider.BouncyCastleProvider \
 -providerpath ./bcprov-jdk15-146.jar -storetype BKS \
 -storepass *****

Keystore type: BKS
Keystore provider: BC

Your keystore contains 128 entries

127, Mar 3, 2011, trustedCertEntry,
Certificate fingerprint (MD5): 4C:56:41:E5:0D:BB:2B:E8:CA:A3:ED:18:08:AD:43:39
126, Mar 3, 2011, trustedCertEntry,
Certificate fingerprint (MD5): AB:57:A6:5B:7D:42:82:19:B5:D8:58:26:28:5E:FD:FF
(...)
61, Mar 3, 2011, trustedCertEntry,
Certificate fingerprint (MD5): 10:FC:63:5D:F6:26:3E:0D:F3:25:BE:5F:79:CD:67:67
60, Mar 3, 2011, trustedCertEntry,
Certificate fingerprint (MD5): 49:79:04:B0:EB:87:19:AC:47:B0:BC:11:51:9B:74:D0

Ajout de mon certificat

Pour ma part j'utilise un certificat PEM (base64) sans mot de passe :
$ keytool -importcert -v -trustcacerts -file "cekage.cer"\
  -keystore res/raw/cacerts \
  -provider org.bouncycastle.jce.provider.BouncyCastleProvider \
  -providerpath ./bcprov-jdk15-146.jar -storetype BKS \
  -storepass *****
(...)
Serial number: 1
Valid from: Wed Feb 22 10:00:00 CET 2012 until: Fri Sep 21 08:12:00 CEST 2012
Certificate fingerprints:
         MD5:  D4:E8:F7:14:9C:A1:DE:DC:89:02:F5:93:F3:AD:AA:C3
         SHA1: 10:9C:6D:D8:DA:64:55:3A:E3:2A:EC:E3:12:19:07:00:DE:AD:BE:EF
         Signature algorithm name: SHA1withRSA
         Version: 3
(...)
Trust this certificate? [no]:  yes
Certificate was added to keystore
[Storing res/raw/cacerts]
Je zip, je signe l'apk, je lance l'application et ... toujours le même message laconique dans la console m'indiquant encore une erreur de handshake.

Fin de l'analyse

Il n'est pas difficile de comprendre que l'application vérifie l'appartenance de l'autorité à une liste exhaustive et contenue dans un keychain.

L'application vérifie ensuite que le certificat est signé par Verisign (VeriSign Class 3 Secure Server CA - G2 selon openssl s_client -connect api.twitter.com:443).
La sécurité est bien renforcée si vous avez installé l'application depuis l'Android Market sur votre terminal.

Le client Android est à l'abri de l'interception par un certificat installé dans votre terminal par un (opérateur / fabricant / technicien / rom cooker ) mal intentionné, de l'interception par certificat racine volé et de l'interception par appliance proxy SSL. Ces appliances sont très prisées des dictatures (poke Amesys) malheureusement des démocraties modernes comme la France.

Transmettre ou pas une donnée personnelle ?

Dans le cas de DirectRepondeur j'ai préféré détruire une partie de l'information (40%) en ne transmettant que les 6 premiers numéros plutôt que transmettre une information complète accessible au premier badboy qui pwn mon serveur.

Si, comme Twitter, l'information doit être complète, vous avez la voie à suivre : ne faîtes pas confiance aux autorités de la ROM, et vérifiez l'émetteur ET le hash du certificat pour ne pas être dupé par un certificat illégitime.

Infaillible ?

Sécurisé sans être inviolable. Eyes on you twitter, don't screw up !
URL     https://api.twitter.com/1/users/lookup.json?email=xx%40gmail.com,yy%40gmail.com&phone=1234,4567
Status  Complete
Response Code   200 OK
Protocol        HTTP/1.1
Method  GET
Content-Type    application/json; charset=utf-8
Client Address  /192.168.1.103
Remote Address  api.twitter.com/199.59.149.200
Enregistrer un commentaire