You are here

My Experience with "Mission Impossible: Hardening Android for Security and Privacy"

Background

There's an excellent guide written by Mike Perry at the Tor project blog titled Mission Impossible: Hardening Android for Security and Privacy. My article will be a summary of my experience following the guide, departures I made from his instructions, and hurdles I encountered with my devices. My main departure from the guide is that I don't push all my traffic through Tor. However, the guide's recommendations to use Cyanogenmod, Privacy Guard, an application firewall, and filesystem encryption go a long way toward taking control of information coming from your Android device.

My Hardware

I have an Asus Transformer (TF101) tablet and HTC One Mini (M4) cell phone that I may provide specific details for, though my notes should mostly be generic.

Cyanogenmod 11 M11 on HTC One Mini (M4)

  • Follow the guide on the Cyanogenmod M4 wiki.
    • Note: The instructions under "Unlocking the Device" mention enabling USB Debugging. It's in the Developer Options menu, and to make the Developer Options menu visible, first you must enable developer mode on the phone. Tap the "Build Number" menu item 7 times.

Cyanogenmod 10.0 on Asus Transformer (TF101)

  • I unlocked my bootloader a while ago with wheelie like the Cyanogenmod TF101 wiki suggests. Wheelie links from the guide are broken now, but the developers have an updated Linux-only version of Wheelie that supports TF101 devices with B70+ serial numbers. I have not confirmed that it's working on my B40 device though.
  • I had problems reading /sdcard/ with ClockworkRecoveryMod so I installed TeamWinRecoveryProject 2.3.2.3 using ADB/Terminal method.
  • I ran the stable Cyanogenmod 9.1.0 for rougly two years. Since I was diving into this article I figured I would update to cm-10-20130929-NIGHTLY-tf101.zip and try it out. It's been running smoothly for some time now. The nightly is CM 10.0 (running Jellybean) so be sure to get the correct gapps if you're using Google Apps (ie. gapps-jb-20121011-signed.zip).
    • I did have a problem with the lock screen widget triggering Android to crash and reboot. Shortly after the "starburst" animation allowing you to drag the unlock icon to a quick Google search or normal unlock, it would crash. I worked around this by unselecting Settings > Lock Screen > Show widgets before unlock. Not too big of a deal because I don't use the lock screen quick actions on my tablet anyway.
    • Initially I had no sound through Bluetooth devices even though they are paired and Media audio is checked under Paired Bluetooth device settings. A forum post by user eatblueorange at xda-developers.com quickly got me straightened out, though I only needed the a2dp portion. I booted into ClockworkRecoveryMod, mounted /system, and then used adb shell on my workstation to edit the /system/etc/audio_policy.conf file. In its entirety, the new file is:
      # Global configuration section: lists input and output devices always present on the device
      # as well as the output device selected by default.
      # Devices are designated by a string that corresponds to the enum in audio.h
      
      global_configuration {
        attached_output_devices AUDIO_DEVICE_OUT_SPEAKER
        default_output_device AUDIO_DEVICE_OUT_SPEAKER
        attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC
      }
      
      # audio hardware module section: contains descriptors for all audio hw modules present on the
      # device. Each hw module node is named after the corresponding hw module library base name.
      # For instance, "primary" corresponds to audio.primary.<device>.so.
      # The "primary" module is mandatory and must include at least one output with
      # AUDIO_OUTPUT_FLAG_PRIMARY flag.
      # Each module descriptor contains one or more output profile descriptors and zero or more
      # input profile descriptors. Each profile lists all the parameters supported by a given output
      # or input stream category.
      # The "channel_masks", "formats", "devices" and "flags" are specified using strings corresponding
      # to enums in audio.h and audio_policy.h. They are concatenated by use of "|" without space or "\n".
      
      audio_hw_modules {
        primary {
          outputs {
            primary {
              sampling_rates 44100
              channel_masks AUDIO_CHANNEL_OUT_STEREO
              formats AUDIO_FORMAT_PCM_16_BIT
              devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO
              flags AUDIO_OUTPUT_FLAG_PRIMARY
            }
          }
          inputs {
            primary {
              sampling_rates 8000|11025|16000|22050|24000|32000|44100|48000
              channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO
              formats AUDIO_FORMAT_PCM_16_BIT
              devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET|AUDIO_DEVICE_IN_WIRED_HEADSET
            }
          }
        }
        # Jan 1, 2015: Adding a2dp section to fix bluetooh audio. (r24mille)
        a2dp {
          outputs {
            a2dp {
              sampling_rates 44100
              channel_masks AUDIO_CHANNEL_OUT_STEREO
              formats AUDIO_FORMAT_PCM_16_BIT
              devices AUDIO_DEVICE_OUT_ALL_A2DP
            }
          }
        }
      }
      

