Sunday, December 18, 2011

Kindle Fire Security, Part III- Making Purchases With A Deregistered Device

This issue was disclosed to Amazon several weeks ago. Amazon did a great job at responding, replicating the problem, and working towards a fix. Below is the disclosure, response, and remediation timeline:

November 23, 2011: Notified Amazon
November 23, 2011: Amazon acknowledged the issue
December 9, 2011:  Update from Amazon on forthcoming patch
Sometime Before The End Of December, 2011: Security update released

Each Kindle Fire is registered and tied to an Amazon account. A registered device has access to the Newsstand, Books, Music, Apps, and so forth. A registered device also has access to make purchases on behalf of the account tied to the device. After you've registered the device and tied it to an Amazon account, you have access to all of those services and aside from unlocking the device, you do not need to re-authenticate to make purchases. 

In the event a device is lost, given to a family member as a gift, etc., the device owner can deregister the device through the Amazon website. Upon deregistering the device, access is immediately revoked from ordering content including Books, Newsstand, Video, Apps, and Music. However, the ability to continue using the registered account to order ACTUAL ITEMS, is not. 

In fact, the session token used to allow a user to continue making purchases through the Amazon store has a lifetime of approximately 72 hours after deregistering the device. While testing, I was able to continue making 1-click purchases for 3 days after deregistering the device. I kept ordering and canceling until the session token eventually stopped working and the device began requesting a new set of credentials. 3 full days with unauthorized access to make purchases.

The next Kindle Fire update should contain a fix for this issue. I'm guessing this issue also requires a server side fix in order to immediately revoke the existing token used for the Amazon app on the deregistered device.

Tuesday, November 22, 2011

Kindle Fire Security, Part II- ADB, DropBox Manager

Another day, another short post detailing some other interesting things about the Kindle Fire. After only a day on the market, it was already rooted.  Here's a link to how it's done: http://forum.xda-developers.com/showthread.php?t=1348830

So, the two highlights of this post: 

Aside from the fact that the Fire shipped with KNOWN exploits present (as many devices sadly do), something else caught my attention through it all: ADB is enabled by default, and users have no way to disable it through the UI. Unlike other Android devices that at least force users to make a conscious decision to leave it enabled at all times, the Fire opts you in. For anyone that's not familiar with ADB, it stands for the Android Debug Bridge.  It's used for debugging, testing, and poking around on a device.  Anyone that can follow the steps within the XDA Developers link, pretty much has access to everything on your device. Even with a locked device. You lose your device = the bad guys win.

Besides everything our apps store and transmit about us, what lurks on the Kindle Fire? Well, let's fast forward to having a rooted device. This lets us navigate the entire filesystem, including app data directories and other directories only intended for privileged users. Here is the output of running 'ls -l' on the / directory:

$ su
su
# ls -l
ls -l
dr-x------ root     root              2011-11-17 14:10 config
drwxrwx--- system   system            2011-11-20 21:02 dropbox
drwxrwx--- system   cache             1969-12-31 19:00 cache
lrwxrwxrwx root     root              2011-11-17 14:10 sdcard -> /mnt/sdcard
drwxr-xr-x root     root              2011-11-17 14:10 acct
drwxrwxr-x root     system            2011-11-17 14:10 mnt
lrwxrwxrwx root     root              2011-11-17 14:10 vendor -> /system/vendor
lrwxrwxrwx root     root              2011-11-17 14:10 d -> /sys/kernel/debug
lrwxrwxrwx root     root              2011-11-17 14:10 etc -> /system/etc
-rw-r--r-- root     root         4203 1969-12-31 19:00 ueventd.rc
-rw-r--r-- root     root          840 1969-12-31 19:00 ueventd.omap4430.rc
-rw-r--r-- root     root            0 1969-12-31 19:00 ueventd.goldfish.rc
drwxr-xr-x root     root              2011-11-15 17:24 system
drwxr-xr-x root     root              2011-11-17 14:10 sys
drwxr-x--- root     root              1969-12-31 19:00 sbin
dr-xr-xr-x root     root              1969-12-31 19:00 proc
-rwxr-x--- root     root        14943 1969-12-31 19:00 init.rc
-rwxr-x--- root     root        11357 1969-12-31 19:00 init.omap4430.rc
-rwxr-x--- root     root         1677 1969-12-31 19:00 init.goldfish.rc
-rwxr-x--- root     root        90116 1969-12-31 19:00 init
-rw-r--r-- root     root          118 1969-12-31 19:00 default.prop
drwxrwx--x system   system            2011-11-20 20:41 data
drwx------ root     root              2011-11-05 00:17 root
drwxr-xr-x root     root              2011-11-17 14:15 dev


