Super Tuesday Extra: Details on the OWC (late) 0day

by Haifei Li
August 11, 2009 at 9:49 am

You may have taken note that Microsoft patched the Office Web Components zero-day vulnerability today. Previously, attacking code exploiting this vulnerability had been found in the wild, which had led us to release FortiGuard Advisory FGA-2009-27, reflecting Microsoft’s Security Advisory 973472 on July 13.

In fact, we worked in a quite nice collaboration with the Microsoft Security Response Center during the responsible disclosure process. As early as in August last year, this vulnerability was discovered by us and reported to the MSRC (marked as FG-VD-2008-021) along with Proof of Concept code; Later, we also spotted public attacking code and notified the vendor on July 11 this year (mentioned in our latest Threat Landscape Report as well).

It is important to note that the PoC we initially provided Microsoft with is not exactly the same as the one found in the wild; as a matter of course, they point to the same flaw, but vectors that could trigger the problem in the ActiveX control are in fact multiple (Note: our IPS signature can detect all vectors of which we are aware).

Regarding the technical details, after thorough research, we found out that the vulnerability lays in an inconsistency between dynamic libraries owc10.dll (or owc11.dll) and jscript.dll in the way they handle the “object” datatype. Indeed, it turned out that owc10.dll uses an instance of this datatype after Javascript already called its destructor (thereby freeing its memory space). It results in a “Use After Free” problem. Following snapshots provide more details:

pic1

On figure 1 above, a trained eye may recognize the assembly instructions operating the call of a C++ class virtual member function. Indeed, when an object is an instance of a virtual class, its memory representation consists in a pointer called the “vpointer”, (usually) followed by the object  member variables. The vpointer holds the address of the class’ vtable, which is a simple list of indexed member function addresses (aka the class methods). Essentially, this is how the dynamic  dispatch of method calls is implemented in machine code, and this is what effectively enables C++ inheritance polymorphism.

Here, register esi holds the object vpointer address (0×39DB88), which, we recall, is also the start of the instanced object’s memory space on the Heap. Therefore, mov eax, dword ptr [esi] loads the vtable address in register eax, and call dword ptr [eax+98] calls the function at index 0×98 in the vtable. What does this function do? The IDA Pro screenshot below enlightens us:

pic2

Obviously, the function at index 0×98 is the class destructor. The object memory space at 0×0039DB88 on the heap is therefore freed. Now, the dodgy thing happening in owc10.dll afterward is shown on Figure 3 below:

pic3

Again, one may recognize the same sequence of instructions typical of a virtual function call: eax holds the object vpointer address, mov ecx, dword ptr [eax] loads the vtable address in ecx, and call dword ptr [ecx+8] calls function at index 0×08 in the vtable.

In other words, the dll calls a method of the object sitting at eax. However, here, eax is set to… 0×0039DB88, and therefore points to an object that was freed above by jscript.dll. Conclusion: we’re in “Use After Free” case, which is relatively serious, since it could likely be exploited by attackers to run any malicious code they want on the system of a user simply visiting a specifically crafted web page.

We pointed this out in our original vulnerability report. Which turned out to be judicious, since as of writing, a working exploit has been seen spreading in the wild for more than one month.

Our customers are of course protected by the relevant IPS patterns. We nonetheless recommend that all Microsoft Office users apply the official patch as soon as possible.

Guillaume Lovet and Kyle Yang contributed to this report.

Author bio: Haifei Li is a senior vulnerability researcher with Fortinet's FortiGuard Labs.