So it turns out that Cyanogemod’s built in updater gets it’s update information by contacting http://download.cyanogemod.org/api

Note the http:// part there. It also turns out there’s no signature verification of the flashable .zip file that the custom recovery uses to update. What this means is that anyone who can MITM your connection (Which means the NSA to anyone who can manipulate the BGP routing table all the way down to anyone who can own your router/has access to your local LAN/WLAN) can change where the cyanogenmod update looks for the image file that CM will flash.

The updater connects to download.cyanogenmod.org on port 80 and asks:

1 {"method":"get_all_builds","params":{"device":"hammerhead","channels":["stable","snapshot","RC","nightly"]}}

In reply the server usually sends:

1 2 3 4 5 6 7 8 9 10 11 12 13 { "id": null, "result": [ { "url": "http://get.cm/get/jenkins/59291/cm-11-20140216-NIGHTLY-hammerhead.zip", "timestamp": "1392551863", "md5sum": "1318e463181519622aa5bb10be0bd5d2", "filename": "cm-11-20140216-NIGHTLY-hammerhead.zip", "channel": "nightly", "changes": "http://get.cm/get/jenkins/59291/CHANGES.txt", "api_level": 19 }, etc

To MITM someone’s update all you need to do is firstly grab a legit copy of the CM update they’re likely to upgrade to, unzip it, replace whatever you want inside it, md5sum it, then serve it up via http. You replace the URL above with your evil URL, the md5sum with your new md5sum and the filename with your evil file. Then use something like mitmproxy + (Wifi pineapple/ARP spoofing/DNS spoofing/etc) to MITM the targets connection. mitmproxy will let you script/regex requests so you can replace the URL/md5sums automagically so then you end up with something like this:

In this case I just modified the build number of the legit CM update, hosted on a webserver running on 192.168.1.83 and MITMed the CM updater to look there for the new update. The middle image shows a screenshot from a Nexus 7 that succesfully applied the hacked update.

This worked because while CM verifies the md5sum (that we replaced) most custom recoveries either just verify that signatures are valid but not authentic or don’t verify that signatures are valid at all.

I’ve opened a bug with CM, CYAN-3502. Lets hope they can fix this. (Probably just by using HTTPS/SSL and verifying certs!)