Hmm, the /dropbox directory seems interesting. Before you get all excited and think that this is some type of Dropbox integration, this isn't it.  This directory is used for DropBoxManager (android.os.DropBoxManager) files, which are generally used for system-wide verbose log storage. Here is what it contains:

# cd dropbox
cd dropbox
# ls -l
ls -l
drwxrwx--- system   cache             2011-11-17 10:11 recovery
-rw------- system   system      50619 2011-11-20 21:02 data_app_crash@1321840952
079.txt.gz
-rw------- system   system      57759 2011-11-20 20:41 system_app_anr@1321839667
379.txt.gz


Of interest in particular (to me, anyway) are the data_app_crash* files.  Whenever an app crashes, a file is written with the errors causing the crash as well as stack traces.  This can include sensitive information in some cases. 

Within the /system/app directory, there is a package called com.amazon.dcp.apk. This application performs metric collection, handles OTA messages, and more. It also interacts directly with files located in the /dropbox directory. It monitors the DropBox service to determine when new entries have been created. This is part of Amazon's metrics and analysis framework. If you want to call it a backdoor, then go for it. This will be a topic within a future post.

To be fair, the DropBoxManager is widely used on other devices as well. Additionally, lots of juicy stuff does get logged to the global logs on other devices too. But it certainly worth examining as many developers may be unaware of the fact that even though they are not explicitly logging events, additional channels exist for unintended data leakage. 

To examine the com.amazon.dcp application a bit deeper, we need to decompile it.  There are many resources on the web that detail how to do this.  Here are a few:



The latest version of Agnitio has the decompilation steps automated, but uses JAD for decompilation rather than JD-GUI: http://www.securityninja.co.uk/application-security/agnitio-security-code-review-tool-v2-1-released/  

Additionally, the Android Reversing Toolset is a distro that contains all of the tools mentioned in the blog posts above.  http://threatpost.com/en_us/blogs/android-reverse-engineering-toolset-debuts-110111

We aren't going to post the source code to Amazon's applications here, since cease-and-desist letters are no fun. Decompiling it using the resources listed above is EASY.

Every time an application crashes, Amazon dumps the stack trace and other information to a crash file within the /dropbox directory via the DropBox service. The files follow the format of data_app_crash@<time_in_milliseconds>.txt.gz. I've observed these files existing for several days without being cleared.  

So the worst part about this: the DropBox service doesn't support granular per-app permissions for retrieving crash log entries. You merely need the READ_LOGS permission, and any arbitrary application can retrieve the contents of each crash that's entered into the DropBox. Often, we tell developers that they are safe as long as they aren't logging sensitive information to the GLOBAL logs. What we leave out is that information such as crash logs (that aren't globally logged) may be inadvertently leaked out via other unexpected channels.     

To connect to the DropBox service used on the Kindle Fire, we can create a new DropBoxManager and get an entry with the following snippet of code:

DropBoxManager mDropBoxMan = ((DropBoxManager) context
                                   .getSystemService("dropbox"));
DropBoxManager.Entry localEntry = mDropBoxMan.getNextEntry(null, 0);

With access to the DropBoxManager, we can list entries.  With the entry we just retrieved, we can retrieve the body of the message with the following:

InputStream inStream = localEntry.getInputStream();
BufferedReader reader = new BufferedReader(
                              new InputStreamReader(inStream));
String line = "";
String logData = "";
while ((line = reader.readLine()) != null) {
          logData += line;
  }
  
If we want to iterate through every entry within the DropBoxManager, we need to get the time in milliseconds of the last entry, and pass that into our next request. The easiest way to do this is to wrap the code above within a do-while block:


DropBoxManager mDropBoxMan = ((DropBoxManager) context
                                   .getSystemService("dropbox"));
DropBoxManager.Entry localEntry = mDropBoxMan.getNextEntry(null, 0);

