Tuesday, July 23, 2013

Cisco ACS Local PAC File Write Redirect

By Brad Antoniewicz.

A couple months ago I came across a sort of interesting bug in the CSUtil.exe. I'd say the overall severity of the vulnerability is pretty low, but I'm wondering if anyone can think of creative ways to exploit it. In this post I'll describe the vulnerability and if you can think of a cool way to exploit it, let me know in the comments below.

CSUtil.exe

CSUtil.exe is a command line utility included within Cisco ACS for Windows. It can preform a variety of functions to parse data from the ACS database and is often used to manually backup the database. It's most commonly invoked by a user with appropriate administrator level rights and output files are stored by default within the directory from which the utility was ran.

File Write Redirect

The vulnerability is introduced when issuing the "-t" option which retrieves a local user's PAC and writes it to a file. During the export process, CSUtil.exe writes a string to a temporary file, tmpUserFileName.txt, then later uses that string as the file name to write the PAC file to. If someone else writes an alternate string to the tmpUserFileName.txt after CSUtil.exe has written the initial string, it's possible to redirect the location in which the PAC file gets written to.

This is demonstrated in the following Video:



Some important notes to mention:

  • tmpUserFileName.txt is written to the same directory where the tool was run from and thus the attacker must have appropriate permissions to write to files within that directory
  • This attack appears to be very much timing related since the attacker would need to overwrite the tmpUserFileName.txt file contents after CSUtil.exe is run but before it completes
  • It is possible to overwrite existing files at potentially arbitrary locations, but they must end in ".pac".

So... In my mind, this is a relatively low risk issue given all of the restrictions. What do you think? Can you make it a high?

Contacting Cisco

As always, I contacted Cisco and let them know of my findings - and as always they were really responsive and welcoming. This issue is being tracked under Cisco PSIRT Case PSIRT-0354447345 and Bug ID CSCug61874 if you want more info!

Tuesday, July 9, 2013

Quick Reversing - WebEx One-Click Password Storage

By Brad Antoniewicz.

Cisco's WebEx is a hugely popular platform for scheduling meetings. You can conduct video and voice calls, screen sharing, and chat through the system. Meetings are usually created via a Web Portal were the user defines when the meeting starts, how long it goes for, and what services (e.g. screen sharing or just voice) their meeting will leverage. WebEx also provides a One-Click Client that offers standalone meeting scheduling and outlook integration so that users can avoid the Web Portal.

The One-Click Client has the ability to save a user's password, so I decided to take a quick look at that functionality - in about an hour I was able to determine the storage, reverse the method it used to encrypt the password, and write a proof of concept tool to decrypt the local storage of the password. The aim of this blog post is to document that process and maybe encourage you to do some reversing!

Process Monitor

Usually the first step when evaluating client applications, is to get an understanding of what file system changes the application is performing (read/writes). This is especially true when you're looking for something thats being stored (in this case, the saved password) because stored info is usually written to a file, database, or within the Windows registry.

Process Monitor is one of those core tools that everyone should have handy and is perfect for this use case.

At this point in the process, we'll focus on One-Click's ptInst.exe executable. It's run during the initial install for One-Click and asks the user for username/password/server URL and if the application should save the password. With ptInst.exe running, we can launch Process Monitor.

First step is to create filter for the executable to reduce getting overwhelmed with information from other processes. Remove all existing filters and then create one to include all processes whose name is "ptinst.exe":



Next up, provide the application a username, password and URL, and tell it to save the password. As soon as the login button is clicked, Process Monitor will show a ton of activity. The first thing that catches my eye is that there are a bunch of writes to the resp.xml XML file.



It's common for applications to store configuration information in an XML file, so maybe we'll get lucky with this one.



resp.xml does contain lots of data, but unfortunately there are 6 stars in place of the actual password (password length is greater than 6, fwiw). So back to Process Monitor.

Next thing that may catch your eye is a number of queries to the Registry. It's very common to see application using the registry to store various information. These queries are particularly interesting because they contain the word "Password":



This is a pretty good indication that the password and password length are stored in the registry. To confirm, check the registry keys themselves. It turns out that the HKCU\Software\WebEx\ProdTools\Password key stores some hex value that isn't the cleartext password, and HKCU\Software\WebEx\ProdTools\PasswordLen contains the length of password.

