Tuesday, 27 December 2011

Introducing VirtualAlloc_s - A Potentially SDL Friendly Version of VirtualAlloc

As a follow on from our previous post on VirtualAlloc and the lack of randomization, and inspired by what the Chromium team did in their OS::Allocate function, we decided to sit down and write our version of VirtualAlloc_s. At which point it is only polite and fair to also give and tip of the hat and acknowledge Didier Stevens' work published in August and September 2011. Dider's work documented the EMET randomization [1][2][3] and his pseudo Address Space Layout Randomisation (ASLR) implementation.

Our VirtualAlloc_s and VirtualAllocEx_s functions are similar to the other Microsoft _s named safe versions of otherwise unsafe functions. The implementations are contained in a single header file and are designed as drop in replacements for any existing calls to VirtualAlloc or VirtualAllocEx.

At a high-level the implementation tries to randomize the address requested from VirtualAlloc (if the developer has not explicitly requested one). If the allocation fails due to say being an invalid address or already being allocated the implementation then falls back to using VirtualAlloc as-is, but alternating (after a random number of executions) between bottom-up or top-down allocations. This feature has the benefit of being guaranteed to work whilst also adding some unpredictability. In addition, we think that this behaviour is a very slight improvement over Google's solution to the problem. The finer details of the implementation are described below.

On the first call to VirtualAlloc_s or VirtualAllocEx_s the implementation initializes itself. This initialization includes seeding rand with the current PID, number of ticks and available RAM, randomly selecting the number of executions (between 1 and 3) that it'll switch between bottom-up and top-down allocations in the fall back scenario and finally selecting if it'll start in bottom-up or top-down fall backup mode. It also performs one low and one high allocation of the size requested by the user. These additional allocations are designed to add a bit more entropy to the fall back scenario. Once initialized and on each subsequent call the implementation generates a random address, attempts to allocate the address and if the allocation fails, falls back to the safe mode described previously.

We've tested the implementation using a number of unit tests. These tests have been in terms of performance overhead, thread safety, unique addresses and bias to specific addresses. Performance wise no noticeable overhead was observed in our unit test cases.

During an extended run (exceeding 110,000 iterations of the unit test cases on Windows 7 as a 32bit process) we recorded 2,048 different addresses being allocated. With regards to distribution while not perfectly uniform we did generally observe a good distribution across the address space as shown below:

Click image for a larger version
A similar run (exceeding 160,000 unit test cases on Windows 7 as a 64bit process) we observed 4,093 different addresses being allocated. Once again, the distribution it is not perfectly uniform. However, from a subjective perspective a good distribution was observed across the address space.

Click image for a larger version
Our proof of concept implementation is compatible with both 32 and 64bit platforms and is thread safe. However, we make no warranties implied or otherwise, that by using our implementation you won't run into issues, will actually gain any extra security or won't inadvertently introduce new security issues (the lawyers wrote that bit).

For developers looking to use the implementation it should simply be a case of search and replace for existing calls to VirtualAlloc/VirtualAllocEx. However, also keep in mind any static libraries or DLLs that your code uses won't benefit unless rebuilt to also use the new header. If you don't have the code to these components you'll need to work with your technology provider to get them to adopt it.

We've made all the code and materials associated with the implementation and testing available for download and additional peer review:
If you spot any mistakes or have any other feedback please feel free to get in touch with us

Finally with regards to license, as we did borrow (copy) some of the Google V8 teams code the implementation falls under the BSD license, so pretty much usable by anyone; but please check to make sure it's compatible with your current policies and licensing.

Wednesday, 21 December 2011

Breaking the Inevitable Niche/Vertical Technology Security Vulnerability Lifecycle

One of the observations we’ve made over the past fifteen years or so, is that things have only slightly improved with regard to new, niche or vertical specific technologies, security and the inevitable vulnerability lifecycle. When we say this, we mean niche and vertical software vendors achieving the utopia of building robust security throughout the development lifecycle to reduce, mitigate and sustain software security (aka an SDL).

Instead we live in a world where market forces almost dictate that security is taken seriously only once a product or market has matured or early exposure has been gained and come to the attention of researchers and/or regulators. While SDLs have become a hot-topic over the last ten years, the reality is organizations don't see security as a measure of quality but as a cost. So getting 'minimum viable product' to market due to time and market pressures is often still a reality, especially in markets where security hasn't hurt their business previously.