do {
     try {
          InputStream inStream = localEntry.getInputStream();
          BufferedReader reader = new BufferedReader(
                                        new InputStreamReader(inStream));
          String line = "";
          String logData = "";
          while ((line = reader.readLine()) != null) {
                    logData += line + "\n";
          }
     } catch (IOException e) {
     }
     //do something with the data here
} while ((localEntry = mDropBoxMan.getNextEntry(null,
               localEntry.getTimeMillis())) != null);

A malicious application on the Kindle Fire with just the READ_LOGS permission and INTERNET, can intentionally crash other applications, retrieve the logs, and exfiltrate them. How? Easy: explicit Intents with malformed or unexpected data sets. There are many ways to interact with other components, but this one is easy to illustrate. Any application can instantiate the Activity of another application provided it is either exported or has at least one Intent Filter in place. If there are permissions required to start a specific Activity, then that application would also need that permission to start it. By calling a specific Activity and sending it unexpected data or while in an unexpected state, in some scenarios it may be possible to intentionally dump information of interest to the crash logs. Also, applications do crash on their own. A malicious app has access to any and all crash logs.

We can call a package named com.nvisium.crashdummy with an Activity class called CrashActivity. The resulting Activity would crash as a resulting of a missing value within the Bundle passed within the Intent. The code for this is below:

ComponentName toLaunch = new ComponentName(
               "com.nvisium.crashdummy",
               "com.nvisium.crashdummy.CrashActivity");
Intent intent = new Intent("android.intent.action.VIEW");
Bundle bundle = new Bundle();
bundle.putString("userName","superman");
intent.setComponent(toLaunch);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(intent);

Combining the ability to crash other apps on demand with the ability to instantly retrieve that data, this is a serious problem in my opinion. 


Stay tuned for Part III, coming soon.

Tuesday, November 15, 2011

Kindle Fire Security- Initial Thoughts

After a few hours of messing with the Kindle Fire, I wanted to post a few observations that jumped out almost immediately. This is the first of several posts on the Fire. These are the "low hanging" fruits:
  • Emails are all stored in the /sdcard directory and can be read by any application
  • No built-in device lockout after X failed logon attempts
  • Your device is shipped already tied to your account, and does not require additional authentication for activation
  • User and device identifier information leak out in many public places (more in a later post)
  • Other, potentially much worse problems (more in a later post)
There are a few issues that seem to be a lot worse, but we'll save those for a rainy day. In many ways, the Fire seems rushed. Amazon got a lot right, but certainly missed some easy things.

First off, if you use the Kindle Fire's email client, congratulations- all of your email is stored within the SD card directory. Any application can list the contents of this directory, copy the database where your email is stored, and read it. This is a significantly degraded approach compared to how Google's Gmail client works, where emails are kept within internal storage. Internal storage = permissions protect you from non-rooted malicious apps. External storage = anyone can read it. When you plug your Fire into a computer, you have access to the /sdcard directory. The commands below show the /sdcard directories and files leading to your email, while plugged into a computer:

mannino$ pwd
/Volumes/KINDLE/Android/data

mannino$ ls
com.amazon.email          com.android.providers.media
com.amazon.venezia          com.cooliris.media

mannino$ cd com.amazon.email
mannino$ ls
files

mannino$ cd files/
mannino$ ls
76f24e2f-cd70-4def-9ad3-17e590d2dc96.db
76f24e2f-cd70-4def-9ad3-17e590d2dc96.db_att

mannino$ sqlite3 76f24e2f-cd70-4def-9ad3-17e590d2dc96.db
SQLite version 3.6.12
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
android_metadata  folders           messages       
attachments       headers           pending_commands
sqlite> select * from messages;
4|0|12|1|Get Gmail on your mobile phone|1321422874000|X_GOT_ALL_HEADERS,X_DOWNLOADED_FULL|mail-noreply@google.com;|kindlefiretrainwreck@gmail.com;||||<html>
<font face="Arial, Helvetica, sans-serif">
<p>
       alt="Access Gmail on your mobile phone"
       style="border:0px;"/>
</a>


