Sunday, June 7, 2015

filenames - Did a version of Windows ever behave this way?


Inspired by today's DailyWTF article.


The author claims that a file C:\Program.exe would be executed when clicking on a shortcut to, for example, C:\Program Files\Doom 2\doom2.exe -nomusic.


Supposedly, Windows first attempts to invoke C:\Program with the arguments Files\Doom 2/doom2.exe -nomusic.


If there is no C:\Program.exe, it then tries C:\Program Files\Doom with the arguments 2/doom2.exe -nomusic.


And if there is no C:\Program Files\Doom.exe\, it finally tries C:\Program Files\Doom 2\doom2.exe -nomusic and succeeds.


This sounds like complete nonsense to me. I can't believe it ever worked this way. A commenter puts it well:



I find it hard to believe that any released version of Windows ever did the trial-and-error approach described by OP.


I absolutely believe that a released version of Windows had brain-dead behavior as a default. I have experienced it firsthand many, many times.


What I don't believe is that a released version of Windows had this brain-dead behavior, as described by the article. It's too huge a security flaw to have gone by unnoticed until some random Daily WTF submission uncovered it, at least a decade later since it would have had to be a version of Windows that predated XP.



Edit for clarity: Here's how I tested this myself.



  1. Copy notepad.exe to C:\program.exe

  2. Run C:\program files\Internet explorer\iexplore.exe

  3. Notepad opens. This is expected because it finds something called C:\program

  4. Move progam.exe to C:\program files\Internet.exe

  5. Run C:\program files\Internet explorer\iexplore.exe


According to the author of the article (and this article from Microsoft), notepad should still open. But it doesn't, the command fails with this message:


C:\program is not recognized as an internal or external command, operable program or batch file.


Again, I am not debating the article's claim that C:\program would be invoked. I am debating that Windows recursively tries every directory until it hits a match.


So, did any version of Windows ever work this way?


Answer



Every version of Windows since long file names where added works this way from Windows 95 and up to including Windows 7.


This is behavior is documented:



The lpApplicationName parameter can be NULL. In that case,
the module name must be the first white space–delimited token in the
lpCommandLine string.
If you are using a long file name that contains a space, use quoted
strings to indicate where the file name ends and the arguments begin;
otherwise, the file name is ambiguous. For example, consider the
string "c:\program files\sub dir\program name". This string can be
interpreted in a number of ways. The system tries to interpret the
possibilities in the following order:


c:\program.exe files\sub dir\program name
c:\program files\sub.exe dir\program name
c:\program files\sub dir\program.exe name
c:\program files\sub dir\program name.exe


As to why it asks this way - so that it doesn't break programs that can't handle spaces in file names correctly.


Edit
It appears the the "Run" command doesn't behave like this - it must have some extra logic added to handle this exact case. However trying to run from anywhere else - including using the CreateProcess function directly which is what most applications would use to run a command.


The see this behavior in action:



  1. Open an administrative Command Prompt

  2. Run: copy c:\Windows\System32\notepad.exe c:\program.exe

  3. Run: c:\Program Files\Internet Explorer\iexplore.exe

  4. Notepad will open telling you it can't find Files\Internet Explorer\iexplore.exe

  5. Type c:\Program Files\Internet Explorer\iexplore.exe into the Run option and IE will open correctly.


Edit 2 In the case of your C:\program files\internet.exe example; I believe this is the command line interpreter getting in the way. It tries to process and tokenize the command line into parameters broken up by spaces. So it takes C:\program as the first token and interprets that as the program name as the rest as parameters.


For a test I created a small application that calls CreateProcess directly and it behaves exactly as documented. Your C:\program files\internet.exe example will launch C:\program files\internet.exe. So it appears that the behavior depends on exactly how the command is run - something may be processing the command line before passing it to CreateProcess.


Example program:


#include 
void main()
{
STARTUPINFO si = {0};
si.cb= sizeof(si);
PROCESS_INFORMATION pi = {0};
CreateProcess(NULL, "c:\\program files\\internet explorer\\iexplore.exe",
NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
}

No comments:

Post a Comment

linux - How to SSH to ec2 instance in VPC private subnet via NAT server

I have created a VPC in aws with a public subnet and a private subnet. The private subnet does not have direct access to external network. S...