By Alin Rad Pop
An interesting vulnerability in Microsoft Windows was disclosed yesterday via a post to Full-Disclosure. The vulnerability allows bypassing checks normally performed when helpctr.exe receives the "-FromHCP" command-line parameter when opening an HCP URI. This allows passing arbitrary parameters to a help document affected by a cross-site scripting error, ultimately allowing execution of arbitrary script code in a privileged context on a user's system when e.g. viewing a specially crafted web page.
The report provides a fair amount of details, a fully functional exploit, and an unofficial hotfix, which patches the function believed to be at fault. The error is presented as occurring when an URL is unescaped inside the helpctr.exe "MPC::HTML::UrlUnescapeW()" function, which apparently fails to properly interpret errors returned from "MPC::HexToNum()", adding FFFFh characters to the decoded string.
After confirming the vulnerability and publishing a Secunia advisory, we scheduled the vulnerability for an in-depth analysis, which uncovered that the cause is different and that the provided, unofficial hotfix does not properly address the vulnerability.
Although at first glance the original vulnerability report seemed to contain sufficient vulnerability details, it in fact omitted to explain how FFFFFFFFh values returned from "MPC::HexToNum()" can be abused to evade the "-FromHCP" whitelist check.
Although we're still putting finishing touches on our analysis, it seems that the check, which ensures that a requested URL is in the whitelist, normally takes place when an "hcp://services/search?topic=" query is received and should ensure that the decoded "topic" parameter is in a list of allowed URLs. Before the check is made, a call to a database query function is performed to locate related topics. If a large number of invalid hexadecimal characters are included in the original "topic" parameter, the database query wrongly returns a non-zero result. The calling function jumps over the whitelist check if non-zero is returned, allowing arbitrary parameters to be processed later. The return value of the outer database query function is tied to the return value of an esent.dll "JetSeek()" call issued from another process (helpsvc.exe).
During our analysis, we discovered that "MPC::HexToNum()" can return FFFFh values simply by replacing "%%A" sequences with "%uFFFF" (getting the function to return e.g. FFFEh using "%uFFFE" would equally work) in the provided starthelp.html. This is equivalent to the case described in the original report in terms of URL decoding (i.e. the same result string is obtained in both cases), but does, contrary to the original exploit, not require an error to be returned from "MPC::HexToNum()".
As the unofficial hotfix intends to fix the vulnerability by making "MPC::HexToNum()" return 0 instead of FFFFFFFFh in case of an error, it does not take into account the above-mentioned approach. It is, therefore, possible to bypass the fix implemented by the unofficial hotfix and still exploit the vulnerability on systems where it is installed.
Users are, therefore, encouraged not to install the unoffical hotfix, but instead remove the HCP URI handler from the registry to prevent exploitation until an official patch is available from Microsoft.
Alin Rad Pop
Senior Security Specialist