At this point, we need to determine what the value of HKCU\Software\WebEx\ProdTools\Password is. It's probably the password, but somehow obfuscated or encrypted and deciphering isn't obvious.

IDA Pro

IDA Pro is another core tool. It's really the defacto tool for reverse engineering. Freeware and Evaluation versions are available and should be completely capable if you're following along (although I am using the paid version).

Strings

Programs often contain constant string values to be used when performing certain functions. For instance, ptInst.exe will likely always use the same registry keys (e.g. HKCU\Software\WebEx\ProdTools\Password), so those actual strings should be stored somewhere within the binary. There are a number of programs that allow you to search for strings within a binary, we'll use IDA (View - Open SubViews - Strings):



If you search through the string list, you'll notice the registry key names aren't there. This is because by default, IDA will only show zero terminated ASCII C strings. We'll learn a little lower that our strings are passed to a Unicode Windows API function.

To show Unicode strings within IDA, right click the Strings tab and go to "Setup". Next select "Unicode" under "Allowed String Types":



Scrolling through the Strings Window a second time will reveal the unicode encoded key name we're looking for: "Password". Double clicking it will open IDA View-A and bring us to the data segment in the binary where the string is located. You'll notice that right above the unicode entry, at the same address, IDA automatically gave this location a variable name, "aPassword".



By selecting "aPassword" and pressing the "x" key, you'll see all of the cross references to that variable name - This is everywhere its used in the program.



We just need to find where the registry key is either set or read and we'll likely see a call to some function nearby that decrypts it. The second reference, sub_34161C+1EB looks to be setting the value since a few instructions after the reference, a call to RegSetValueExW() is made.



RegSetValueEx()

An observation to make is that the program is calling RegSetValueExW(). The "W" stands for "wide" which indicates the program is using the Unicode version of the RegSetValueEx() API function. This speaks to why we needed to configure our Strings Window to show Unicode strings. Had the function been RegSetValueExA(), we'd be using the ANSI version.

If we look at the RegSetValueEx() MSDN Page we see that the fifth value passed to the function is a pointer to the data which is to be stored within the registry key. IDA helps us out a bit by showing the same data types for each of the values being pushed onto the stack as the MSDN entry. Looking at the fifth value pushed onto the stack (working backwards from the call to RegSetValueExW()), we see lpData, which is stored within the EAX register. It's value is loaded into that register by the prodceeding call, where we find its actually the value [ebp+428h+var_428]. If we highlight that, then look at the previous references we'll discover that this value is always used above as the destination in an earlier call to memcpy().



So this means that it's likely the value being set for Password registry key is the result of the memcpy(). We'll need to realign our trace to follow the source variable of that memcpy() if we want to figure out how our saved password is stored.

To the Source

If we highlight the Src to the memcpy(), or [ebp+428h+Src], we'll see its used above and pushed onto the stack:



The function call after a bunch of pushes is to sub_3412bb. If we look at it, its a pretty simple function and doesn't really alter the stack :



This means our Src is still on the stack and may be used by the following function call to the CryptoData() exported function. CryptoData() sets up a stack frame and then does a quick jump to sub_342332:



Function sub_342332 starts to look interesting. First up, it has a bunch of arguments, this means that just by eyeing it up, we can guess that our Src will likely be used. If we count the number of elements pushed onto the stack, then look at the number of arguments IDA identified in the function, we could get an idea:



Looks like they all line up. Also make note of the cmp [ebp+arg_1c], 0. We can clearly see that the calling function sets that to 1, so we know that we'll be taking the negative branch on the jz below.

Keys!

The negative branch brings us to sub_34227b which looks like gold. From a quick overview, we see that there is some constant value being loaded into an array or structure:



And then there are calls to AES_set_encrypt_key() and AES_ofb128_encrypt().A quick search will reveal both of these functions are part of the OpenSSL libraries. What's even better is that someone else has already implemented these functions in an open project. For whatever reason the OpenSSL documentation doesn't have full coverage of both of these functions, so this project helps to reduce the effort in guessing what the higher level code looks like and ultimately what's needed to reimplement it.

AES_set_encrypt_key