Privacy Guard

In my opinion, this is the biggest step toward taking control of how applications use information on your Android device. Granular permission categories allow you to give applications only the information you are comfortable providing to it. Privacy Guard does so in a manner that does not break application functionality.

I recommend activating Privacy Guard on all applications and setting them to "Always Ask." Then, as you go about using your device for the next few days you'll get a prompt for every permission the application wants to use. With this prompt you can choose to remember yes/no. In this way you will naturally create a minimum set of permissions for all applications.

HTC One Mini (M4)

  • Privacy Guard works great in Cyanogenmod 11!

Asus Transformer (TF101)

  • Unfortunately, because the latest build for TF101 is Cyanogenmod 10.0, Privacy Guard is not built in. It first appeared in Cyanogenmod 10.1 nightlies as "Incognito Mode" and grew from there into what it is today. Nor is App Ops available, since Cyanogenmod 10.1 runs Android 4.1.x. So my third choice is to download XPrivacy from github and follow the Installation instructions. It has a dizzying amount of control over application permissions.

Encrypting the Filesystem

First there are a few basic nuances Mike Perry does not mention that I will:

  1. To get su on the device via adb, you'll need to have enabled Settings > Developer options > Root access > Apps and ADB. (You may want to disable ADB root when you're done, and just turn it on as you need it.)
  2. Be sure your battery is at 100% before starting encryption.

Also, as mentioned in the article, filesystem encryption may fail if the device has many applications running. The reason for this is that the inplace encryption may not be able to kill one of those processes, meaning that vold cannot unmount /data before encryption. My advice is a bit simplistic but I'd recommend turning off wireless, mobile data, bluetooth, GPS, etc. and then rebooting your device. Wait for the phone to fully start up but don't do anything more. The phones capabilities should still be disabled and as few applications as possible will be running due to the reboot. Then run the cryptfs enablecrypto inplace command as described. Hopefully you won't have to troubleshoot further.

If you do have to troubleshoot further, here are a few of my notes relating mostly to my experience with the HTC One Mini.

HTC One Mini (M4)

Whether running encryption using vdc through an adb shell or through Settings > Security > Encrypt Phone, both routes yeilded an "unmounting /data failed" error message. Looking at the Android Open Source Project (AOSP) documentation for encryption, one can see that the /data filesystem is supposed to be unmounted during the encryption process. With many applications installed and running processes, it's more likely that one may prevent vold from unmounting /data.

Comment #29 of AOSP Issue 58073 had a good suggestion if you're encountering this error. I opened two terminal windows and brought up an ADB shell in both. In one window I had the commenter's suggestion running:

while true; do lsof | grep /data; sleep 0.2; done

In the other window, I ran the encryption command:

su
vdc cryptfs enablecrypto inplace YourEncryptionPassword

Looking back at the first window, if a process is preventing /data from being unmounted, you'll see it listed in the lsof loop. I saw something similar to:

dhcpcd     4446       dhcp    4       ???                ???       ???        ??? /data/misc/dhcp/dhcpcd-wlan0.pid

It looks like wireless is the culprit. Fixing the issue was only a matter of rebooting the phone, turning off wireless, turning off mobile data, and running the encryption command again. On a previous phone I had a similar /data unmounting issue that was not dhcpcd-wlan0.pid, though I can't remember the applications. It required killing a number of culprit pids before starting encryption.

Asus Transformer (TF101)

Running vdc cryptfs enablecrypto through adb shell I got the following error:

D/VoldCmdListener(  101): cryptfs enablecrypto inplace {}
E/Cryptfs (  101): Cannot get size of block device

This xda-developers thread seems to describe my situation very closely. At the end of the post, the author links to another xda-developers thread which describes recovery.fstab and is explained by Gary Peck in CYAN-87. I think this means making my own build of Cyanogenmod with length=-16384 added to recovery.fstab. (TODO: attempt to fix, may not have to build with edited recovery.fstab, only resize partition).

