Tuesday, July 09, 2013

Why don't elevated processes inherit their environment variables from their non-elevated parent?

As a general rule, child processes inherit the environment of their parent. But if the parent is non-elevated and the child is elevated, then this inheritance does not happen. Why not?

There are two answers to this question. For the kernel-color glasses answer, I defer to Chris Jackson, the App Compat Guy. It's interesting to see how it all works, but it doesn't explain why the mechanism was designed to block environment variable inheritance.

The reason for the design is that allowing an elevated process to inherit the PATH from a non-elevated process creates an attack vector.

The non-elevated process sets its PATH to put some attacker-controlled directories ahead of the directories the elevated application actually expects. For example, suppose the elevated application links to C:\Program Files\Common Files\Contoso\Contoso­Grid­Control.dll. It arranges for this by setting the system PATH to include the C:\Program Files\Common Files\Contoso directory. Or maybe the program calls Load­Library on a DLL that might not exist, and it handles the case that the call fails by disabling some optional feature. (Whether this is a good idea or not is beside the point.)

The attacker changes the PATH to read \\rogue\server;C:\Program Files\Common Files\Contoso, so that the library search finds the evil copy on the rogue server before finding the expected version in the Common Files directory (or in the case of a DLL that may not exist, it finds the evil copy on the rogue server instead of failing outright).

Bingo, the attacker has injected arbitrary code into an elevated process. Game over.

For similar reasons, the current directory is reset to the system directory when a non-elevated program launches an elevated program.

Read more: The Old New Thing
QR: Inline image 1