This Tuesday, Microsoft released additional updates for older platforms to protect against potential nation-state activity. Among the updates, the official patch fixing the CVE-2017-7269 vulnerability is available.
This official patch is a good way to confirm the root cause of the bug commented on my previous notes, allocating the target buffer size with the number of characters instead of the number of bytes in the functions HrCheckIfHeader and HrGetLockIdForPath.
This blog entry contains my notes running patch diffing on CVE-2017-7269.
Obtaining the patch
The patch description is available here. The description contains the proper information to download/apply the patch fixing the remote code execution vulnerability in WebDav.
A Windows Update catalog's direct link on this patch is available too. It displays six different patches fixing the vulnerability for different platforms. In our case we are interested on
KB3197835 is the reference assigned by Microsoft to this vulnerability.
We can extract the patch's contents with the '/extract' parameter.
We will be interested on the patched httpext.dll file shipping in the C:\patches\SP2QFE directory.
Diffing the patch
Diaphora returns the following numbers, based on heuristics, to match the different functions between the primary and the secondary file.
- Best matches: 1714
- Partial matches: 6
- Unreliable matches: 2
- Unmatched in primary: 9
- Unmatched in secondary: 8
A high number of functions (1714) were labeled as 'Best matches' by Diaphora. The patched version looks quite similar to the original version.
On the other hand, there are 6 functions labeled as 'Partial matches' with ratios between 0.760 and 1.
The first (6711D86D/6711D64C/0.950) and last (67128552/6713A0C7/0.880) entries in the 'Partial matches' table are not very interesting. They contain minor differences.
The second (67125326/6712516D/1) and third (67125627/67125473/1) entries contain the bugfix for the vulnerability. This bugfix updates the vulnerable code in HrCheckIfHeader and HrGetLockIdForPath functions as expected.
The fourth (67126100/67125F51/0.920) entry fixes a handle leak. This leak lives in safe_revert_self::~safe_revert_self()
The fifth entry (671270CF/67126F85/0.760) adds a more strict approach to handle multibyte conversions to wide chars. It is an update in the ScConvertToWide function.
The main fixes shipping with the patch
The HrCheckIfHeader bugfix...
The new code knows a Windows wide char type is always two bytes so it multiplies the number of characters by two, and then it adds two extra bytes to take into account the extra zero ending the string. This new value is the right size for the target buffer.
The HrGetLockIdForPath bugfix contains the same vulnerability that HrCheckIfHeader. The bugfix is the same one.
In the case of the ScConvertToWide update, it looks Microsoft did some hardening in order to reduce the attack surface in the multibyte to wide char conversion.
In detail, the dwFlags parameter used with the MultiByteToWideChar function is always 8 now. The value 8 (MB_ERR_INVALID_CHARS) is used to fail if an invalid input character is encountered. In the non patched version it could be 0 or 8 depending on the code page used.
Having a look in the documentation for the MultiByteToWideChar function, the new code will fail with ERROR_INVALID_FLAGS for the code pages 50220, 50221, 50222, 50225, 50227, 50229, 57002 through 57011, 65000 (UTF-7) and 42 (Symbol). Those code pages require dwFlags set to 0.
In the case of the safe_revert_self::~safe_revert_self bugfix, the patch fixes a handle leak. The new code always closes the handle.