First up I wanted to identify what values were being passed to AES_set_encrpyt_key(). I knew its arguments were something like:

 AES_set_encrypt_key (const unsigned char *someKey, const int size, AES_KEY *keyCTX)



To make life easier, I used WinDBG, set a breakpoint on the call, and inspected the memory at that location. What I discovered is that the key being used was a combination of these two registry keys:

  • HKEY_CURRENT_USER\Software\WebEx\ProdTools\UserName
  • HKEY_CURRENT_USER\Software\WebEx\ProdTools\SiteName


For UserName I had braanton and for SiteName I had siteaa.webex.com/siteaa. When looking at WinDBG, the value being passed to AES_set_encrpyt_key() was:

 braantonsiteaa.webex.com/siteaab



Which led me to believe the key was essentially the UserName value concantenated with the SiteName and repeated until it filled 32 characters (which accounts for the trailing "b").

AES_ofb128_encrypt

A little searching revealed the arguments for AES_ofb128_encrypt should be something like:

 AES_ofb128_encrypt(*in, *out, length, *key, *ivec, *num);



This is where that big constant value comes in. If you look at it fully assembled, you'll find that it is:

 123456789abcdef03456789abcdef012



This gives us everything we need to encrypt the password, our psuedocode for the assembly in sub_34227b would look something like:

 IV = 123456789abcdef03456789abcdef012;
password = "some value";
key = [UserName + SiteName repeated to 32 chars];
num=0;

AES_KEY keyCTX;

AES_set_encrypt_key (key, 256, &keyCTX);

AES_ofb128_encrypt(password, out, sizeof(password), &keyCTX, IV, &num);



Decrypting

AES_ofb128_encrypt() uses output feedback (OFB) which makes the decryption process nearly identical to the encryption process. All we have to do is provide the encrypted value (i.e. the one stored in the Password key) with the appropriate length (i.e. the one stored in the PasswordLen key) and we'll be able to decrypt it. This all comes down to the static IV and UserName/SiteNamekey values. To demonstrate this, I wrote the following Proof of Concept code:



You'll need to edit the source and manually define the appropriate values for regVal and key then just compile and run:

 brad@wee:~/onedecrypt$ gcc -o webex-onedecrypt -lssl webex-onedecrypt.c
brad@wee:~/onedecrypt$ ./webex-onedecrypt
Reg Key Value = cc 6d c9 3b a0 cc 4c 76 55 c9 3b 9f
Password = bradbradbrad



Contacting Cisco

As always, I contacted Cisco and let them know of my findings - and as always they were really responsive and welcoming. This issue is being tracked under Cisco PSIRT Case PSIRT-0219916903 and Bug ID CSCuh73132 if you want more info!


Hope you liked this, if so - Follow me on twitter - @brad_anton

Tuesday, July 2, 2013

Potential attack vectors against Z-Wave®

By Robert Portvliet.

A couple years ago I was doing some research on Z-Wave, and after sifting through what was publicly available regarding the protocol I came up with some ideas as to how it might be attacked. My colleague Neelay Shah and I even worked on some code for it. However, at the time I concluded that I needed a USRP to make forward progress into writing a tool that could sniff Z-WAVE traffic, which was/is pretty important for a number of attacks. Not wanting to drop the $ at the time, I just shelved what I had for the moment, and figured I’d get back to it later. Well, you know how that goes, so here we are two years later and I’m likely not going to get around to it. Plus there seems to be a Blackhat talk on it this year, so I’m just going to dump what I have in this blog post, and if anyone finds it useful, so be it :)

For those not familiar with it, Z-Wave is a short range wireless protocol, which operates in the 900MHz ISM band (in the US), and is most commonly used for home automation. It is also supported by a number of alarm system and lock manufacturers. What follows is more or less a summary of what I was able to find publicly available regarding Z-WAVE, and what attacks might be possible against the protocol.

Background

When I began searching the internet for information on the protocol, I discovered that it seemed very little public security research had been done regarding Z-Wave. Even since then, the only research released is what Dave Kennedy and Rob Simon included in their Defcon 19 presentation.

