Microsoft Windows Kernel - Registry Hive Loading 'nt!RtlEqualSid' Out-of-Bounds Read (MS16-138)








We have encountered a Windows kernel crash in the nt!RtlEqualSid function invoked through nt!SeAccessCheck by nt!CmpCheckSecurityCellAccess while loading corrupted registry hive files. An example of a crash log excerpt generated after triggering the bug is shown below:

N bytes of memory was allocated and more than N bytes are being referenced.
This cannot be protected by try-except.
When possible, the guilty driver's name (Unicode string) is printed on
the bugcheck screen and saved in KiBugCheckDriver.
Arg1: a1f11004, memory referenced
Arg2: 00000000, value 0 = read operation, 1 = write operation
Arg3: 816d40b3, if non-zero, the address which referenced memory.
Arg4: 00000000, Mm internal code.

Debugging Details:


92bbb5e4 816f92b9 a1f11004 83af4ff0 92bbb6ac nt!RtlEqualSid+0x9
92bbb604 816d3292 00000000 20204d43 00000000 nt!RtlpOwnerAcesPresent+0x87
92bbb634 816d3cfe a1f10f50 00000001 00bbb6b0 nt!SeAccessCheckWithHint+0x178
92bbb668 818f8ff8 a1f10f50 92bbb6b0 00000000 nt!SeAccessCheck+0x2a
92bbb6c0 81820906 a75e69c8 000051d8 00000001 nt!CmpCheckSecurityCellAccess+0xe5
92bbb6fc 818206ad 03010001 92bbb728 92bbb718 nt!CmpValidateHiveSecurityDescriptors+0x1bd
92bbb73c 8182308f 03010001 80000588 8000054c nt!CmCheckRegistry+0xd8
92bbb798 817f6fa0 92bbb828 00000002 00000000 nt!CmpInitializeHive+0x55c
92bbb85c 817f7d85 92bbbbb8 00000000 92bbb9f4 nt!CmpInitHiveFromFile+0x1be
92bbb9c0 817ffaae 92bbbbb8 92bbba88 92bbba0c nt!CmpCmdHiveOpen+0x50
92bbbacc 817f83b8 92bbbb90 92bbbbb8 00000010 nt!CmLoadKey+0x459
92bbbc0c 8168edc6 0014f8a4 00000000 00000010 nt!NtLoadKeyEx+0x56c
92bbbc0c 77cc6bf4 0014f8a4 00000000 00000010 nt!KiSystemServicePostCall
WARNING: Frame IP not in any known module. Following frames may be wrong.
0014f90c 00000000 00000000 00000000 00000000 0x77cc6bf4


816d40b3 668b06          mov     ax,word ptr [esi]

The issue reproduces on Windows 7. It is easiest to reproduce with Special Pools enabled for the NT kernel (leading to an immediate crash when the bug is triggered), but it is also possible to observe a crash on a default Windows installation. In order to reproduce the problem with the provided sample, it is necessary to load it with a dedicated program which calls the RegLoadAppKey() API.

3 samples attached with single-byte differences compared to the original file, and the base sample itself.

Proof of Concept: