Unicode and ANSI Buffer Size Mismatches

Unicode and ANSI Buffer Size Mismatches

The buffer overrun caused by Unicode and ANSI buffer size mismatches is somewhat common on Windows platforms. It occurs if you mix up the number of elements with the size in bytes of a Unicode buffer. There are two reasons it s rather widespread: Windows NT and later support ANSI and Unicode strings, and most Unicode functions deal with buffer sizes in wide characters, not byte sizes.

The most commonly used function that is vulnerable to this kind of bug is MultiByteToWideChar. Take a look at the following code:

BOOL GetName(char *szName) { WCHAR wszUserName[256]; // Convert ANSI name to Unicode. MultiByteToWideChar(CP_ACP, 0, szName, -1, wszUserName, sizeof(wszUserName)); // Snip  }

Can you see the vulnerability? OK, time is up. The problem is the last argument of MultiByteToWideChar. The documentation for this argument states: Specifies the size, in wide characters, of the buffer pointed to by the lpWideCharStr parameter. The value passed into this call is sizeof(wszUserName), which is 256, right? No, it s not. wszUserName is a Unicode string; it s 256 wide characters. A wide character is two bytes, so sizeof(wszUserName) is actually 512 bytes. Hence, the function thinks the buffer is 512 wide characters in size. Because wszUserName is on the stack, we have a potential exploitable buffer overrun.

Here s the correct way to write this function:

 MultiByteToWideChar(CP_ACP, 0, szName, -1, wszUserName, sizeof(wszUserName) / sizeof(wszUserName[0]));

A Real Unicode Bug Example

The Internet Printing Protocol (IPP) buffer overrun vulnerability was a Unicode bug. You can find out more information on this vulnerability at www. microsoft.com/technet/security; look at bulletin MS01-23. IPP runs as an ISAPI filter in Internet Information Services (IIS) 5, which runs under the SYSTEM account therefore, an exploitable buffer overrun is even more dangerous. Notice that the bug was not in IIS. The vulnerable code looks somewhat like this:

TCHAR wszComputerName[256]; BOOL GetServerName(EXTENSION_CONTROL_BLOCK *pECB) { DWORD dwSize = sizeof(wszComputerName); char szComputerName[256]; if (pECB->GetServerVariable (pECB->ConnID, "SERVER_NAME", szComputerName, &dwSize)) { // Do something. }

GetServerVariable, an ISAPI function, copies up to dwSize bytes to szComputerName. However, dwSize is 512 because TCHAR is a macro that, in the case of this code, is a Unicode or wide char. The function is told that it can copy up to 512 bytes of data into szComputerName, which is only 256 bytes in size! Oops!



Writing Secure Code
Writing Secure Code, Second Edition
ISBN: 0735617228
EAN: 2147483647
Year: 2005
Pages: 153

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net