FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
Security
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Furl
Slashdot
Y! MyWeb
Blink
May 16, 2006

Secure Coding in C++/CLI

(Page 3 of 4)

Enabling the /GS option does not make programs completely immune to buffer overflow vulnerabilities. Buffer overflows in the stack can still crash the program, and the possibility still exists for attackers to exploit a stack-based overflow to execute arbitrary code even with the /GS flag enabled. More importantly, the /GS flag cannot detect buffer overflows in either the heap or data segments.

To illustrate, Listing Two presents the previous example program rewritten to use the Win32 GUI. This program provides a menu bar with some simple options, including a File menu with two menu options: "Login" and "Exit." The Login command prompts the user for a password using a dialog window. Once the password is entered, the user presses the "OK" button and the password is checked against the recorded password.

 1. #include "stdafx.h"
 2. #include "TestItDan.h"
 3. #include <stdlib.h>
 4. #include <stdio.h>
 5. #include <windows.h>
 6. #define MAX_LOADSTRING 100
 7. struct user {
 8.     wchar_t *name;
 9.     size_t len;
10.     int uid;
11. };
13. HINSTANCE hInst;
14. TCHAR szTitle[MAX_LOADSTRING];
15. TCHAR szWindowClass[MAX_LOADSTRING];
16. TCHAR lpszUserName[16] = L"guest";
17. TCHAR lpszPassword[16] = L"0123456789abcde";
18. struct user *userP = (struct user *)0xcdcdcdcdcdcdcdcd;
19. size_t userNameLen = 16;
20. size_t userPasswordLen = 0xffffffff;
25. int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow) {
26.     UNREFERENCED_PARAMETER(hPrevInstance);
27.     UNREFERENCED_PARAMETER(lpCmdLine);
28.     MSG msg;
29.     HACCEL hAccelTable;
30.     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
31.     LoadString(hInstance, IDC_TESTITDAN, szWindowClass,                         MAX_LOADSTRING);
32.     MyRegisterClass(hInstance);
33. userP = (struct user *)malloc(sizeof(user));
34. if (!InitInstance (hInstance, nCmdShow)) {
35.     return FALSE;
36. }
37. hAccelTable =
          LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTITDAN));
38. while (GetMessage(&msg, NULL, 0, 0)) {
39.     if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
40.         TranslateMessage(&msg);
41.         DispatchMessage(&msg);
42.     }
43. }
44. return (int) msg.wParam;
45. }

109. INT_PTR CALLBACK GetPassword(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { 110. TCHAR lpszGuestPassword[16] = L"NCC-1701"; 111. UNREFERENCED_PARAMETER(lParam); 112. switch (message) { 113. case WM_INITDIALOG: 114. return (INT_PTR)TRUE; 115. case WM_COMMAND: 116. if (LOWORD(wParam) == IDOK) { 117. EndDialog(hDlg, LOWORD(wParam)); 118. SendDlgItemMessage(hDlg, 119. IDC_EDIT1, 120. EM_GETLINE, 121. (WPARAM) 0, // line 0 122. (LPARAM) lpszPassword 123. ); 124. userP->len = userNameLen; 125. if (wcscmp(lpszPassword, lpszGuestPassword) == 0) { 126. return true; 127. } 128. else { 129. MessageBox(hDlg, 130. (LPCWSTR)L"Invalid Password", 131. (LPCWSTR)L"Login Failed", 132. MB_OK 133. ); 134. } 135. return (INT_PTR)TRUE; 136. } 137. break; 138. } 139. return (INT_PTR)FALSE; 140. }

Listing Two

The program is compiled and tested in the same environment except that the Unicode character set is specified and the buffer security check option (/GS) is enabled. We continue to use managed extensions (that is, Common Language Runtime support). The program builds cleanly without error.

This is a relatively simple program, although it is somewhat longer because of the code required to support the Windows GUI. There are several variables of interest from lines 17-20. The lpszPassword variable is an initialized static variable consisting of 16 wide characters (32 bytes). Following this variable is the userP pointer and two unsigned integers: userNameLen and userPasswordLen. After userP is initialized on line 33, these variables have the following addresses:

&lpszPassword = 0x0040911C
&userP =   0x0040913C
&userNameLen =  0x00409140
&userPasswordLen =   0x00409144

userP is 0x00554D30. userNameLen is 0x00000010. userPasswordLen is 0xffffffff. If we examine memory starting at the address of lpszPassword, we can clearly see the initial values for these variables (Example 3).

0040911C   30 00 31 00 32 00 33 00 34 00 35 00 36 00 37 00
0040912C   38 00 39 00 61 00 62 00 63 00 64 00 65 00 00 00
0040913C   30 4d 55 00 10 00 00 00 ff ff ff ff 8a 00 07 02
0040914C   c6 00 07 02 02 01 07 02 00 00 00 00 01 00 00 00

Example 3: Memory starting at the address of lpszPassword.

The vulnerability in this program is in the call to SendDlgItemMessage on lines 118-123. The EM_GETLINE message specifies that a line of text from the edit control IDC_EDIT1 (the text edit box in the Login dialog) is copied to the fixed-length buffer lpszPassword. This buffer has sufficient space for 15 Unicode characters and a trailing null word. If more than 15 characters are input, a buffer overflow occurs. If 20 characters are entered, the 17th and 18th characters overwrite userP. The 19th and 20th characters overwrite userNameLen, and the trailing null word overwrites userPasswordLen.

Assuming that both userP and userNameLen are overwritten, an arbitrary memory write occurs on line 124 when userNameLen is assigned to the address stored in userP + 4 (the offset of len within struct user). By overwriting an address to which control is eventually transferred, attackers can take advantage of an arbitrary memory write to transfer control to arbitrary code. In this example, the return address on the stack is overwritten. Because the lpszGuestPassword variable is declared as an automatic variable in the GetPassword function, you can examine memory starting from the address of this variable.

Previous Page | 1 Secure Coding in C++/CLI | 2 Vulnerabilities | 3 GS Option | 4 More Vulnerabilities Next Page
TOP 5 ARTICLES
No Top Articles.



MICROSITES
FEATURED TOPIC

ADDITIONAL TOPICS

INFO-LINK