21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Discussion<br />

The Win32 API provides several functions for executing new programs. In the days of<br />

the Win16 API, the proper way to execute a new program was to call WinExec( ).<br />

While this function still exists in the Win32 API as a wrapper around CreateProcess( )<br />

for compatibility reasons, its use is deprecated, and new programs should call<br />

CreateProcess( ) directly instead.<br />

A powerful but extremely dangerous API function that is popular among developers<br />

is ShellExecute( ). This function is implemented as a wrapper around<br />

CreateProcess( ), and it does exactly what we’re about to advise against doing with<br />

CreateProcess( )—but we’re getting a bit ahead of ourselves.<br />

One of the reasons ShellExecute( ) is so popular is that virtually anything can be executed<br />

with the API. If the file to execute as passed to ShellExecute( ) is not actually<br />

executable, the API will search the registry looking for the right application to launch<br />

the file. For example, if you pass it a filename with a .TXT extension, the filename<br />

will probably start Notepad with the specified file loaded. While this can be an<br />

incredibly handy feature, it’s also a disaster waiting to happen. Users can configure<br />

their own file associations, and there is no guarantee that you’ll get the expected<br />

behavior when you execute a program this way. Another problem is that because<br />

users can configure their own file associations, an attacker can do so as well, causing<br />

your program to end up doing something completely unexpected and potentially<br />

disastrous.<br />

The safest way to execute a new program is to use either CreateProcess( ) or<br />

CreateProcessAsUser( ). These two functions share a very similar signature:<br />

BOOL CreateProcess(LPCTSTR lpApplicationName, LPTSTR lpCommandLine,<br />

LPSECURITY_ATTRIBUTES lpProcessAttributes,<br />

LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,<br />

DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory,<br />

LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation);<br />

BOOL CreateProcessAsUser(HANDLE hToken, LPCTSTR lpApplicationName,<br />

LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,<br />

LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles,<br />

DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory,<br />

LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation);<br />

The two most important arguments for the purposes of proper secure use of<br />

CreateProcess( ) or CreateProcessAsUser( ) are lpApplicationName and lpCommandLine.<br />

All of the other arguments are well documented in the Microsoft Platform SDK.<br />

lpApplicationName<br />

Name of the program to execute. The program may be specified as an absolute<br />

or relative path, but you should never specify the program to execute in any way<br />

other than as a fully qualified absolute path and filename. This argument may<br />

also be specified as NULL, in which case the program to execute is determined<br />

from the lpCommandLine argument.<br />

34 | Chapter 1: Safe Initialization<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!