Android Lockdown, or How to Find the Inner Linux!

What a year! After more than one year, this blog is still alive!

“They besought him of how canst one become so fullsome [as him] in the midst of rude men; `Dost as they dost not!`, he sweren”

That’s it for now …


[to all the people who are reading this directly, through a feed, through Fedora Planet, through Fedora Planed feed, etc.]
– Hellow! How do you do?

[to anybody who is listening out there!]
– Greetings from planet earth!

When I first bought my Android Samsung Exhibit II smartphone I was mostly interested in working with Android as an embedded Linux operation system and perhaps doing some projects on it; but the Android Debugging Bridge (ADB) shell wasn’t really comfortable and more or less convinced me that it’s not really meant to be used that way. Plus I really don’t like Java so I just forgot about the Linux inside.

[Almost] Everything was going smoothly until a few days ago 1 I got locked out of my phone. Android asks for the connected Google account credentials if someone forgot the gesture code or if someone entered too many wrong codes. The problem is that I had disabled data connection since I don’t have data service, and moreover, I had turned off wifi in order to to preserve battery that morning; so there is no internet access and thus Android could not verify my username and password with Google! :( 2

Android Lockdown

My first reaction was to try some special codes such as blank password or 0000, but soon I realized that nothing could be done from outside and the only way was to hack into my phone! Luckily for me, I had left the USB debugging option enabled since I initially tried adb, so getting a shell was as easy as connecting to my phone and running adb.

Since my knowledge of Android internals wasn’t any further than the fact that it’s Linux based, I had no idea of the security methods, controlling the device, etc.. I’m not complaining because I believe that is exactly what makes hacking fun 3

These are my main ideas on how to work around the problem:

1- Enable the wireless (`iw`, `wpa_supplicant`, etc.)

[Too long, didn't write!] Didn’t work! I had used `iw` and `wpa_supplicant` to connect a WRT54GL Linksys wireless router (with OpenWRT installed on it) to another wireless network (yes, client mode!) before, but Android doesn’t have `iw` on it and apparently `wpa_supplicant` couldn’t initiate the connection appropriately.
For more information about `iw` (even though Android doesn’t have it, almost all distros do) and `wpa_supplicant` Refer to The Respective Manuals. 4
In short, the cool thing about `iw` is that you can perform network level AND hardware level operations with it, kinda like `ip` but for wireless devices. A few of useful commands that I use sometimes are:

$ iw list	# list physical devices
# iw dev <devname> scan [-u] [freq <freq>*] [ies <hex as 00:11:..>] [ssid <ssid>*|passive]	# scan for wireless networks, just look at all those data! Ain't it fascinating? :D
# iw dev <devname> connect [-w] <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1:6162636465]
# iw dev <devname> disconnect

2- Connect my phone to internet using my laptop as a gateway (`iptables`, `ip route`, etc.)

The idea is simple, I’m sure lot’s of you have tried to share internet between two systems at one point before; could be a virtual machine, an embedded system, a PC without wifi card, or getting internet from your 3G phone! As a matter of fact I did succeed to do so with my Android phone, but for some reason the lock didn’t let me in; I could ping Google from the shell, but perhaps the applications can only access internet through predefined ways (wifi and 3G)

For more information refer to `iptables` and `ip` manual pages. I found this link 5 to be very informative, even though the purpose is different and it’s mainly graphical, it’s for the same cause. `ip` and `iptables` are two network related commands that you must know how to work with! Some basic examples:

# iptables -L -n	# shows current firewall setting
# iptables -L -t nat -n	# shows current NAT setting

$ ip route	# or `ip r`, same thing. shows the routing table.
# ip r del default
# ip r add default via [gateway] dev [devname]

3- Break the lock (resetting the lock, etc.)

Honestly, I didn’t expect this one to work! I mean, seriously, it shouldn’t be so easy to break the lock! But it worked!

[root@eve ~]# adb shell
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
# id
uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)
# ls
efs
...
# ls /efs
cryptprop_FailedAttempts
cryptprop_persist.sys.timezone
cryptprop_onetimeboot
cryptprop_securewipedata
cryptprop_lock_pattern_autolock
cryptprop_lock_pattern_tactile_feedback_enabled
dmp
cryptprop_lockscreen.password_type
cryptprop_persist.sys.language
cryptprop_rebootMode
cryptprop_lockscreen.lockoutattemptdeadline
edk_p
lost+found
cryptprop_lock_pattern_visible_pattern
cryptprop_essiv
cryptprop_lockscreen.patterneverchosen
cryptprop_applied_result
cryptprop_efs
# mount
...
/dev/block/mmcblk0p27 /efs ext4 rw,relatime,barrier=1,data=writeback 0 0
...
# umount /efs
# 

DONE! The lock is gone! And I wasn’t even root! Apparently /efs is where Android stores many of it’s important properties files, many of which are readable only by root, but anybody can unmount it! This is certainly a security flaw that I’m sure it fixed in the newer versions of Android (mine is Gingerbread 2.3).

Conclusion: But the point of this post wasn’t just to reveal a security flaw after 6 months! The point was to show you that at the end of the day, Linux does as Linux does, no matter what the distribution is or what kind of cpu architecture is running it. I learned things from my phone that became useful later while working with servers! Again, Linux does as Linux does; just find the inner shell, and you’re all set. Maybe you’ll only need to enable usb debugging on Android, or perhaps you’ll have to open up your Amazon Kindle and connect a serial port to a secret port, but in the end, you will feel as if you’re working with your own system, you’ll feel like home. ;-)

