Interview with Channel 4 News about contactless cards

Channel 4 News got in touch with me about contactless credit cards. They asked if it was possible to read personal details from NFC credit cards using an Android phone. Of course this has been known for some time but they wanted to demonstrate it for the public so I put an app together at short notice and they filmed the piece below.

Source code wasn't released but check out this related project on GitHub

Downloading APKs from Android Market

Note: This is a very old post and will no longer work because the Google Play API has changed significantly. This post has been left here for historical reference.

Sometimes I need to get hold of an Android application from the Market for analysis. One way to do this is to manually use the Market on an Android device or emulator, install the App, and then copy it off. For various reasons this isn't always ideal - I sometimes don't want to install an App if I don't know what it does, and I may want to get it a lot faster (i.e. automate it).

In this post I share what worked for me in creating a command line script to login to the Market and download the application's APK. This isn't anything particularly new as an unofficial Market API already exists for searching the Market and Tim Strazzere posted some Java source to emulate a download request. However, in Tim's example you have to manually specify the App's assetID and your authToken which means it isn't automated. What I wanted was a script which takes a package name as a parameter and downloads it. To achieve this I used the Market API to login, get an authToken, search for the package, get its assetID, and then submit a download request.

I've documented this for interest, it isn't supported software and there isn't much error checking. If you use this it is assumed you know what you are doing.

What was used:

  • Linux with PHP including curl support
  • Rooted Android phone (I used a spare development phone)
  • Temporary GMail account associated with phone
  • PHP Android Market API by Splitfeed
  • ADB from the Android SDK

I'm using Ubuntu Linux and PHP with curl support. To install it you need something like this:

$ sudo apt-get install php5-curl

The first step is to get the Android Market userID which is required in the download request for APKs. I'm not aware of an easy way to get this at the moment but it is simple enough to sniff from the real Market App and only needs to be done once. Tim Strazzere comes to the rescue again with a nice tip for easily sniffing traffic on Android.

Open up the Market App on the device and find an app to install, start the following ADB command and then click install:

$ adb shell tcpdump -vv -s 0 -w /sdcard/output.cap

After install hit Ctrl+C to to stop sniffing. Open up the .cap file in something like wireshark and look for a GET request which contains the deviceID and userID parameters and make a note of them. I found that on my phone the GET request was different from the one in Tim's post, it had extra parameters and when I manually emulated it I was given a 302 redirect to download the file. However, using the older GET request as per Tim's post and ignoring the extra parameters seems to still work and leads to the direct download of the APK.

Download PHP Android Market API and unzip it somewhere. In the subfolder examples create a file called local.php with the following contents (replacing my values with yours):

