Category Archives: Penetration Test

Back at the beginning of 2012 I played around with some Python ctypes as part of a project I was working on in the background. At the time I released a few code snippets that used ctypes to do a few fun things, but never really got around to releasing the main project I was working on.

The main project I was working on was a simple Python script that injects shellcode into a running process using CreateRemoteThread (nothing brand new here). The interesting part of the project (for me anyway) was the ability for the Python script to request the shellcode to inject using DNS TXT requests, ICMP request/responses or simple HTTP(S) request (using SSPI if required). I demo’d the code at the BSides London conference in 2012 at the underground / lightning talks an had some positive feedback, however the time just hasn’t been there to finish things off since then.

As a result of the lack of time to finish things off, I’ve put up the latest modular version of PySC (version 0.8) on Github for people to use, tear apart , and generally laugh at as you see fit. As the project is still in prototype your mileage may vary.

PySC was designed to be configured using the config.py file present in /config directory, and run headless on a Windows system after being packed into an executable using something like PyInstaller. However you can run it using command line options as well by running it with -h to see the various options.

The /optional directory also includes some example server-side implementations for Metasploit and a Python Scapy ICMP listener for delivering Shellcode to the PySC client.

PySC expands on the numerous available tools and scripts to inject into a process on a
running system.

Aims of this project:

– Remove shellcode from the script to help avoid detection by AV and HIPS systems
– Offer a flexible command line based script
– Also provide the ability to run fully automated, as an EXE (by using pyinstaller)

To this end this prototype script offers the ability to download shellcode from a
remote DNS server (using TXT records) or through Internet Explorer (using SSPI to
utilize system-wide proxy settings and authorization tokens) and injects it into a
specified process. If injection into the specified process is not possible, the script
falls back to injecting into the current process.

Module dependancies: none

Notes:

PySC will by default run silent (no user feedback) to enable user
feedback (error/status messages) please use debug mode (-d/–debug
at command-line, or set debug = True in the script itself)

Any command-line options passed to PySC at runtime override the
hard-coded values within the script.

To use PySC as a stand-alone executable, set the desired parameters
in the script itself, and use pyinstaller to create an .exe

It’s been a bit quiet here on the blog, so I thought I’d take a few minutes to write up an issue I raised with the fine folks over at LastPass .

Alongside the HTTP Response Code stuff, I’ve been playing around more and more with Android applications. One of the things I presented on in Vegas at the BSidesLV Underground track was breaking into Android Secure Containers. The name of the talk was cryptic for sure, mostly because said “secure” containers were anything but secure, and because I hadn’t had time to report the issues to the effected vendors. The issues I discussed weren’t tied to a single application, and effect numerous apps within the Play Store…
So, here we are a month later, and LastPass has rolled out a “fix” for the issue I reported to them. This means I can give you the down and dirty details now that you’ve all updated your Android devices to the latest LastPass version (currently 2.5.1). FYI: the CVE numbers for these issues although not referenced in the LastPass changelogs as yet are CVE-2013-5113 and CVE-2013-5114.

This research needs a little back story to explain it, so bear with me for a minute while I set the stage.

Back Story / Testing Scenario

I started down this research track when I was looking at how Android applications provide additional security through PIN and/or password protection of specific applications. This additional layer of security offered by applications like LastPass is there to stop people who have physical access to your Android device from getting into the more secure areas of your data (e.g. Passwords). With this in mind I expected the implementation of these protections to be designed to stand up to an attacker with physical access to the device (aka. somebody who’s stolen/borrowed/found your Android device).

Some Facts

Without root access to the android device, it’s not directly possible to view or alter the data of specific applications. Even if USB Debugging is enabled (by the owner, or later by an attacker with device access) it’s only possible to view specific data on the Android device, not all the juicy stuff. Everything I’m about to discuss is possible based on a non-rooted device, however USB debugging needs to be enabled to allow us to interact with the device using adb. Remember, the scenario we’re talking about here is physical device access, so this shouldn’t be a big hurdle.

Note: It goes without saying that everything that can be achieved here with ADB /USB Debugging can also be achieved through exploitation of the device… although, there are much more fun things to do if you’re popping shell on a device ;)

The LastPass Case

LastPass allows a user to save their password within the Android application so that you don’t need to type it every time you open the app. This isn’t abnormal for applications, and like any good security minded application they give you options to secure the access using something other than your long long password (aka… the PIN).

Given my experience, users of such applications have too much faith in the security of their devices and have no desire to type in their 32 character random LastPass password whenever they open the application (have you tried that on a handheld device? Yhea, not fun…). Much better to store the password in the secure container settings and assign a PIN to protect the app (because that’s secure!).

So with the back story and the explanation out the way, here’s the meat of the issue

The Meat

When I first started testing LastPass on the Android (version 2.0.4 at the time) I noticed something interesting about the AndroidManifest. In particular the android:allBackup was set to True, meaning that even though I couldn’t read or edit the configuration/settings of LastPass directly on the device (remember, non-rooted device) or via ADB (remember, USB debugging enabled, but even then no direct access), I could perform backup and restore operations via ADB.

This led me down the trail of learning more about the “adb backup” command (introduced in Android ICS). What makes adb backup and restore so useful in this context, is the ability to not only backup a device entirely over USB, but also to specifically backup individual application data (with or without the APK file). This makes the backup and restore much more flexible for what we’re looking at doing. After all, backing up an entire 16GB device every time gets tiring (I’m looking at you iOS).