If you lose your device, someone with a lot of time on their hands will eventually brute force your password. There is no lockout function, at all. Compared to most other Android distributions that default to locking a user out after several failed attempts, this one simply doesn't.  Hence, this fails to protect you against even "casual" bad guys, assuming your password is reasonably simple.  

Finally, when Amazon shipped your device, they were "kind" enough to tie it to your account. Yes, the account that is also tied to your credit card(s). After entering your wireless network key, the device will instantly bypass the part of the registration where credentials are required.  So if someone snatched your device before you did, they could have went on a shopping spree, downloaded a bunch of books or music, and lived happily ever after with their content.  I'm not sure about you, but when something is tied to my credit card, I'd like a little more protection. Amazon should at least require the user's password before proceeding.

There are actually quite a few other issues, but I'm going to give Amazon some time to fix them before a public disclosure.  Yes, this is a device built for consumers.  Still, there are no excuses for missing the simple things.

This is the first of several posts on the Fire. So, stay tuned!

Tuesday, September 27, 2011

OWASP Top 10 Mobile Risks

The OWASP Top 10 Mobile Risks were presented last week at the OWASP Appsec USA conference in Minneapolis, Minnesota.  This is a list of the most prevalent and dangerous risk areas in mobile application development today.  Including myself (Jack Mannino), the presentation was given along with Zach Lanier from Intrepidus Group, and Mike Zusman from Carve Systems.

You can find the slides here: http://www.slideshare.net/JackMannino/owasp-top-10-mobile-risks

To be clear, a Top 10 list is merely a start rather than a comprehensive set of risks and compensating controls.  Our goal is to raise visibility into some of these problems, and help developers understand these issues in order to reduce their prevalence and impact in real-world applications.

Currently, this is a release candidate list.  A lot can still change before it gets the green light as final.

If you are interested in contributing to the OWASP Mobile Security Project, please feel free to get in touch with me or anyone else involved with project leadership.

-Jack

Tuesday, June 7, 2011

Blackbox Vs. Whitebox Mobile Security Testing

When you distribute a mobile application via any of the app stores (Apple, Android Market, etc), it is important to understand that your code can be and will be reverse engineered.  Non-obfuscated Android apps are generally the fastest to reverse engineer, but with enough time any application will suffer the same fate.  Code obfuscation is more of a speed bump than a roadblock.  If you are paying a third party consultant to reverse engineer your application, keep in mind that this is time and money that could likely be better spent looking for serious security issues within the application instead. 

The first type of testing we'll discuss is pure blackbox testing.  Anyone that has performed a blackbox mobile application assessment against a compiled application has likely encountered scenarios that made testing extremely difficult.   Funky encoding formats, proprietary protocols, and other issues to deal with can consume a considerable amount of time (billable time) while assessing an application.  

While this may be acceptable for an attacker (with unlimited time), in a time-boxed assessment this can eat into the amount of time spent looking for real security issues.  Issues that may be trivial to detect with enough time can be overlooked in a pure blackbox scenario simply because the consultant ran out of time at the end of the engagement.

In a whitebox scenario, the security tester has complete access to the original source code.  With source code for the client-side app, a security tester can execute and debug the app within an IDE.  The application still runs on an actual device or emulator/simulator, but the application's flow of execution can be tightly controlled through the IDE.   Methodically debugging in Eclipse or Xcode is much more efficient than other methods of testing.  Having the luxury to set breakpoints at key areas within the application can give a skilled tester the ability to do magical things. 

In addition to being able to quickly and accurately validate issues on the client, a security tester can easily deal with issues like custom encoding or proprietary transmission protocols by hooking in methods to fuzz the application when source code is provided.  This makes testing the mobile app itself much easier, as well as testing remote services.  Increased efficiency = your money is best utilized looking for security problems and offering solid remediation guidance.

When we scope mobile assessments for our clients, we explain the pros and cons of each approach.  We've found that upon giving a detailed explanation of both approaches and setting realistic expectations upfront, clients favor efficiency and a more comprehensive review.  Security by obscurity has never worked, and will never work.     

Thursday, May 26, 2011

Revisiting Android TapJacking

Resources:


