A lot of the presentations at security (or perhaps more appropriately, "insecurity") conferences such as Black Hat are devoted to experiments or "dares" for hackers to break through some new version of digital security. After awhile, it gets to be like watching pre-schoolers daring one another to punch through ever-taller Lego walls. But in the midst of last July's briefings came at least one scientifically researched, carefully considered, and thoughtfully presented presentation: the result of a full-scale investigation by three engineers at a consultancy called Hustle Labs, demonstrating how the presumption of trust between browsers, their add-ons, and other code components can trigger the types of software failures that can become exploitable by malicious code.
Engineers Mark Dowd, Ryan Smith, and David Dewey are being credited today with shedding light on a coding practice by developers that leaves the door open for browser crashes. The discovery of specific instances where such a practice could easily become exploitable is the focus of the most critical of Microsoft's regular second-Tuesday-of-the-month patches -- arguably the biggest of 13 bulletins addressing a record 34 fixes.
Among today's fixes is one that specifically addresses a relatively new class of Web apps that use XAML, Microsoft's XML-based front-end layout language, instead of HTML for presenting the user with controls. The class of apps is currently being called XAML Browser Application, or XBAP (perhaps Microsoft should have it shut off just for the lousy acronym). Simply browsing to a maliciously crafted XBAP application could create an attack vector, says one of Microsoft's bulletins published this morning.
But that isn't actually the problem, but the symptom of a very serious problem uncovered by the Hustle Labs trio -- one that may generate several more security fixes in coming months. At the root of the problem is the fact that browser plug-ins and components external to browsers -- for instance, the components that tie browsers to the .NET Framework in order to run XBAP apps -- are given higher levels of trust than the browser itself. These days, trust levels are turned down on the browser to disable most any chance of a simple JavaScript deleting elements of the user's file system without authorization; but plug-ins are often given a medium level of trust simply because they must be interoperable with a component (the Web browser) that is outside of its own context.
So when a plug-in creates references to new components, a principle called transitive trust mandates that this medium-level trust be transferred to the new component. And when that new component is an instance of an ActiveX object, that new level of trust may mean that if the object causes an exception, the mess it leaves behind could have just enough privilege attributed to it to execute malicious code.
The mess itself, the Hustle Labs researchers illustrated last July at Black Hat (PDF available here), can be caused by a tricky data type that has raised my eyebrows since the early '90s when I witnessed its first demonstrations: It's the variant type, created to represent data that may be passed as a parameter between procedures or components, whose type may be unspecific or even unknown. The way Microsoft represents variants in memory is by pairing their type with their value as a single unit, and that type is actually a pointer to a structure. That structure may be a primary type, but most often in the case of COM components (known to Web users as ActiveX components), it's a complex object comprised of multiple data elements, assembled together like records in a database, often whose types may include other variants.
The problem with using variants, as Microsoft learned the hard way (more than once), is that when you're trying to secure the interfaces between components, the absence of explicit types makes it difficult to ensure that they're behaving within the rules. But as the researchers discovered, it's the security code itself -- what they call marshaling code, resurrecting language from COM's heyday -- that can actually cause a serious problem, a mess that leaves behind opportunities for exploitation.
"The most obvious mistake a control can make with regard to object retention is to neglect to add to the reference count of a COM object that it intends to retain," the trio writes. A reference count helps a control to maintain a handle to the object it's instantiated. But marshaling code, in an effort to provide security to the system, will also amend the reference count; and when it thinks the control is done with the object, it will decrement that count in turn. So if the control had any other plans for the object, it has to add its own reference count to the same object.
To make a (very) long story short, there often ends up being more pointers to the object than there are objects. And with medium-level privilege, those pointers can theoretically be exploited.
The case-in-point involves those nasty variants. Adding references to objects in memory often involves copying the objects themselves; and in the case of variants, there's a special function for that. But to know to use that special function, marshaling code would have to be aware that the objects being copied and re-referenced are variants; so instead, they resort to the tried-and-true memcpy() library function. That function is capable of copying the complex object, but in such a "shallow" way that it doesn't give a whit about whether the contents of the complex object are complex objects in themselves -- and since memcpy() predates COM by a few decades, it doesn't increment the reference count for new instances of included objects that are created in the process. A pointer to the new object exists, of course, but not the reference that COM requires.
So an ordinary memory cleanup routine could clean up the contents of the duplicated contained object, even though a component has designs on using that object later. As the group writes, "If the variant contains any sort of complex object, such as an IDispatch [a common COM object], a pointer to the object will be duplicated and utilized without adding an additional reference to the object. If the result of this duplicated variant is retained, the object being pointed to could be deleted, if every other instance of that object is released."
There are a multitude of similar examples in this research paper of essentially the same principle in action: a principle that points to a fundamental flaw in the way COM objects have been secured up to now. The Hustle Labs team takes Microsoft to task only at one point in the paper, and quite gently, for implementing Patch Tuesday fixes that tend to resort to using "killbits" in the Registry for turning off COM components and ActiveX controls impacted by this kind of vulnerability, instead of reworking the marshaling code to address the problem at a fundamental level.
So today's round of Patch Tuesday releases may go into more detail than just resorting to killbits -- in a few situations this week, new patches actually go into further depth at patching problems that were said to have been patched already, including with the GDI+ library. But it's an indication that independent researchers with conscientious goals are truly getting through.