cmd.exe 使用 notepad.exe 打开文件路径而不是将其解释为参数

cmd.exe opens the file path with notepad.exe instead of interpreting it as an argument

给定 cmd.exe,我观察到一个我不理解的特殊情况, 似乎无法解释:

这个简单的命令如预期的那样执行:

> type ..\..\..\..\..\..\windows\win.ini
; for 16-bit app support
[fonts]
[extensions]
[mci extensions]
[files]
[Mail]
MAPI=1

但是这样做会发生什么?那么,它用给定的文件打开记事本 并且 shell 被阻止,直到记事本再次关闭:

> cmd.exe /c "type ..\..\..\..\..\..\windows\win.ini"

另一方面,这三个变体的行为符合某些人的预期(如第一个示例):

> cmd.exe /c type ..\..\..\..\..\..\windows\win.ini
...
> cmd.exe /c "type" "..\..\..\..\..\..\windows\win.ini"
...
> cmd.exe /c "type C:\windows\win.ini"
...

要打开记事本,也可以只给出文件名。如果仅给出路径,似乎 cmd.exe 使用默认程序打开文件:

> ..\..\..\..\..\..\windows\win.ini
> C:\windows\win.ini

所以,似乎 cmd.exe 将给定的命令解释为两个命令,并且只“执行”第二个命令(打开文件,之前的所有内容都被忽略)。此外,路径似乎必须是相对的。我现在的问题是,为什么以及在什么情况下会发生这种行为。请注意,type 只是一个示例。它也适用于 echopingipconfig、...


如果您已经喜欢这个行为,让我们再添加一个:

> cmd.exe /c "echo a > output.txt ..\..\..\..\..\..\windows\win.ini"
> type output.txt
a  ..\..\..\..\..\..\windows\win.ini

如果您在没有 cmd.exe \c 的情况下执行此操作,则会另外引入一个换行符:

> echo a > output2.txt ..\..\..\..\..\..\windows\win.ini
> type output2.txt
a
..\..\..\..\..\..\windows\win.ini

作为 Linux 用户,我只是对 shell 的不直观感到困惑。是否有一些文档说明为什么会这样,以及如何防止这种行为(不删除 cmd.exe /c 部分)?

我偶然发现了一个博客-post 详细分析了我问题第一部分的行为:https://hackingiscool.pl/cmdhijack-command-argument-confusion-with-path-traversal-in-cmd-exe/

基本上,给出以下命令:

> cmd.exe /c "type ..\..\..\..\..\Windows\System32\ipconfig.exe"

Windows 将 type .. 解释为“目录”,然后像 ..\ 一样多次进入父目录,直到到达驱动器根目录。使用这个确切位置,我们可以指向任意已知文件或可执行文件。给定一个路径,cmd.exe 检测到此位置有一个文件,因此执行找到的可执行文件而不是按最初预期的方式解释命令。