This might sound a ridiculous statement but bear with us. If we look at typically what happens with a new technology or market that successfully matures we see the following life-cycle:



The net result is that vendors don’t have an incentive to front load their investment in security; until they know their entry into an existing market with a product, or the establishment of new market is going to be a success. The reality is, if your products are not a success then it's unlikely that security researchers will look at your products (exceptions can exist) so you won’t be getting pressure from clients about security (other than maybe superficial marketing buzzword bingo requirements).

So this leads us to the inevitable vulnerability lifecycle for successful and initially less common or niche technologies:


If you think we’re just spinning a line, we've seen some really good examples over the past ten years or so. Essentially, it's a snowball effect. A technology piques the interest of a security researcher or academia (or a funded programme is created); time is invested and papers are released and presentations are given. This in turn raises the profile of the technology and it's weaknesses which increases the pressure on the technology/vendor.

Even technologies which are considered obscure or inaccessible over time will become the subject of scrutiny and security research. Independent researchers can obtain indirect funding for their time (via programs such as ZDI) or academia can invest which permits access to software or hardware potentially considered out of reach by the vendor. Additionally, where there is a drive within the community to create an open source implementation it can typically be re-purposed for security research. A great example here is OpenBTS/OpenBSC and everything it lead to in the field of active GSM/GPRS research. A technology previously considered out of reach by vendors and industry bodies is methodically picked apart. It can be expected in the future that it won't take twenty years (like GSM) for future technologies to get such close scrutiny.

Examples of technologies that we've had direct experience with that have followed this cycle include:
  • Cellular application protocols (WAP, SMS, MMS etc).
  • GSM, GPRS and 3G networks.
  • Mobile operating systems.
  • Mobile handset cellular baseband.
  • Bluetooth.
  • In car telematics.
  • SCADA.
  • Fixed line telecommunication equipment.
There are others we don’t have direct experience of, yet they have also followed the same cycle:
  • Embedded healthcare technology.
  • Smart grid (arguably a derivative of SCADA).
In each of these cases it wasn’t a question of IF there were security vulnerabilities, but more of which security researcher was going to get access to the technology first, find vulnerabilities and publish. It is hard to believe that vendors consider a 'lack of technology access' a suitable security stop-gap until such time that market or regulatory forces exist which demand that security issues be fixed and a mature SDL be deployed.

An example of the frustration felt by some quarters can be seen through emerging themes from the US government such as DIS (Designed in Security).


So if you’re a vendor, and your starting to receive reports of security vulnerabilities in your products; it means you’re getting to a stage of market penetration where you need to re-invest some of the return, and start paying back the security debt you've incurred to achieve success. For future products, deployment of a lightweight SDL will likely occur to try and regain control of the security balance.

However, the reality is that vendors will likely only ever deploy a full SDL if there is a material effect on their business because of security. This material effect could be regulatory, customer or market differentiation driven.

For the security research community, much like the great explorers it’s a continual race to find the new land of opportunity; a land where new vulnerabilities are easily found and a technology is ripe for exploitation.

So in summary, hardware and software security cannot be ignored in technology, no matter how niche or vertically aligned. If we ignore security we're laying eggs, that if the technology / market is successful will turn into bugs (of the security kind) being reported. These bugs may then with time lead to a full-on infestation which fatally undermines the security of the product. To break this cycle we need to treat not only the immediate host of the bugs (the software) but also the environment (development practices) to stop re-infestation (through component re-use) of future products.

Monday, 19 December 2011

Maltego for Windows Binary Analysis – Identifying Vendor Trust Relationships

So we've been working with Maltego on and off for a couple of years now to see how we can develop new transforms that add value and extend its functionality in useful ways. This has led to us experimenting a lot with small ideas (and some larger ones, but you’ll have to wait for those).

One of the ideas we had was, wouldn't it be useful to use the Maltego visualisation and data mining engine on Windows binaries? This is sort of a cool concept, but what useful information could we extract? Some braining storming later and we thought that in modern software development the end products we install can be made up of software components from many different vendors. So we thought if we extract this information we can start seeing relationships between:
  • Software publishers
  • Code signers
  • Geographic locations
  • Third/fourth party component providers

So we wrote a set of prototype Maltego local transforms to extract information from Windows binaries. The ones we created are:
  • Code signer and vendor company (from signature and binary details)
  • Binaries signed/produced by a company (inverse of the above)
  • Calculating file hashes
  • String extraction