Although we probably didn't need another *jacking vulnerabillity, TapJacking is a relatively easy vulnerability for a malicious application to leverage in Android prior to version 2.3 (Gingerbread).  To be clear, we did not discover this attack vector.  For the initial disclosure and a good writeup, please reference the Lookout Blog.  We are revisiting this issue to raise awareness and provide developers with a friendly reminder that they are still on the hook to defend against this in their applications.  Although 2.3 provides the ability to protect against this, it is not enabled by default.

What TapJacking allows a malicious application to do is overlay the Activity at the top of the stack with another object (ie- Toast) that passes touch events through to the Activity.  The result is that the user has no clue what they are really clicking on or typing into because it is hidden from view yet still accessible.  So while a user may be tapping to install new paid applications, transferring funds, or dialing expensive numbers overseas, they are still happily clicking away at whatever they see.  The illustration below demonstrates how a Toast object would overlay an Activity:



We wrote a proof of concept application that you can install to your phone or Android virtual device in order to see how the attack works.  You can find it in the Android Market (https://market.android.com/details?id=com.nvisium.tapjacking).  The proof of concept application can also be used to perform security testing to ensure your anti-TapJacking defenses are working properly.  You can download it directly to your phone from the Android Market , or you can pull down the Eclipse project from GitHub and build it yourself (https://github.com/nVisiumSecurity/TapJacking-Demo). You can easily modify this application to test it against your own applications by modifying the package and class names that are launched by the background services.  You can also modify the offsets within the layouts to determine where icons and buttons will be placed within the Toast overlay.

Another interesting thing to take note of is the fact that our sample application requires zero permissions.  Permissions in Android get a lot of attention, and therefore we've begun to train our users to make some of their security decisions based on the types of permissions an application requests.  If a wallpaper application requests SEND_SMS, CALL_PHONE, ACCESS_COARSE_LOCATION, and other sensitive rights, it will hopefully make someone very suspicious.  However, a wallpaper application that makes use of TapJacking could fly a bit further under the radar.  The applications that are being granted the sensitive rights could be installed silently in the background instead, achieving the same effect and with less risk of detection.

The good news: there is a relatively simple fix: in the 2.3 SDK and above, subclasses of the View class inherit the setFilterTouchesWhenObscured method.  You set this on your View derived object and it prevents interaction when something else is on top of it.  This can be called either through code or declared within your resource and layout XML files.  Any sensitive functionality such as purchasing, account modification, or changing a user's settings should be protected.  So assuming you create a button within a layout file instead of within code, you would create it like so:


<Button android:text="Button" 
android:id="@+id/button1"
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:filterTouchesWhenObscured="true">
</Button>

That's  it.  Simple.  Easy.  Even though your Activity may be at the top of the stack, if there is anything obscuring it from view Android will disallow interaction with it.  For most applications, this should not be an issue.

The bad news: this is not enabled by default (as it hopefully will be at some point).  It also means your users with pre-2.3 devices aren't protected, either.  According to Google's own numbers (http://developer.android.com/resources/dashboard/platform-versions.html), close to 96% of the Android ecosystem is still using 2.2 and below.  Since many older phones are no longer receiving updates and will never see an official Gingerbread release, this issue will be around for a while.  So it's up to developers to implement this on their own.  Hopefully as a larger percentage of devices begin to use 2.3, Google will consider enabling this by default.

From the people we've talked to that specialize in mobile malware and forensics, this technique has not been used much in the wild.  However, as Android malware continues to grow at an alarming pace, it is only a matter of time before we may see this used.  Combine that with a growing number of applications using in-app billing, and the use cases expand even more.  We also hope that Google will begin to make use of their own security features in future releases of their own packages, such as settings, dialer, and market applications. 





Friday, May 20, 2011

Exploitable Mobile App Challenge- Submission Period Extended!

We are extending the submission period for the Exploitable Mobile App Challenge for an extra month. The new deadline to get your applications submitted is July 1, 2011. Don't wait until the last minute if you haven't already started on an app!

For the scoop on the competition, please refer to our initial blog entry: http://blog.nvisiumsecurity.com/2011/04/exploitable-mobile-app-challenge-now.html

Several interesting applications have been submitted, but based on feedback the submission period was simply not long enough. Please spread the word and encourage your fellow developers to kick in a few spare cycles to create an application. This campaign is intended to increase mobile application security awareness and visibility.

Not to mention, we are giving away some pretty great things for free like a iPad 2 and Motorola Xoom.