Tor and Firewall Configuration

Personally, I keep a non-exit node running in Orbot (for others) and use Orweb when I'm browsing the web without authenticating. However, I'm not interesting in running all my traffic and applications through Tor, as the guide and its install-firewall.sh script would have me do. So I did not run the script, and looking into its contents I skipped everything that had to do with Tor-ifying my device.

However, there is one gem that has to do with "Google Captive Portal Detection." Android connects to http://clients3.google.com/generate_204 after wifi association to see if you're behind a captive portal (eg. hotel wireless). This is worrisome because Google gets a bit of data on you each time you connect to a wireless network. Instead the script disables captive portal detection and sets the captive portal server to 127.0.0.1 (ie. localhost) for good measure. Rather than picking apart the scripts, you can just run the lines yourself via ADB.

adb shell su -c "settings put global captive_portal_server 127.0.0.1"
adb shell su -c "settings put global captive_portal_detection_enabled 0"

Droidwall vs. AFWall+

Mike Perry also seems to have a preference for Droidwall over AFWall+. From the README.md file in Github, "[AFWall+'s] original codebase was derived from DroidWall by Rodrigo Rosauro. DroidWall was sold to AVAST in December 2011, and is no longer actively maintained." Simply because AFWall+ is actively developed and periodic updates are released, I'm inclined to use it, despite the comments made by Mike Perry in the Installation and Setup: Tor and Firewall configuration section of his article.

Miscellaneous

At the end of Mike Perry's guide, he makes several application recommendations. I have a few recommendations of my own to add.

AdAway

AdAway edits your device's /etc/hosts file and adds lines that direct thousands of ad tracking services to 127.0.0.1 (ie. localhost). This means that any ad in the browser, in an application, etc. are routed to 127.0.0.1 and will return "not found." I like the idea that it's low-level in the system and not confined to a browser plug-in or something. At first I was a bit nervous about giving an application root permissions to accomplish these changes and apply updates, but I peeked at the source code. Everything seemed in order and I've been very happy with the application itself.

Firefox Plug-ins

As recommended in the guide, Firefox is a great browser. I think there are few privacy-minded plug-ins to run in browser, as recommended by PRISM Break.

  • HTTPS Everywhere, developed by the Electronic Fronteir Foundation maintains a list of all sites that function reliably over HTTPS and will redirect any website visited in HTTP to be over HTTPS if possible.
  • Self-Destructing Cookies, removes cookies immediately after you leave the website that placed them there. I like the increased granularity over Firefox's three options in Settings > Privacy > Cookies. If you would like a site to keep cookies on your device, the Settings > Cookie Whitelist option will allow you to do so easily.

Default Search Provider in Firefox Mobile

I'm starting to dig DuckDuckGo as a search engine for its anonymous, unlogged web searches. To add it as a search provider in Firefox mobile just browse to https://duckduckgo.com/. Long-press in the search field to have it added as a search provider in Firefox mobile (documentation).

Comments

There are many recommended privacy and security tools as well that can be employed. It is also a noteworthy fact that there are free versions apps as well that are supported by advertisements, thus you just need to explore a few bucks to get the paid version.

1. thanks for the tips re encryption.

2. rather than using https://duckduckgo.com, bypass legacy DNS and exit node by using their hidden service https://3g2upl4pq6kufc4m.onion/

3. If you use firefox, try and make it send the same headers as Tor browser?

4. this captive portal detection, I noticed this rather by chance while checking my cyanogenmod+orbot+orwall setup for leaks using tcpdump on my wifi router. The connections were pretending to be IPv6 connections with some weird address translation scheme (they were really IPv4 with lots of zeros prepended or somesuch) when I hunted them down with netstat and they were only in /proc/net/tcp6, not /proc/net/tcp.

Weirdly, even telling iptables6 to drop everything didn't seem to help. What a fucking great idea, to embed apparently unblockable connections to google so deep in the system! Luckily, there's the option mentioned above, which worked. Luckily also, I'm paranoid enough never to have had any private data on the device so even if identifying information or data would have been transmitted, there wouldn't have been any to transmit. Most luckily, the connections really appear to be mostly harmless. Still ...