As I said the goal was really to prove an idea and understand the value of both the visualization and the ability to leverage Maltego’s existing transforms to further mine data and relationships in relation to binaries. We see these plug-ins could be used as-is by organizations wishing to:
  • Understand the make up in terms of software publishers of an application / package
  • Identify code trust relationships between organizations
  • During malicious code analysis to identify sources of strings found in a binary (i.e. code fragments)

Anyway without further ado we've put together a rough little demo video of some of the transforms we wrote to give you an idea.



During the development we also wrote a C# helper class to expedite local transform development.  For example a very basic test case is now:


So that's it, idea to prototype in a single blog post..

If you’re interested in these plug-ins and what we’re doing with Maltego feel free to prop us an e-mail to maltego@recx.co.uk or contact us via Twitter @RecxLtd. We’ll happily share the plug-ins as-is with source code with interested parties.

Tuesday, 13 December 2011

The Curious Case of VirtualAlloc, ASLR and an SDL

So Address Space Layout Randomization (ASLR) is becoming increasingly common way on multiple platforms to not resolve security issues but frustrate exploitation. While doing a bit of further research into ASLR on Microsoft Windows 7 one weekend we tripped across some behaviour that was a revelation to us. The revelation was that VirtualAlloc is not subject to ASLR on Windows, this is unlike HeapAlloc and malloc. This fact is surprising considering that:
  • This behaviour is not documented on MSDN
  • This API is not on the Microsoft banned API list
  • Vendors can use VirtualAlloc to allocate memory read-execute, write-execute and read-write-execute

This obviously represents a risk if misused by software vendors and may not be flagged as bad even if the most rigorous of SDLs was adhered to. Why is this behaviour a risk? Well VirtualAlloc could potentially undermine the effectiveness of ASLR (when used) and create the break an aggressor needs.

So we then went looking to see who else was aware of this behaviour. We only found a single public reference when we tripped across Chris Rohlf’s and Yan Ivnitskiy’s Mantasano paper titled ‘Attacking Clientside JIT Compilers’ from the summer. In this paper the authors state:

However, the VirtualAlloc call on Win32 is not randomized by default and will return predictable allocations of contiguous memory at offsets of 0x10000 bytes. Fortunately, VirtualAlloc takes an optional argument indicating the desired page location to allocate. Creating a randomization wrapper around VirtualAlloc to simulate mmap’s existent behaviour should be a straightforward process.”

So armed with this we thought it would be useful to understand how prevalent the use of VirtualAlloc with memory protection constants such as PAGE_EXECUTE_READWRITE and PAGE_EXECUTE_WRITECOPY were. We decided to use 'cloud grep' aka Google code search.

Numerous examples were found in many different projects, including:

One of the more interesting implementations is in Google’s Chromium where they take heed of Chris's and Yan’s advice. 

So this is a real positive outcome, the vendor understands the risk, implements a mitigatation and moves on. Anyway, next we went onto binaries, we did a quick audit of files on one of our Windows 7 machines which included Office 2010. We notice that MSO.DLL uses the function.




Now for this to be of concern to us, we need to have 40h or 80h passed as the last parameter to VirtualAlloc. 40h is PAGE_EXECUTE_READWRITE and 80h is PAGE_EXECUTE_WRITECOPY. Looking through MSO.DLL we find at least one example where this occurs:



From this we know that Microsoft Office allocated memory that is RWX using VirtualAlloc on an otherwise enabled ASLR binary. Now this by itself is not a vulnerability, but knowing this behaviour exists means that there is a light at the end of the tunnel if you're trying to bypass ASLR.

We had a chat with Microsoft about the behaviour of VirtualAlloc. They were good enough to point out that there are numerous factors in the real world that could cause some randomization. These factors include the bottom up randomization in EMET, as documented by Didier in his post Bottom Up Randomization Saves Mandatory ASLR.

Anyway, in conclusion we see that there are a number of instances where VirtualAlloc is used in a potentially dangerous manner in the real-world by a variety of software vendors. While some vendors (credit to Google) mitigate the lack of randomness, not all will. Google and Microsoft are also not the only vendors to use this functionality; there are and will continue to be others who also use it. So in short this is something to add to your grep strings when doing code reviews in order to flag to development teams to ensure they're aware and mitigate appropriately.

Update
We've released an SDL friendly version of VirualAlloc called VirtualAlloc_s.