There does however, exist a fairly active community of home automation hobbyists who have reversed engineered portions of the protocol, primarily using serial sniffers. These enthusiasts have compiled a fairly large amount of data on the protocol through this reversing, and also from documents published by various vendors that detail parts of the protocol as it pertains to their specific products. There is also some Zensys documentation available on these sites such as the Z-Wave module selection guide, the Z-Wave protocol overview, and the Z-Wave node type overview and network installation guide. These hobbyists also publish a rather steady stream of blog posts and tutorials on how to write code that will allow one to interact with Z-Wave controllers and devices. Some of the best are available here:



One of the most useful things developed by the home automation community is an open source C++ library called OpenZ-Wave. Its associated Google Group is very active, and a good place to do research & ask questions. There was also another project which began to develop a Python wrapper known as Py-OpenZ-Wave with the goal of even further simplifying developing Z-Wave projects. Unfortunately, it seems that the Py-OpenZwave project hasn’t gotten very far since that time, but it’s a good idea nonetheless.

Utilizing this information it is possible to quickly gain a fairly decent understanding of the protocol and how its various components interoperate. A detailed description of the protocol is outside the scope of this post, but one of the best descriptions of the protocol publicly available can be found in the paper Catching the Z-Wave, by Mikhail Galeev. Also, as previously mentioned, the Z-Wave protocol docs are easily found on the internet. However, it should be noted that all of this documentation is from v4 (400) of the protocol and as such is slightly dated, but is still exceptionally useful.

Hardware

There are a couple hardware items worth having to start off with. I was using a AEON Labs Z-Stick 2, which is ~ $40. There is also the AEON Labs Z-Stick Lite, but it’s not flash able and appears to be the same price as the regular Z-Stick now.

The other interesting piece of hardware is the Razberry Pi, which is a Z-Wave® ZM3102 Module for the Raspberry Pi. However, the downside is the Z-Way software it comes with is closed source, so you are limited what you can do with the API provided to you.(Unless you reverse their binaries of course… ) There is some doc available here. You can grab the Z-Way bundle here

A USRP would be a huge help if you don’t mind spending the coin. In truth the bus series would probably do the job at ~ $600 + cost of the daughter board. I’m waiting for the HackRF (frequency range 30 MHz to 6 GHz) to be publicly available. It will likely be a big help for stuff that like this. The BladeRF (300MHz - 3.8GHz RF frequency range) doesn’t look bad either. It appears that some folks have been playing around with Z-Wave with the RTL-SDR, which is great for RX only, but has no ability to transmit.

Potential Attack Vectors

Ok, so enough of that. Here is what I came up with in terms of potential attack vectors.

Sniffing Z-Wave traffic

The first and obvious vector that came to mind was to sniff the Z-Wave network traffic in order to discover the HomeID, NodeID’s and other information about the network. This would be the easiest way to attack a network and could be done from a distance with a high gain 900mhz antenna. Unfortunately, no open source sniffers have yet been developed by the community.

Sigma sells a sniffer called the ‘Zniffer’ as part of their Z-Wave® Home Control Development Kit for about $3000 or so. However, you have to sign an NDA if you buy their devkit. Copies of their SDK, which include the firmware for the sniffer module, have made it into the wild, but you will still need the hardware to flash it to (and most likely a programmer). Still, it would be easier to design a sniffer by reversing the current firmware I suppose..

I was also able to locate a Lagotech HIP-22 sniffer for sale on EBay, and you can actually purchase it from a few places for ~ $150 but it also requires the Lagotek ‘HIT’ software to function.

As stated previously, a USRP and GNU-Radio could be used to develop a sniffer as well. This would require figuring out the protocol from the ground up, and there’s something of a learning curve to GNU-Radio, but if you’re already a software radio guy you’re ahead of the game in that area. The RTL-SDR is another possibility, but its RX only so you won’t be able to inject any packets. Again, I’m hoping to get my paws on a HackRF in the not too distant future, which I’m hoping will bridge the gap here.

Unpairing nodes from the network