By performing an adb backup (command: adb backup com.lastpass.lpandroid -apk) and accepting the prompt on the device, you end up with a backup.ab file containing the LastPass application (APK) and the data/configuration/settings from the application. There have been numerous discussions on the format used by Android Backup files, but I wasn’t happy with any of the solutions offered to decrypt the AB files into something usable. So I decided to automate the lengthy process in Python (see http://blog.c22.cc/2013/08/01/bsideslv-android-backup-unpacker-release/) and add in some features to ease things a little.

The final result is a directory output of the LastPass application (with or without the APK – your choice – screenshot is without APK).

Taking a look at the files the sp/LPandroid.xml quickly stood out as worth further analysis. As expected the configuration file contained the username and password in encoded format (if saved within the LastPass app). Alongside this the XML also contains an encoded version of the PIN and various other application settings. Putting aside the possibility to decode the password and PIN, a few settings caught my eye for easy wins:

reprompt_tries

This is a simple integar that increases as incorrect PINs are entered

passwordrepromptonactive

pincodeforreprompt (holds encoded PIN)

requirepin

These control the password reprompt on startup and the PIN protection (yeah, you can see where this is going already)

The Story So Far

We have access to the LastPass configuration of a non-rooted device via adb backup… and we can fiddle with the resulting configuration file. However we’re still playing about with the XML inside a backup and not with the device itself. We need to get the changes back into the device

Next Step

Using more Python trickery goodness (seehttp://blog.c22.cc/2013/08/01/bsideslv-android-backup-unpacker-release/) we can take the directory structure created and rebuild the Android Backup file (with the changes that we’ve made to the files of course). Then we can restore the backup to the device (if you still have access to it) or to your own device/emulator (make sure you have the APK in the backup file or the app already installed if you want to restore to another device).

Effects

As expected, playing with the reprompt_tries by setting it to a minus number (-9999 for example) allows you to bypass the 5 PIN attempts before wipe feature of LastPass. This essentially gives you 10,000 retries. If you can’t guess a 4 digit PIN in 10,000 retries, then nothing can help you :P

However, the easier and more fun option is the pincodeforreprompt / passwordrepromptonactive and requirepin alteration which results in the LastPass application not requiring a PIN for entry anymore.

Backup configuration and unpack

Alter XML settings as required

Pack configuration and restore

<<< Profit >>>

After-effects

Some of the more eagle eyed amongst you may have already noticed another interesting attack vector here. The ability to backup LastPass from a device (within 30 seconds if you’re handy ;) and return the device to the owner, coupled with the freedom to restore said backup to an attacker controlled device, makes the attack much more interesting. Not only can you do this, bypass the PIN in your own time, and then read and extract the stored passwords as desired. You can also maintain access to the users LastPass account until such time as they change their LastPass password itself.

If the original owner alters their any of the passwords their store in the LastPass service, the attacker can simply close and restart the cloned Android container to update the information from LastPass’ servers.

Note: Version 2.5.1 mentions an alteration in the way LastPass creates UUIDs. This may effect this cloning attack – as yet unconfirmed

Round 2 – It’s not over yet

You may have noticed the use of quotes around “fix” at the beginning of this post… After LastPass got back to me to say they’d fixed the issue (actually they responded to say they’d fixed it the day before I reported it as they’d disabled allowBackup and not pushed it to the Play Store yet), I started looking at the proposed fix and possible bypasses based on the same physical access scenario. After a few false starts I have a working bypass for their fix that once again allows the attack (with an additional step). Once they’ve fixed the fix, I’ll let you guys know how that one went down ;)

Until then, make sure you upgrade your Lastpass to the latest Play Store version (2.5.1 at this time) and keep an eye out for further fixes!

Much like everybody else, I was really looking forward to the new Burp 1.5 professional release and the new Extensions… now that there’s some API documentation and example code out their, I had a little play to see what was possible.

As I had limited time, I played a little with the IScannerListener API to get a feel for things. Although the API is still in draft, there are lots of things in place and it’s definitely more than usable in most situations. There are still some points I’d like to see improved in newer releases (or explained better), but for a .01 release I’m already in love with the possibilities Hopefully I’ll have some time to rewrite the UAtester tool to work as a Burp Extension of the next few months.

Until then, I’ve thrown together a quick (very quick) extension to display newly discovered scanner findings in the output console. Nothing you can’t already do, but useful to have open in an external window as you browse a site or run manual tests.

Yeah… ASCII art is old skool cool ;)

The current script will output new findings on anything you have in-scope. The script will automatically skip displaying findings types that have already been displayed for the host (to avoid flooding the output with the same findings again and again). you can alter this setting and set it to work on all hosts (not just in-scope) within the .py file itself.

As I said, this is only something I was playing with… but still, let me know what you think ;)

Some months bask I asked people to help me test out a printer MITM modules I was working on for Metasploit. Well the good news is, I finally managed to get things working (mostly) and the module was accepted into Metasploit trunk a few months back (yeah, I’ve been slacking recently on updating the blog, sorry).

Currently it supports RAW and LPR (IPP proved a pain in the… well, you know what. I’m hoping to implement this in a future revision however.)

Feel free to try it out and let me know what you think… More information can be found HERE

Links

Disclaimer

The contents of this personal blog are solely my own opinions and comments, as such they do not reflect the opinions of my employer(s) past, present or future. No legal liability is accepted for anything you do, think, or consider fact as the basis of articles and links posted on this blog.

"Three to one...two...one...probability factor of one to one...we have normality, I repeat we have normality. Anything you still can’t cope with is therefore your own problem."

Note: A large portion of content I post on my blog comes from "live blogging" of security conferences. These posts are in notes form and are written live during a talk. As such errors and emissions are expected. I'm only human after all!