Object Creation Mistakes

Object Creation Mistakes

Object creation mistakes relate to how some Create functions operate. In general, such functions, including CreateNamedPipe and CreateMutex, have three possible return states: an error occurred and no object handle is returned to the caller, the code gets a handle to the object, and the code gets a handle to the object. The second and third states are the same result, but they have subtle differences. In the second state, the caller receives a handle to an object the code created. In the third state, the caller receives a handle to an already existing object! It is a subtle and potentially dangerous issue if you create named objects such as named pipes, semaphores, and mutexes that have predictable names.

The attacker must get code onto the server running the process that creates the objects to achieve any form of exploit, but once that's accomplished, the potential for serious damage is great.

A security exploit in the Microsoft Telnet server relating to named objects is discussed in Predictable Name Pipes Could Enable Privilege Elevation via Telnet at http://www.microsoft.com/technet/security/bulletin/MS01-031.asp. The Telnet server created a named pipe with a common name, and an attacker could hijack the name before the Telnet server started. When the Telnet server created the pipe, it actually acquired a handle to an existing pipe, owned by a rogue process.

The moral of this story is simple: when you create a named object based on a well-known name, you must consider the ramifications of an attacker hijacking the name. You can code defensively by allowing your code only to open the initial object and to fail if the object already exists. Here's some sample code to illustrate the process:

#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE # define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000 #endif int fCreatedOk = false; HANDLE hPipe = CreateNamedPipe("\\\\.\\pipe\\MyCoolPipe", PIPE_ACCESS_INBOUND FILE_FLAG_FIRST_PIPE_INSTANCE , PIPE_TYPE_BYTE, 1, 2048, 2048, NMPWAIT_USE_DEFAULT_WAIT, NULL); // Default security descriptor if (hPipe != INVALID_HANDLE_VALUE) { // Looks like it was created! CloseHandle(hPipe); fCreatedOk = true; } else { printf("CreateNamedPipe error %d", GetLastError()); } return fCreatedOk;

Note the FILE_FLAG_FIRST_PIPE_INSTANCE flag. If the code above does not create the initial named pipe, the function returns access denied in GetLast Error. This flag was added to Windows 2000 Service Pack 1 and later.

Another option that can overcome some of these problems is creating a random name for your pipe, and once it's created, writing the name of the pipe somewhere that client applications can read. Make sure to secure the place you write the name of the pipe so that a rogue application can't write its own pipe name. Although this helps with some of the problem, if a denial of service condition is in the server end of the pipe, you could still be attacked.

It's a little simpler when creating mutexes and semaphores because these approaches have always included the notion of an object existing. The following code shows how you can determine whether the object you created is the first instance:

HANDLE hMutex = CreateMutex( NULL, // Default security descriptor. FALSE,  "MyMutex"); if (hMutex == NULL) printf("CreateMutex error: %d\n", GetLastError()); else if (GetLastError() == ERROR_ALREADY_EXISTS ) printf("CreateMutex opened *existing* mutex\n") ; else printf("CreateMutex created new mutex\n");

The key point is determining how your application should react if it detects that a newly created object is actually a reference to an existing object. You might determine that the application should fail and log an event in the event log so that the administrator can determine why the application failed to start.

Remember that this issue exists for named objects only. An object with no name is local to your process and is identified by a unique handle, not a common name.



Writing Secure Code
Writing Secure Code, Second Edition
ISBN: 0735617228
EAN: 2147483647
Year: 2001
Pages: 286

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