Notes:

  1. well, actually 6 months ago when I drafted this post!
  2. Do I really need to mention that I couldn’t enable any of those while in lockout? Give me some credit, man!
  3. just to clarify: hacking equals curiosity, IMO.
  4. aka. RTRM :-p I’m gonna start a “respect the manual” movement someday … ya’ll see …
  5. I’ve just bought a Raspberry Pi and I did pretty much the same thing, in terminal! I’ll write about it soon

6 Comments

  1. Posted December 23, 2012 at 6:38 AM | Permalink

    Hi,

    I had the same problem in 2009, and solved it by deleting the gesture.key file (I did not have adb enabled so booted a custom recovery image that gives adb and root).

    Later I made a tool that brute-forced the md5 hash of the gesture, and created this page: http://moshe.nl/android/

    After a few years, I now have a new android phone, and the tool still works. As a coincidence, I saw this post on Planet Fedora, It seems I’m not the only one that had this problem, and neither are you!

  2. mahrud
    Posted December 23, 2012 at 3:23 PM | Permalink

    This is great! I wonder, how did you find out what the algorithm that produces gesture.key is? Your tool found out what my key is just using the first 4bytes so it can’t be md5, right?

  3. Posted December 24, 2012 at 1:39 AM | Permalink

    I remembered it was MD5 (I now think it was SHA1), however I found it by reading the android source. I’m not 100% sure, but I think this is it:
    https://github.com/CyanogenMod/android_frameworks_base/blob/jellybean/core/java/com/android/internal/widget/LockPatternUtils.java#L733 (the patternToHash method)

    Apparently that function uses SHA1, but the strength of the hash does not matter at all, because the search space is tiny. I simply brute-forced everything (even including many impossible gestures), and saved the result to JSON. ( http://moshe.nl/android/gestures/ is the folder containing the files, the tool is simply a javascript lookup. )

    Because of the small number of gestures, I don’t think there are many duplicates in the first 4 bytes, and the tool shows the solution when there is only one matching hash left.

  4. mahrud
    Posted December 24, 2012 at 2:14 AM | Permalink

    Oh, I forgot that it’s all open source! Nice!
    I see. They should have added some salt. I wonder why do they use salted sha-1 for password-auth but gesture-auth remains unsalted … not very smart! But of course, I don’t know where to begin to count security mistakes! Why the hell is gesture.key readable in the first place? It’s permissions is 600 system:system and adb is not in system group, so …?

    # ls -l /data/system/gesture.key
    -rw------- system   system         20 2012-11-04 14:18 gesture.key
    # id
    uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)

    Essentially usb debugging mode makes all security considerations absolutely useless!
    Now I’m kinda curious about how can I read the memory without adb because if that works out, having that gesture.key is easy to break, android’s [physical] security will be worthless!

  5. Gunjan
    Posted December 24, 2012 at 10:42 AM | Permalink

    I am afraid I failed to understand what you meant by not being root. By looking at your adb shell dump I can say that you are running those commands as a root user. On android, a simple user is not allowed to mount/unmount the partitions. It looks like either you are using a rooted mobile or you are running your adb shell as root ( latter will be possible if the device is not a production device ).

  6. mahrud
    Posted December 24, 2012 at 3:52 PM | Permalink

    Look at this:

    [mahrud@eve ~]$ adb shell
    * daemon not running. starting it now on port 5037 *
    * daemon started successfully *
    # id
    uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)
    # su
    # id
    uid=0(root) gid=0(root)

    Yes my device is rooted, but every time I su a notification pops up in my phone and I have to allow it in order to get root and I couldn’t do that because of the lockdown.
    Also, if you look at the code above, you can see that the default user is neither root or in root group, but it is in mount group!
    However, it is possible that the rooting process added the default user to these groups. Honestly, I don’t think so, but maybe you are right. I’ll have to try it on a not rooted device.

    In any case, the main goal is to show the joy of reaching and using the inner linux. ;-)http://algorithms.ir/~mahrud/blog/wp-admin/edit-comments.php#comments-form

One Trackback

  1. [...] Everything was going smoothly until a few days ago 1 I got locked out of my phone. Android asks for the connected Google account credentials if someone [...]