Microsoft Silverlight Vulnerability CVE-2016-3367 Analysis

On Tuesday, Microsoft released a security update for Silverlight (MS16-109). Silverlight vulnerabilities are always one of the attacker’s favorite targets because most of them allow remote code execution. In this blog, I will explain what the vulnerability is about and the exploit indicators.

Patch Diff and Root Cause:

Patch diff is a very common way for security researchers and even attackers to figure out how a patch works and what’s the vulnerability. It returns the binary difference between the vulnerable binary file and the patched one. Below is a comparison of the patched binary file of Silverlight with the last vulnerable one:

PATCHDIFF
PATCHDIFF

You can see clearly that two functions are updated which are “ExpandByABlock” and “MakeRoom”. This is a fairly small change and both functions are within “StringBuilder” class. You can easily get the source code for these 2 functions from MSDN:

private void ExpandByABlock(int minBlockCharCount)

private void MakeRoom(int index, int count, out StringBuilder chunk, out int indexInChunk, bool doneMoveFollowingChars)

The problem here is we don’t know if this is still the vulnerable code or the fixed code. And also, which code block is the patch if this is the fixed code. So let’s find out from the function’s binary diff:

9-15-patchexpandbyablock

So basically the patch for “ExpandByABlock” provides an extra code block before going to the vulnerable codes. As a patch, this is mostly a condition check. This patch code block is:

ldarg.1
ldarg.0
call     instance int32 System.Text.StringBuilder::get_Length()
add
ldarg.1
blt.s    loc_C

In line 1, the patch loads the arguments 1 which is “minBlockCharCount” in the function, and adds the value with Length of this “StringBuilder”. Jump to the exception if the sum is less than “minBlockCharCount”.

From that we know the patch is here:

9-15-patchsourcecode

Clearly this is an integer overflow vulnerability. Basically the argument “minBlockCharCount” stands for how many Characters needs to be expanded. On vulnerable binaries, Microsoft only checks that the newly added length plus current length should less than “m_MaxCapacity” to avoid overflow.  The value of “m_MaxCapacity” is set to 0x7fffffff which is 2,147,483,647. But this will cause a problem. Let’s say the currently string’s length is 2,147,483,647-1 and someone wants to add 2 characters (minBlockCharCount). So minBlockCharCount + Length is 2,147,483,647-1+2. It exceeds the maximum value of an integer, so the plus result is -2,147,483,648. And of course this big negative value is less than “m_MaxCapacity”.

The patch simply makes sure that minBlockCharCount plus Length is not a negative value (minBlockCharCount is asserted to be greater than 0 in line 2 of this function). This fix will stop this integer overflow vulnerability.

The second updated function “MakeRoom” has a similar issue, and the fix is also similar.

makeroom's fix
makeroom’s fix

For programmers, coding style like:

if (insertingChars > MaxCapacity - this.Length) {
throw new OutOfMemoryException();
}

Is much better than:

if (insertingChars +this.Length> MaxCapacity ) {
throw new OutOfMemoryException();
}

for boundary checks because of the integer overflow I explained.

Exploit Indicators

This is about how the attacker will take advantage of this vulnerability to hack people. Both “ExpandByABlock” and “MakeRoom” are private functions. This means they can’t be called outside “StringBuilder” class. To exploit this vulnerability, attackers needs to find a code path to hit these 2 vulnerable functions.

For “MakeRoom”, there are two function calling path which will hit this vulnerable function:

public StringBuilder Replace(String oldValue, String newValue, int startIndex, int count)

public StringBuilder Insert(int index, String value, int count)

For “ExpandByABlock”, there is:

public unsafe StringBuilder Append(char* value, int valueCount)

These 3 public functions are entrance  to exploit this vulnerability. To detect this, simply check the length of strings waiting to be replace/insert/append.

If its length is greater than MaxCapacity – currentstringlength, then someone is trying to exploit CVE-2016-3367.

Conclusion

This is the second integer overflow vulnerability in Silverlight from Microsoft this year after CVE-2016-0034. Attackers and exploit kit writers are expected to weaponize this vulnerability soon: it took them less than 9 days to weaponize  CVE-2016-0034 in February. So we recommend that customers should scan their network with QID: 91272 to defend against this coming threat.

 

Leave a Reply

Your email address will not be published. Required fields are marked *