<?php
define('GOOGLE_EMAIL',[email protected]');
define('GOOGLE_PASSWD','yourpassword');
// Use a random number with the same number of digits:
define('ANDROID_DEVICEID','0000000000000000');
// Use your real deviceID here that you sniffed:
define('ANDROID_REALID','0000000000000000000');
// Use your sniffed userID parameter here:
define('ANDROID_USERID','00000000000000000000');

I found that the Market API worked with a fake deviceID but not my real one, and the APK download request worked with my real deviceID but not the fake one. I didn't look into it too much as it seems to work okay as above.

Download test_download.php.txt and save it in the examples folder as test_download.php.

Edit MarketSession.php in /Market so this line:

private $authSubToken = "";

Becomes:

public $authSubToken = "";

Okay that is the preparation. We can now use the script to grab any free app from the Market by passing the package name as a parameter. In this example I found a Notepad application on Android Market and saw the package name in the URL was bander.notepad, so:

[email protected]:~/market-api/examples$ php test_download.php bander.notepad
* About to connect() to android.clients.google.com port 80 (#0)
*   Trying 74.125.71.139... * connected
* Connected to android.clients.google.com (74.125.71.139) port 80 (#0)
> POST /market/api/ApiRequest HTTP/1.1
User-Agent: Android-Market/2 (sapphire PLAT-RC33); gzip
Host: android.clients.google.com
Accept: */*
Cookie: ANDROID=DQAAAREDACTED
Content-Type: application/x-www-form-urlencoded
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Content-Length: 586

< HTTP/1.1 200 OK
< Content-Type: application/binary
< Date: Sun, 12 Jun 2011 23:34:37 GMT
< Expires: Sun, 12 Jun 2011 23:34:37 GMT
< Cache-Control: private, max-age=0
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< Content-Length: 140
< Server: GSE
< 
* Connection #0 to host android.clients.google.com left intact
* Closing connection #0

Downloading Notepad (3073103588488610805)

[email protected]:~/market-api/examples$ ls -hl *.apk
-rw-r--r-- 1 user user 45K 2011-06-13 00:34 bander.notepad.apk

And now we have the APK. The Market API is actually really good and it can also get other data about the app such as author, version, what permissions it needs, screenshots, etc. It would be a fairly trivial enhancement to get the script to save this extra metadata at the same time as the APK if needed.

Developments on Android Security and Forensics

It has been a little while since I've had the chance to blog and a few things have been going on so I thought I'd sneak in an update.

While I was in the Caribbean, the annual Pwn2Own competition happened. There were several contestants lined up to exploit the Android device but in the end none of them stepped up. The first was security expert Jon Oberheide who I learned just before the competition had a working exploit, but unfortunately he informed Google who patched it before the event. Now that Jon has revealed details about how he almost won Pwn2Own everyone can see he was going to use a simple XSS in the Android Market! I discussed the same type of attack after my initial look at the Market security here and remember a lot of people dismissing it. Well, Jon actually went ahead and developed the attack, and it was a shame he didn't get to show off the fantastic work he had done at Pwn2Own. Google were fast to rectify as usual and their site was combed over for a new XSS before the competition with no luck. They have really enhanced the security since the first time I looked. Still, the case remains that users are one XSS flaw away from having software installed and run on their device!

I haven't published much new research recently in part because my free time has been spent developing the next version of an Android Forensics tool for a mobile forensics company. Due to NDAs and such I am not able to give details, but it is looking really good, and it is scary to see what data we can extract from Android phones!

Speaking of Android forensics, there is a new book coming out shortly by Andrew Hoog, CIO of viaForensics, about Android Security and Forensics. I've been lucky enough to get an early preview and it looks very good and very detailed, and the best resource on the subject I've seen to date. Some of my research is referenced a couple of times as well!

Android Lock Screen Bypass

Note: This post is very old. Google made a change in Android 4.0 for security reasons so that newly installed apps cannot be started with a broadcast intent until the user runs it manually at least once. Therefore this technique doesn't work on devices running 4.0 or later.

So far I have tried out 5 Android devices here in the UK (test device, personal phone, and those of friends). They all lack the same feature - if you forget your PIN or pattern code, there doesn't seem to be a way to reset it. You are effectively locked out of your device. Searching online I see that some people are able to reset it after a certain number of attempts by entering their GMail credentials, but I am unable to do so on mine or others I have tried.

We now have the fantastic web based Android Market, and I wrote about a few minor security findings here. One of the common responses I saw to articles talking about the threat of malware distribution was that when remotely installed, an application doesn't automatically run and the user would have to manually launch the malware. This is not actually correct, and to demonstrate I decided to create a legitimate utility which can be deployed to a locked phone, executed remotely, and set to disable the lock screen. This will yield access to a locked device so that the user may go in and backup their data.

How it works

Quite simple really. Android sends out a number of broadcast messages which an application can receive, such as SMS received or WiFi disconnected. An application has to register its receiver to receive broadcast messages and this can be done at run time, or for some messages, at install time. When a relevant message comes in it is sent to the application and if the application is not running it will be started automatically.

After testing out various broadcast messages the best one I found for the purpose of this utility was android.intent.action.PACKAGE_ADDED. This exists in all APIs since version 1 and is triggered when an application is installed. So to get the application to execute remotely, we first deploy it from the Android Market, then deploy any other application which will cause the first one to launch.

Once launched it is just a matter of calling the disableKeyguard() method in KeyguardManager. This is a legitimate API to enable applications to disable the screen lock when, say, an incoming phone call is detected. After finishing the call the app ought to enable the screen lock again, but we just keep it disabled.

Get the Screen Lock Bypass application: Google Play