An attack vector that I was investigating was the ability to unpair nodes from the network from a distance as a denial of service attack. However, the problem with unpairing a node from the network is it requires the action to be initiated from both ends. This is commonly accomplished by pressing a button on the node in question and on the remote or the primary controller. An attacker would also need to utilize a high gain 900mhz antenna as pairing is done using very low power, requiring the devices being paired to be within a proximity of 3' to one other. There is also full power inclusion which works with devices that support it, but that only has a range of 20' (unobstructed) so the attacker would still require a high gain antenna. It may be possible to spoof the unpairing frames to the node, making them appear to come from the Z-Wave controller, but this still would not solve the problem of placing the node in the proper ‘listening’ state necessary to unpair it from the network. As stated previously, this has to be initiated on the node itself, making this attack largely impractical.

Attacking and unlocking door locks:

A rather desirable attack would to find a way to cause a Z-Wave enabled door lock to open by sending it unauthorized traffic containing a command to unlock. What makes this a difficult attack is that door locks, like those made by Schlage, utilize the encryption command class in Z-Wave which employs AES128, and are also supposedly using a onetime value for each frame sent to/from the door lock. However, they do have a weakness that an attacker may be able to exploit, but it requires a sniffer and for the attacker to be present when the locks are being added to the Z-Wave network. The locks perform a key exchange with the controller when they join the network and if an attacker were to be there with a sniffer when this takes place they may be able to intercept this key and use it to encrypt\decrypt traffic. This window is obviously very narrow, but might be able to be abused by a home automation installer with malicious intent.

Denial of service attacks

An attack that is almost always possible when dealing with wireless communications of any sort is denial of service via jamming. Jamming is accomplished by transmitting a steady stream of ‘noise’ on the same frequency as the intended victim. Z-Wave operates in the 900mhz spectrum and a quick Google search reveals several 900mhz jammers commercially available for only a few hundred dollars, or you could build your own. The manufacturers claim about 30 meters effective range, but this could be increased dramatically using an amplifier. This attack would not require any knowledge of the target Z-Wave network other than its general location and could be sustained indefinitely.

Brute-forcing the HomeID

After reviewing all the possible attack vectors and taking into account the feasibility of each, as well as the time necessary to implement them, I decided the most practical plan of attack would be to write a tool that would brute force the HomeID. The 32bit HomeID value is required to send and receive traffic to a specific Z-Wave network. The idea would be to write a bit of code that that would iterate through this value and for each iteration send a single frame to a NodeID on the network likely to exist, such as NodeID 0x02, and then listen a few milliseconds for an acknowledgment frame (ACK).

My colleague Neelay Shah offered to write the code, and we utilized information regarding how to craft and send Z-Wave frames from http://www.digiwave.dk/en/programming/the-z-wave-protocol-in-csharp/, as well as sample code provided by same, to help craft the tool which would perform the attack. This sample code was modified and then integrated with our code that would iterate through the 32bit HomeID which comprises the first four bytes of the Z-Wave frame. This code was tested and found to be functional, but unfortunately had one oversight that proved difficult to address. The oversight was that the HomeID cannot be changed in the Z-Wave frame to be a value different from the value of the HomeID set in the EEPROM on the Z-Wave dongle. If this occurs, the driver does not know how to handle it and will not send the frame. At first glance this seems like a fairly easy challenge to surmount, simply update the value in the EEPROM as well. The problem with this approach is that there are 4.3 billion possible values in the 32bit HomeID and an EEPROM will only take about one million writes (or less, depending upon quality), before it wears out, long before the correct value for the HomeID would be discovered. A possible solution to this problem would be to investigate if the HomeID value could be modified in memory instead, but it also seems to not be possible to modify the HomeID in memory when using a Z-Wave dongle. So, the most practical way to approach this attack appears to once again be to use SDR to create the tools that provide the functionality necessary to perform the attack.

If one were to implement this attack utilizing SDR, there still remains the issue of brute forcing 4.3 billion possible values, which could potentially take hundreds of hours. However, there exists the possibility of enhancing this attack by narrowing down the number of values an attacker would need to iterate through. Manufacturers such as Motorola are allocated unique blocks of HomeIDs by Sigma. If these HomeIDs are allocated in sequential order and one was able to collect the HomeIDs from several devices made by that particular manufacturer, it may be possible to narrow the values needing to be brute forced to a few million, which would take far less time to attack.

I am including the code that Neelay wrote for the HomeID brute forcing. As I said, it’s not really effective unfortunately, but I’m including it in case it is useful to anyone.



Additional Resources