https://download.microsoft.com/download/5/8/9/58911986-D4AD-4695-BF63-F734CD4DF8F2/ws-commands.pdf
Cmd.exe
states:
Unicode here means of course Windows NT’s native UTF-16LE encoding.
Parameter Description … … /a Formats internal command output to a pipe or a file as American National Standards Institute (ANSI). /u Formats internal command output to a pipe or a file as Unicode.
Cmd.exe
.
Start the Command Processor
Cmd.exe
, then execute
the following command lines:
CHDIR /D "%PUBLIC%" 1>comspec.bat "%COMSPEC%" /U /D /C ECHO PAUSE DIR comspec.bat TYPE comspec.bat CALL .\comspec.batNote: the command lines can be copied and pasted as block into a Command Processor window.
Volume in drive C has no label. Volume Serial Number is 1957-0427 Directory of C:\Users\Public 04/27/2018 08:15 PM 14 comspec.bat 1 File(s) 14 bytes 0 Dir(s) 9,876,543,210 bytes free A U S E 'P' is not recognized as an internal or external command, operable program or batch file.The text file
comspec.bat
contains 14 bytes in 7
UTF-16LE
code units, the string PAUSE
plus a
CR/LF
pair – contrary to Microsoft’s own
recommendation the Command Processor
writes no
Byte Order Mark!
OUCH¹: the internal
Type
command fails to display
UTF-16LE
encoded files without
Byte Order Mark
properly!
OUCH²: (the internal
Call
command of) the Command Processor
fails to execute batch scripts in Windows NT’s
native
UTF-16LE
encoding!
Open the batch script comspec.bat
with
NotePad.exe
, press the
Ctrl S keyboard
shortcut to save it unchanged and exit the text editor:
NOTEPAD.EXE comspec.bat
Repeat the last 3 commands from step 1.:
DIR comspec.bat TYPE comspec.bat CALL .\comspec.bat
Volume in drive C has no label.
Volume Serial Number is 1957-0427
Directory of C:\Users\Public
04/27/2018 08:15 PM 16 comspec.bat
1 File(s) 16 bytes
0 Dir(s) 9,876,543,210 bytes free
PAUSE
'■P' is not recognized as an internal or external command,
operable program or batch file.
Note: NotePad.exe
silently added a
Byte Order Mark,
the batch script comspec.bat
now contains 16 bytes in 8
UTF-16LE
code units.
OUCH³: while the internal
Type
command displays the file comspec.bat
properly now,
(the internal
Call
command of) the Command Processor
still fails to execute it!
Cmd.exe
states:
Note: this feature enables (unprivileged) users to tamper with
Parameter Description … … /d Disables execution of AutoRun commands. […]
If you don't specify /d […], Cmd.exe looks for the following registry subkeys:
If one or both registry subkeys are present, they're executed before all other variables.
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun\REG_SZ
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun\REG_EXPAND_SZ
Logonscripts configured by their (privileged) administrators who are unaware of the pitfalls demonstrated below!
AutoRuncommands are executed whenever a batch script is started with one of the Win32 functions
ShellExecute()
.
ShellExecuteEx()
or
WinExec()
,
for example from Windows graphical shell
Explorer.exe
per double-click
or the Runentry of its Start Menu:
Create the text file
comspec.bat
with the following content in an arbitrary, preferable empty
directory:
@REM Copyleft © 1997-2024, Stefan Kanthak <stefan.kanthak@nexgo.de>
@SET /P =%CMDCMDLINE%
@EXIT /B
Execute the batch script comspec.bat
created in
step 1. per double-click:
C:\Windows\system32\cmd.exe /c ""C:\Users\Stefan\Desktop\comspec.bat" "Oops:
Explorer.exe
fails to provide
the parameter /d
to disable the execution of
AutoRuncommands when starting batch scripts!
Display the
file types
associated with the extensions .bat
and
.cmd
and their command line templates:
ASSOC .bat FTYPE batfile ASSOC .cmd FTYPE cmdfileNote: the command lines can be copied and pasted as block into a Command Processor window.
.bat=batfile batfile="%1" %* .cmd=cmdfile cmdfile="%1" %*
ShellExecute()
and
ShellExecuteEx()
retrieve these command line templates, replace the various tokens
%‹digit›
,
%‹letter›
and %*
with file
or path names and arguments, then feed the completed command line to
one of the
CreateProcess()
,
CreateProcessAsUser()
,
CreateProcessWithLogonW()
or
CreateProcessWithTokenW()
functions.
Launching Applications (ShellExecute, ShellExecuteEx, SHELLEXECUTEINFO)
The documentation for the
CreateProcess()
function states:
To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following arguments: /c plus the name of the batch file.Due to the security vulnerability CVE-2014-0315 alias MS14-019 I discovered and reported at the MSRC about 11 years ago, which was fixed with security update 2922229 some months later, the following note was added several years later:
Important
The MSRC engineering team advises against this. See MS14-019 – Fixing a binary hijacking via .cmd or .bat file for more details.
AutoRuncommands when starting batch scripts, change the command line template registered with the file types alias Programmatic Identifiers
batfile
and cmdfile
associated with the
extensions .bat
and .cmd
from its default
value "%1" %*
to
C:\Windows\System32\Cmd.exe /D /C "%1" %*
:
FTYPE batfile=%COMSPEC% /D /C "%1" %* FTYPE cmdfile=%COMSPEC% /D /C "%1" %*Note: the internal
Ftype
command must be executed with administrative access rights.
If you still have not abandonded the bad habit of
using the Protected Administrator account created
during Windows Setup you also need to change the
command line templates registered for the RunAs
verb:
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\batfile\Shell\Open\Command]
@="C:\\Windows\\System32\\Cmd.exe /D /C \"%L\" %*"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\batfile\Shell\RunAs\Command]
@="C:\\Windows\\System32\\Cmd.exe /D /C \"%L\" %*"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\cmdfile\Shell\Open\Command]
@="C:\\Windows\\System32\\Cmd.exe /D /C \"%L\" %*"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\cmdfile\Shell\RunAs\Command]
@="C:\\Windows\\System32\\Cmd.exe /D /C \"%L\" %*"
CAVEAT: thanksto the Merged View of HKEY_CLASSES_ROOT introduced with Windows 2000 this remediation but fails if the unnamed default registry entry with the default command line template is present in the corresponding registry key
HKEY_CURRENT_USER\Software\Classes\‹file type›\Shell\‹verb›\Command
of a user account!
When the command shell processes a pipe (|) symbol, it actually runs both commands specified simultaneously.Note: internal commands except
Rem
with an argument other than /?
, i.e.
Assoc
,
Break
,
Call
,
Cd
,
Chdir
,
Cls
,
Color
,
Copy
,
Date
,
Del
,
Dir
,
Dpath
(undocumented),
Echo
,
Endlocal
,
Erase
,
Exit
,
For
,
Ftype
,
Goto
,
If
,
Keys
(undocumented),
Md
,
Mkdir
,
Mklink
,
Move
,
Path
,
Pause
,
Popd
,
Prompt
,
Pushd
,
Rd
,
Ren
,
Rename
,
Rmdir
,
Set
,
Setlocal
,
Shift
,
Start
,
Time
,
Title
,
Type
,
Ver
,
Verify
and
Vol
,
are executed in a child
Cmd.exe
process!
The TechNet article Using command redirection operators states too:
Using the pipe operator (|)The documentation for the internalThe pipe operator (|) takes the output (by default, STDOUT) of one command and directs it into the input (by default, STDIN) of another command. For example, the following command sorts a directory:
dir | sort
In this example, both commands start simultaneously, but then the sort command pauses until it receives the dir command's output. The sort command uses the dir command's output as its input, and then sends its output to handle 1 (that is, STDOUT).
Rem
command of the Command Processor
states:
- You cannot use a redirection character (< or >) or pipe (|) in a batch file comment.
Start the Command Processor, then run the following command lines to show proper but undocumented behaviour:
ECHO %CMDCMDLINE^% | MORE.COM 1>&2 ECHO %CMDCMDLINE^% | ECHO %CMDCMDLINE^%Note: the command lines can be copied and pasted as block into a Command Processor window.
C:\windows\system32\cmd.exe /S /D /c" ECHO %CMDCMDLINE% " C:\windows\system32\cmd.exe /S /D /c" ECHO %CMDCMDLINE% 1>&2" C:\windows\system32\cmd.exe /S /D /c" ECHO %CMDCMDLINE%"Note: the Command Processor executes each internal command of these pipelines in a separate child
Cmd.exe
process
– fortunately with the parameter /D
to disable
the execution of AutoRuncommands!
Execute the following command lines to show more proper behaviour:
1>&2 ECHO %CMDCMDLINE^% | REM ECHO %CMDCMDLINE^% | REM ECHO %CMDCMDLINE^% | REM /?
C:\Windows\system32\cmd.exe /S /D /c" ECHO %CMDCMDLINE% 1>&2" The process tried to write to a nonexistent pipe. Records comments (remarks) in a batch file or CONFIG.SYS. REM [comment]Note: on the right hand side of a pipeline output redirection works with the internal
Rem
command.
Execute the following command lines to show undocumented behaviour:
REM /? | ECHO %CMDCMDLINE^% REM | ECHO 1>&2 %CMDCMDLINE^%
C:\Windows\system32\cmd.exe /S /D /c" ECHO %CMDCMDLINE%"Note: redirection characters can’t be used with the internal
Rem
command and an argument other than /?
outside of batch
scripts too – REM | …
is
not recognised as a pipeline.
Execute the following command lines to show the first undocumented misbehaviour:
SET COMSPEC=%SystemRoot%\System32\Reg.exe DPATH | KEYS SET COMSPEC=. BREAK | EXIT SET COMSPEC=NUL: ECHO | REMNote: the Registry Console Tool Reg.exe is only (ab)used as
canaryhere.
ERROR: Invalid Argument/Option - '/S'. Type "REG /?" for usage. ERROR: Invalid Argument/Option - '/S'. Type "REG /?" for usage. '.' is not recognized as an internal or external command, operable program or batch file. 'NUL:' is not recognized as an internal or external command, operable program or batch file.OUCH¹: the Command Processor evaluates the (user-controlled) environment variable
COMSPEC
and
tries to execute the file, directory or device it points to as
child process of itself!
CAVEAT: (ab)using an environment variable to locate an executable file is a well-known weakness, documented as CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') and CWE-73: External Control of File Name or Path in the CWE™; it allows well-known attacks like CAPEC-13: Subverting Environment Variable Values documented in the CAPEC™.
Note: properly implemented, the
Command Processor would fetch its own
path name with the Win32 function
GetModuleFileName()
instead to (ab)use the value of a user-controlled environment
variable!
Execute the following command lines to show the second undocumented misbehaviour:
SET COMSPEC=%RANDOM% SET PATHEXT DPATH | KEYS SET PATHEXT=NUL: BREAK | EXIT SET PATHEXT=%SystemRoot%\System32\Reg.exe ECHO | REM SET PATHEXT= SHIFT | VER
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
'.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC' is not recognized as an internal or external command,
operable program or batch file.
'NUL:' is not recognized as an internal or external command,
operable program or batch file.
'C:\Windows\System32\Reg.exe' is not recognized as an internal or external command,
operable program or batch file.
'' is not recognized as an internal or external command,
operable program or batch file.
OUCH²: if the environment variable
COMSPEC
points to a non-existent path, the
Command Processor tries to execute
the file, directory or device the (user-controlled) environment
variable PATHEXT
points to as child process of itself,
even if this environment variable is missing – and fails
always, independent of its value!
Finally execute the following command lines to show the bug:
SET COMSPEC= DPATH | KEYSOUCH³: the Command Processor crashes with an access violation exception 0xC0000005 reading address
NULL
when an arbitrary internal command
is executed in a pipeline while the environment variable
COMSPEC
is missing!
Note: the crash induced by the absence of the
environment variable COMSPEC
is yet another
well-known weakness, documented as
CWE-248: Uncaught Exception
and
CWE-476: NULL Pointer Dereference
in the
CWE™.
(Optional) If you have the Debugging Tools for Windows installed, execute the Command Processor under the debugger:
CDB.EXE /C g;q /G /g "%COMSPEC%" /D /C SET COMSPEC=^& EXIT ^| EXITNote: if necessary, see the MSDN articles Debugging Using CDB and NTSD and CDB Command-Line Options for an introduction.
Microsoft (R) Windows Debugger Version 6.11.0001.404 X86 Copyright (c) Microsoft Corporation. All rights reserved. CommandLine: "C:\Windows\system32\cmd.exe" /D /C SET COMSPEC=& EXIT | EXIT Symbol search path is: srv* Executable search path is: ModLoad: 4ac70000 4acbc000 cmd.exe ModLoad: 779c0000 77b40000 ntdll.dll ModLoad: 75610000 75720000 C:\Windows\syswow64\kernel32.dll ModLoad: 752d0000 75317000 C:\Windows\syswow64\KERNELBASE.dll ModLoad: 75540000 755e1000 C:\Windows\syswow64\ADVAPI32.DLL ModLoad: 757a0000 7584c000 C:\Windows\syswow64\msvcrt.dll ModLoad: 77420000 77439000 C:\Windows\SysWOW64\sechost.dll ModLoad: 77300000 773f0000 C:\Windows\syswow64\RPCRT4.dll ModLoad: 750e0000 75140000 C:\Windows\syswow64\SspiCli.dll ModLoad: 750d0000 750dc000 C:\Windows\syswow64\CRYPTBASE.dll ModLoad: 73d60000 73d67000 C:\Windows\SysWOW64\WINBRAND.dll ModLoad: 76f60000 77060000 C:\Windows\syswow64\USER32.dll ModLoad: 764f0000 76580000 C:\Windows\syswow64\GDI32.dll ModLoad: 76580000 7658a000 C:\Windows\syswow64\LPK.dll ModLoad: 76690000 7672d000 C:\Windows\syswow64\USP10.dll ModLoad: 76630000 76690000 C:\Windows\SysWOW64\IMM32.DLL ModLoad: 75470000 7553e000 C:\Windows\syswow64\MSCTF.dll (2f60.32bc): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=00000000 ebx=00002000 ecx=00551210 edx=00000002 esi=005511a8 edi=005511a8 eip=4ac7247d esp=002dfa00 ebp=002dfa0c iopl=0 nv up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206 *** ERROR: Module load completed but symbols could not be loaded for cmd.exe cmd+0x247d: 4ac7247d 668b08 mov cx,word ptr [eax] ds:002b:00000000=???? 0:000:x86> cdb: Reading initial command 'g;q' (2f60.32bc): Access violation - code c0000005 (!!! second chance !!!) quit:
Microsoft (R) Windows Debugger Version 6.1.7601.17514 AMD64 Copyright (c) Microsoft Corporation. All rights reserved. CommandLine: "C:\Windows\system32\cmd.exe" "/C SET COMSPEC=& EXIT | EXIT" Symbol search path is: srv* Executable search path is: ModLoad: 00000000`4aa90000 00000000`4aae9000 cmd.exe ModLoad: 00000000`77800000 00000000`7799f000 ntdll.dll ModLoad: 00000000`775e0000 00000000`776ff000 C:\Windows\system32\kernel32.dll ModLoad: 000007fe`fd510000 000007fe`fd577000 C:\Windows\system32\KERNELBASE.dll ModLoad: 000007fe`fd980000 000007fe`fda5b000 C:\Windows\system32\ADVAPI32.DLL ModLoad: 000007fe`fe1c0000 000007fe`fe25f000 C:\Windows\system32\msvcrt.dll ModLoad: 000007fe`fe260000 000007fe`fe27f000 C:\Windows\SYSTEM32\sechost.dll ModLoad: 000007fe`ff250000 000007fe`ff37c000 C:\Windows\system32\RPCRT4.dll ModLoad: 000007fe`f7520000 000007fe`f7528000 C:\Windows\system32\WINBRAND.dll ModLoad: 00000000`77700000 00000000`777fb000 C:\Windows\system32\USER32.dll ModLoad: 000007fe`fe350000 000007fe`fe3b7000 C:\Windows\system32\GDI32.dll ModLoad: 000007fe`fd970000 000007fe`fd97e000 C:\Windows\system32\LPK.dll ModLoad: 000007fe`fe280000 000007fe`fe34b000 C:\Windows\system32\USP10.dll ModLoad: 000007fe`fdf10000 000007fe`fdf3e000 C:\Windows\system32\IMM32.DLL ModLoad: 000007fe`ff9c0000 000007fe`ffacb000 C:\Windows\system32\MSCTF.dll (5f8.2558): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. *** ERROR: Module load completed but symbols could not be loaded for cmd.exe cmd+0x2bff: 00000000`4aa92bff 66f2af repne scas word ptr [rdi] 0:000> cdb: Reading initial command 'g;q' (5f8.2558): Access violation - code c0000005 (!!! second chance !!!) quit:
COMSPEC
is a well-known weakness,
documented as
CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
and
CWE-73: External Control of File Name or Path
in the
CWE™;
it allows well-known attacks like
CAPEC-13: Subverting Environment Variable Values
documented in the
CAPEC™.
The crash induced by the absence of the (user-controlled)
environment variable COMSPEC
is yet another
well-known weakness, documented as
CWE-248: Uncaught Exception
and
CWE-476: NULL Pointer Dereference
in the
CWE™.
This at least 31 year old bug (really:
absolute beginner’s programming error) can
trivially be (ab)used to conduct a denial of service
attack
against the Command Processor and crash
it upon launch, thus disabling its use for single or all users of a
machine:
REGEDIT4
[HKEY_CURRENT_USER\Software\Microsoft\Command Processor]
"AutoRun"="SET COMSPEC=& EXIT | EXIT"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]
"AutoRun"="SET COMSPEC=& EXIT | EXIT"
%
and
!
are used for (delayed)
expansion of environment variables at the (interactive) command
prompt as well as in batch scripts – where the single
%
is used for parameter expansion.
Create the text file
com!spec.bat
with the following content in an arbitrary, preferable empty
directory:
REM Copyleft © 1997-2024, Stefan Kanthak <stefan.kanthak@nexgo.de>
SETLOCAL DISABLEDELAYEDEXPANSION
CALL :com%spec
SETLOCAL ENABLEDELAYEDEXPANSION
:comspec
DIR "%~f0"
ECHO comspec%
ECHO com%spec
ECHO %comspec
ECHO !%!
ECHO comspec!
%ECHO com!spec
ECHO !comspec
MKDIR !!
ECHO% !
RMDIR !!
!PAUSE
EXIT /B
Note: the single exclamation mark (or a single
percent sign) can be placed anywhere in the filename!
Start the batch script com!spec.bat
created in
step 1. per double-click:
REM Copyleft © 1997-2024, Stefan Kanthak <stefan.kanthak@nexgo.de> SETLOCAL DISABLEDELAYEDEXPANSION CALL :comspec DIR "C:\Users\Stefan\Desktop\com!spec.bat" Volume in drive C has no label. Volume Serial Number is 1957-0427 Directory of C:\Users\Stefan\Desktop 04/27/2018 08:15 PM 320 com!spec.bat 1 File(s) 320 bytes 0 Dir(s) 9,876,543,210 bytes free ECHO comspec comspec ECHO comspec comspec ECHO comspec comspec ECHO !! !! ECHO comspec! comspec! ECHO com!spec com!spec ECHO !comspec !comspec MKDIR !! ECHO ! ! RMDIR !! !PAUSE '!PAUSE' is not recognized as an internal or external command, operable program or batch file. EXIT /B SETLOCAL ENABLEDELAYEDEXPANSION DIR "C:\Users\Stefan\Desktop\com!spec.bat" Volume in drive C has no label. Volume Serial Number is 1957-0427 Directory of C:\Users\Stefan\Desktop File Not Found ECHO comspec comspec ECHO comspec comspec ECHO comspec comspec ECHO !! ECHO is on. ECHO comspec! comspec ECHO com!spec comspec ECHO !comspec comspec MKDIR !! The syntax of the command is incorrect. ECHO ! ECHO is on. RMDIR !! The syntax of the command is incorrect. !PAUSE Press any key to continue . . . EXIT /BOUCH¹: in batch scripts, the Command Processor strips single percent signs from the command line before it is echoed and executed!
OUCH²: when delayed environment variable expansion is enabled in batch scripts, the Command Processor strips all exclamation marks which don’t surround the name of an environment variable from the command line after it is echoed and before it is executed!
Command Search Sequence:
When a command is submitted for execution (either by typing or as part of a script), the shell performs the following actions:Note: unfortunately there’s no explicit statement when input and output redirection are processed.[…]
All parameter and environment variable references are resolved (see chapter 3).
Compound commands are split into individual commands and each is then individually processed according to the following steps (see the section "Running Multiple Commands" for details of compound commands). Continuation lines are also processed at this step.
The command is split into the command name and any arguments.
If the command name does not specify a path, the shell attempts to match the command name against the list of internal shell commands. If a match is found, the internal command executes. Otherwise, the shell continues to step 5.
If the command name specifies a path, the shell searches the specified path for an executable file matching the command name. If a match is found, the external command (the executable file) executes. If no match is found, the shell reports an error and command processing completes.
If the command name does not specify a path, the shell searches the current directory for an executable file matching the command name. If a match is found, the external command (the executable file) executes. If no match is found, the shell continues to step 7.
The shell now searches each directory specified by the PATH environment variable, in the order listed, for an executable file matching the command name. If a match is found, the external command (the executable file) executes. If no match is found, the shell reports an error and command processing completes.
Create the text file
comspec.bat
with the following content in an arbitrary, preferable empty
directory:
@REM Copyleft © 1997-2024, Stefan Kanthak <stefan.kanthak@nexgo.de>
@SETLOCAL ENABLEDELAYEDEXPANSION
@ECHO %%0 com %~0 spec
@ECHO %%1 com %~1 spec
@ECHO %%2 com %~2 spec
@ECHO %%3 com %~3 spec
@ECHO %%4 com %~4 spec
@ECHO %%5 com %~5 spec
@ECHO %%6 com %~6 spec
@ECHO %%7 com %~7 spec
@ECHO %%8 com %~8 spec
@ECHO %%9 com %~9 spec
@EXIT /B
Start the Command Processor
Cmd.exe
, then execute
the batch script comspec.bat
created in step 1.
via the following command line with 9 properly quoted arguments
containing special characters:
.\comspec.bat "!!" "&" "&&" "0<." "1>." "^" "^^" "|" "||"
%0 com .\comspec.bat spec %1 com spec %2 com 'spec' is not recognized as an internal or external command, operable program or batch file. %3 com 'spec' is not recognized as an internal or external command, operable program or batch file. Access denied Access denied %6 com spec %7 com ^ spec 'spec' is not recognized as an internal or external command, operable program or batch file.OOPS: input and output redirection are processed after parameter and environment variable expansion!
OUCH¹: the
Command Processor fails to execute the
last ECHO
command – its output
%9 com is missing!
Execute the batch script comspec.bat
created in
step 1. a second time with the same 9 arguments, now unquoted
and their special characters properly escaped:
.\comspec.bat ^!^! ^& ^&^& 0^<. 1^>. ^^ ^^^^ ^| ^|^|
%0 com .\comspec.bat spec %1 com spec %2 com 'spec' is not recognized as an internal or external command, operable program or batch file. %3 com 'spec' is not recognized as an internal or external command, operable program or batch file. Access denied Access denied %6 com spec 'spec' is not recognized as an internal or external command, operable program or batch file.OUCH²: now the eighth and tenth
ECHO
fail execution!
�
OUCH³: � OUCH⁴: � OUCH⁵: � OUCH⁶: � OUCH⁷: �
Assoc
command of the Command Processor
states:
Displays or modifies file name extension associations. […]assoc [<.ext>[=[<FileType>]]]
[…]
Remarks
To remove the file type association for a file name extension, add a white space after the equal sign by pressing the SPACEBAR.
Start the Command Processor
Cmd.exe
, then execute
the following command lines to display some non-associations:
ASSOC batfile ASSOC batfile\DefaultIcon ASSOC batfile\Shell\Open\Command ASSOC CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}\InprocServer32
batfile=Windows Batch File batfile\DefaultIcon=%SystemRoot%\System32\imageres.dll,-68 batfile\Shell\Open\Command="%1" %* CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}\InprocServer32=%ProgramFiles%\Windows Defender\MpOav.dllOops¹: the internal
Assoc
command reads not just associations, but also the values of unnamed
default registry entries in arbitrary registry keys of the
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
registry branch.
Start the Command Processor
Cmd.exe
with
administrative access rights, then execute the following command
lines to write, display and remove some non-associations, also prove
the highlighted statement of the documentation cited above wrong:
ASSOC CLSID ASSOC CLSID=%RANDOM% ASSOC CLSID ASSOC CLSID= ASSOC CLSID
File association not found for extension CLSID CLSID=12345 CLSID=12345 File association not found for extension CLSIDOops²: the internal
Assoc
command reads and writes not just associations, but also the
values of unnamed default registry entries in arbitrary registry
keys in the HKEY_LOCAL_MACHINE\SOFTWARE\Classes
registry branch.
Oops³: contrary to the highlighted statement
of the documentation cited above, the internal
Assoc
command requires no white space after the equal
sign to remove a value!
Call
,
Del
alias
Erase
,
Move
,
Ren
alias
Rename
and
Type
commands of the Command Processor
state:
Calls one batch program from another without stopping the parent batch program. […]
Deletes one or more files. This command is the same as the erase command.
Moves one or more files from one directory to another directory.
Renames files or directories. This command is the same as the rename command.
Displays the contents of a text file. Use the type command to view a text file without modifying it.
Start the Command Processor
Cmd.exe
, then create
the subdirectory comspec
in the public TMP
directory of the system and remove it, then create a file
comspec
there and (try to) erase it:
MKDIR "%SystemRoot%\Temp\comspec" RMDIR "%SystemRoot%\Temp\comspec" COPY "%COMSPEC%" "%SystemRoot%\Temp\comspec" ERASE "%SystemRoot%\Temp\comspec"Note: the command lines can be copied and pasted as block into a Command Processor window.
1 file(s) copied.
The system cannot find the file C:\Windows\Temp\comspec.
OOPS: WTF?
Verify that the file %SystemRoot%\Temp\comspec
created
in step 1. really exists, then overwrite it and (try to)
display its content, (try to) execute it, (try to) rename it and
(try to) move it into your current (working) directory:
MKDIR "%SystemRoot%\Temp\comspec" COPY /Y NUL: "%SystemRoot%\Temp\comspec" TYPE "%SystemRoot%\Temp\comspec" CALL "%SystemRoot%\Temp\comspec" RENAME "%SystemRoot%\Temp\comspec" COMSPEC MOVE "%SystemRoot%\Temp\comspec"
A subdirectory or file C:\Windows\Temp\comspec already exists. 1 file(s) copied. Access denied Access denied Access denied Access deniedOUCH: the Command Processor seems to perform a (superfluous) access check on files!
Display the access permissions of the file
%SystemRoot%\Temp\comspec
created in step 1.:
ICACLS.EXE "%SystemRoot%\Temp\comspec"
C:\Windows\Temp\comspec NT AUTHORITY\SYSTEM:(I)(F)
AMNESIAC\Stefan:(I)(F)
BUILTIN\Administrators:(I)(F)
Successfully processed 1 files; Failed processing 0 files
Note: your user account
%COMPUTERNAME%\%USERNAME%
has full access to this file,
inherited from the parent directory!
Create the text file comspec.c
with the following
content in an arbitrary, preferable empty directory:
// Copyleft © 2004-2024, Stefan Kanthak <stefan.kanthak@nexgo.de>
#define STRICT
#define UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
__declspec(noreturn)
VOID CDECL wmainCRTStartup(VOID)
{
WCHAR szBuffer[MAX_PATH];
DWORD dwBuffer = GetWindowsDirectory(szBuffer, sizeof(szBuffer) / sizeof(*szBuffer));
DWORD dwError = ERROR_SUCCESS;
if (dwBuffer == 0UL)
dwError = GetLastError();
else
{
memcpy(szBuffer + dwBuffer, L"\\Temp\\comspec", sizeof(L"\\Temp\\comspec"));
if (!DeleteFile(szBuffer))
dwError = GetLastError();
}
ExitProcess(dwError);
}
Compile and link the source file comspec.c
created in
step 4.:
SET CL=/Oi /W4 /Zl SET LINK=/ENTRY:wmainCRTStartup /NODEFAULTLIB /SUBSYSTEM:CONSOLE CL.EXE comspec.c kernel32.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. comspec.c Microsoft (R) Incremental Linker Version 10.00.40219.386 Copyright (C) Microsoft Corporation. All rights reserved. /ENTRY:mainCRTStartup /NODEFAULTLIB /SUBSYSTEM:CONSOLE /out:comspec.exe comspec.obj kernel32.lib
Execute the console application comspec.exe
built in
step 5. and evaluate its exit code:
.\comspec.exe CERTUTIL.EXE /ERROR %ERRORLEVEL%
0x0 (WIN32: 0 ERROR_SUCCESS) -- 0 (0) Error message text: The operation completed successfully. CertUtil: -error command completed successfully.
Finally verify that the file %SystemRoot%\Temp\comspec
created in step 1. doesn’t exist any more:
MKDIR "%SystemRoot%\Temp\comspec" RMDIR "%SystemRoot%\Temp\comspec"
Call
command of the Command Processor
states:
Calls one batch program from another without stopping the parent batch program. […]Note
Call has no effect at the command prompt when it is used outside of a script or batch file.
Start the Command Processor
Cmd.exe
in an
arbitrary, preferable empty directory, then execute the following
single command line:
CALL :EOF
Invalid attempt to call batch label outside of batch script.Oops: the internal
Call
command yields at least an error message when used at the
(interactive) command prompt.
Execute another single command line:
CALL winrm.vbs
Call
command has effect at the (interactive) command prompt outside of a
script or batch program and calls not just batch programs – it
acts similar to the internal
Start
command and evaluates the association of file types to file
extensions as well as the environment variable PATH
!
Display the file type of the file extension .vbs
and
its associated command line template:
ASSOC .vbs FTYPE VBSFile
.vbs=VBSFile VBSFile="%SystemRoot%\System32\WScript.exe" "%1" %*
Optionally execute the following command lines, then close the windows of Editor and WordPad:
ASSOC .ini FTYPE inifile CALL system.ini ASSOC .rtf FTYPE rtffile CALL license.rtfNote: the command lines can be copied and pasted as block into a Command Processor window.
.ini=inifile inifile=%SystemRoot%\system32\NOTEPAD.EXE %1 .rtf=rtffile rtffile="%ProgramFiles%\Windows NT\Accessories\WORDPAD.EXE" "%1"
PATH
is used to locate
executable files, standard input redirection and the internal
Type
command of the Command Processor use
the undocumented environment variable DPATH
to locate
(data) files; it is queried and set with the undocumented internal
Dpath
command, similar to the internal
Path
command.
Start the Command Processor
Cmd.exe
, then execute
the following command line:
DPATH /?
Allows programs to open data files in specified directories as if they were in the current directory. APPEND [[drive:]path[;...]] [/X[:ON | :OFF]] [/PATH:ON | /PATH:OFF] [/E] APPEND ; [drive:]path Specifies a drive and directory to append. /X:ON Applies appended directories to file searches and application execution. /X:OFF Applies appended directories only to requests to open files. /X:OFF is the default setting. /PATH:ON Applies the appended directories to file requests that already specify a path. /PATH:ON is the default setting. /PATH:OFF Turns off the effect of /PATH:ON. /E Stores a copy of the appended directory list in an environment variable named APPEND. /E may be used only the first time you use APPEND after starting up your system. Type APPEND ; to clear the appended directory list. Type APPEND without parameters to display the appended directory list.OOPS: the Command Processor is confused – an (external)
APPEND.EXE
command is not shipped with 64-bit editions of Windows!
OUCH: the internal Dpath
command has
a single argument, either a single semicolon or a
list of semicolon-separated directory names!
Execute the following command lines to show the true behaviour:
DPATH SET DPATH TYPE system.ini CLIP.EXE 0<system.ini DPATH %SystemRoot% SET DPATH TYPE system.ini CLIP.EXE 0<system.ini MORE.COM system.iniNote: the command lines can be copied and pasted as block into a Command Processor window.
DPATH=(null) Environment variable DPATH not defined The system cannot find the file system.ini. The system cannot find the file specified. DPATH=C:\Windows ; for 16-bit app support [386Enh] woafont=dosapp.fon EGA80WOA.FON=EGA80WOA.FON EGA40WOA.FON=EGA40WOA.FON CGA80WOA.FON=CGA80WOA.FON CGA40WOA.FON=CGA40WOA.FON [drivers] wave=mmdrv.dll timer=timer.drv [mci] Cannot access file C:\Users\Stefan\Desktop\system.ini
Echo
command of the Command Processor
states:
RemarksThe documentation for the internal[…]
When inside a block terminated by parentheses (
()
), both opening and closing parentheses must also be escaped using the caret (^
) immediately before each one. For example,This is ^(now^) correct
will correctly displayThis is (now) correct
.
If
command of the Command Processor
states:
RemarksOops: the example proves the highlighted statement wrong![…]
Examples
- You must use the else clause on the same line as the command after the if.
[…]
To delete the file Product.dat from the current directory or display a message if Product.dat is not found, type the following lines in a batch file:
IF EXIST Product.dat ( del Product.dat ) ELSE ( echo The Product.dat file is missing. )
Note
These lines can be combined into a single line as follows:
IF EXIST Product.dat (del Product.dat) ELSE (echo The Product.dat file is missing.)
Start the Command Processor
Cmd.exe
, then execute
the ECHO
command line from the documentation cited
above with only the inner closing parenthesis escaped:
(ECHO This is (also^) correct)
This is (also) correctOops;: contrary to the highlighted statement of the first documentation cited above, the inner opening parenthesis doesn’t need to be escaped!
Execute the following ECHO
command lines referencing an
environment variable with both, one or no inner parentheses escaped:
(ECHO %CommonProgramFiles^(x86^)% but fails to evaluate the variable!) (ECHO %CommonProgramFiles(x86^)% also fails to evaluate the variable!) (ECHO %CommonProgramFiles(x86)% fails miserably!)Note: the command lines can be copied and pasted as block into a Command Processor window.
%CommonProgramFiles(x86)% but fails to evaluate the variable!
%CommonProgramFiles(x86)% also fails to evaluate the variable!
"\Common" cannot be processed syntactically at this point.
OOPS: contrary to the highlighted statement of the
first documentation cited above, this example but fails!
OUCH: the last command line is reparsed after environment variable expansion and fails due to the expanded parentheses!
Execute an IF … ELSE …
command block that
evaluates the (system) environment variable
ProgramFiles(x86)
in its then
clause:
IF DEFINED ProgramFiles(x86) ( ECHO %ProgramFiles(x86)% comspec ) ELSE ( ECHO %ProgramFiles% )
"comspec)" cannot be processed syntactically at this point.
Combine the command block from step 1. into a single line:
IF DEFINED ProgramFiles(x86) (ECHO %ProgramFiles(x86)% comspec) ELSE (ECHO %ProgramFiles%)
"comspec)" cannot be processed syntactically at this point.
Invert the condition of the IF
clause and swap the
then
clause with the ELSE
clause:
IF NOT DEFINED ProgramFiles(x86) (ECHO %ProgramFiles%) ELSE (ECHO %ProgramFiles(x86)% comspec)
"comspec)" cannot be processed syntactically at this point.
Enable delayed (environment variable) expansion and repeat step 2. with exclamation marks instead of the percent signs:
SETLOCAL ENABLEDELAYEDEXPANSION (ECHO !CommonProgramFiles^(x86^)! is evaluated now!) (ECHO !CommonProgramFiles(x86^)! is evaluated now!) (ECHO !CommonProgramFiles(x86)! fails but miserably too!)
C:\Program Files (x86)\Common Files is evaluated now!
C:\Program Files (x86)\Common Files is evaluated now!
"!" cannot be processed syntactically at this point.
OUCH: the parser is severely broken – parentheses inside a pair of exclamation marks which surround the name of an environment variable don’t terminate an outer block!
Drop the (here superfluous) parentheses around the single command of
the ELSE
clause from step 5.:
IF NOT DEFINED ProgramFiles(x86) (ECHO %ProgramFiles%) ELSE ECHO %ProgramFiles(x86)%
C:\Program Files (x86)
Enable delayed (environment variable) expansion and escape the closing parenthesis:
SETLOCAL ENABLEDELAYEDEXPANSION IF DEFINED ProgramFiles(x86) (ECHO !ProgramFiles(x86^)!) ELSE (ECHO %ProgramFiles%)
C:\Program Files (x86)
For
command of the Command Processor
states:
Runs a specified command for each file in a set of files.OUCH: the highlighted parts but contradict each other –[…]
for {%%|%}<Variable> in (<Set>) do <Command> [<CommandLineOptions>]
[…]
Parameter Description {%%|%}<Variable> Required. Represents a replaceable parameter. Use a single percent sign (%) to carry out the for command at the command prompt. Use double percent signs (%%) to carry out the for command within a batch file. Variables are case sensitive, and they must be represented with an alphabetical value such as %A, %B, or %C. […]
Remarks
Using batch parameters
The following attributes apply to the for command:
To avoid confusion with the batch parameters %0 through %9, you can use any character for Variable except the numerals 0 through 9.
any characterallows more than just an
alphabeticalvalue alias (upper or lower case) letter!
Start the Command Processor
Cmd.exe
, then execute
the following command lines which use non-alphabetical
ASCII
characters for the variable:
FOR /F "Tokens=1-15" %! IN ("Exclamation Quote Hash Dollar Percent Ampersand Apostrophe Left_Parenthesis Right_Parenthesis Asterisk Plus Comma Minus Dot Slash") DO @ECHO %! %^" %# %$ %^% %^& %' %( %) %* %+ %, %- %. %/ FOR /F "Tokens=1-10" %0 IN ("Zero One Two Three Four Five Six Seven Eight Nine") DO @ECHO %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 FOR /F "Tokens=1-7" %: IN ("Colon Semicolon Less Equal Greater Question At") DO @ECHO %: %; %^< %= %^> %? %@ FOR /F "Tokens=1-6" %[ IN ("Left_Square_Bracket Backslash Right_Square_Bracket Caret Underline BackQuote") DO @ECHO %[ %\ %] %^^ %_ %` FOR /F "Tokens=1-4" %{ IN ("Left_Curly_Bracket Vertical_Bar Right_Curly_Bracket Tilde") DO @ECHO %{ %^| %} %~Note: the command lines can be copied and pasted as block into a Command Processor window.
Exclamation Quote Hash Dollar %% Ampersand Apostrophe Left_Parenthesis Right_Parenthesis Asterisk Plus Comma Minus Dot Slash Zero One Two Three Four Five Six Seven Eight Nine Colon Semicolon Less Equal Greater Question Left_Square_Bracket Backslash Right_Square_Bracket Caret Underline BackQuote Left_Curly_Bracket Vertical_Bar Right_Curly_Bracket TildeOops¹: with exception of the percent sign, all printable ASCII characters can be used for the variable!
Use some (arbitrary) characters for the variable:
FOR /F %€ IN ("Euro") DO @ECHO %€ FOR /F "Tokens=1-11" %¢ IN ("Cent Pound Currency Yen Broken_Bar Section Diaeresis Copyright Feminine_Ordinal Left_Angle Not") DO @ECHO %¢ %£ %¤ %¥ %¦ %§ %¨ %© %ª %« %¬ FOR /F %® IN ("Registered") DO @ECHO %® FOR /F %¶ IN ("Paragraph") DO @ECHO %¶
Euro Cent Pound Currency Yen Broken_Bar Section Diaeresis Copyright Feminine_Ordinal Left_Angle Not Registered ParagraphNote: a demonstration with (for example) Cyrillic, Greek or Hebrew letters is left as an exercise to the reader!
Execute the following command lines to show surprising behaviour:
FOR /F "Delims=" %? IN ("! !! "" & && <NUL: >NUL: ^ ^^ | ||") DO ECHO %? FOR /F "Tokens=1-10" %0 IN ("! !! "" & && <NUL: >NUL: ^ ^^ | ||") DO ECHO %0 %1 %2 %3 %4 %5 %6 %7 %8 %9
ECHO ! !! "" & && <NUL: >NUL: ^ | || ! !! "" & && <NUL: >NUL: | || ECHO ! !! "" & && <NUL: >NUL: ^ | || ! !! "" & && <NUL: >NUL: | ||Oops²: with exception of the caret, which keeps its function as escape character, unescaped special characters forwarded by the internal
For
command via %‹character›
are treated as
literals!
Caveat: in batch scripts with delayed expansion
enabled, exclamation marks are but removed!
For
command of the Command Processor
states:
The documentation for the Command Processor
- Parsing output
You can use the for /f command to parse the output of a command by making a back-quoted string from the Set between the parentheses. It is treated as a command line, which is passed to a child Cmd.exe. The output is captured into memory and parsed as if it is a file.
Cmd.exe
states:
Note: this feature enables (unprivileged) users to tamper with
Parameter Description … … /d Disables execution of AutoRun commands. […]
If you don't specify /d […], Cmd.exe looks for the following registry subkeys:
If one or both registry subkeys are present, they're executed before all other variables.
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun\REG_SZ
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun\REG_EXPAND_SZ
Logonscripts configured by their (privileged) administrators who are unaware of the pitfalls demonstrated below!
Start the Command Processor, then run
the following command lines to set the Windows
directory as
CWD, remove all
environment variables, verify that none are left and list the
environment variables of a child
Cmd.exe
process:
REM Copyright © 2004-2024, Stefan Kanthak <stefan.kanthak@nexgo.de> CHDIR /D "%SystemRoot%" FOR /F "Delims==" %? IN ('SET') DO @SET %?= SET FOR /F "Delims=" %? IN ('SET') DO @ECHO %?Note: the command lines can be copied and pasted as block into a Command Processor window.
COMSPEC=C:\Windows\system32\cmd.exe PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC PROMPT=$P$GOops: if the Command Processor does not inherit the environment variables
COMSPEC
, PATHEXT
and
PROMPT
from its parent process it sets them with default
values.
Execute the following (equivalent) command lines to show the command
line of the child
Cmd.exe
process:
FOR /F "Delims=" %? IN ('ECHO %CMDCMDLINE^%') DO @ECHO %? FOR /F "Delims= UseBackQ" %? IN (`ECHO %CMDCMDLINE^%`) DO @ECHO %?
C:\Windows\system32\cmd.exe /c ECHO %CMDCMDLINE% C:\Windows\system32\cmd.exe /c ECHO %CMDCMDLINE%OUCH¹: both
FOR /F … IN ('…') DO …
and
FOR /F "UseBackQ" … IN (`…`) DO …
execute their child
Cmd.exe
process only
with the parameter /c
, i.e. AutoRuncommands are executed!
Execute the following command lines to set an AutoRun
command
in the user’s Registry, start a child
Cmd.exe
process and
remove the AutoRun
command afterwards:
System32\REG.EXE ADD "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /V "AutoRun" /T REG_SZ /D "VERIFY" /F FOR /F "Delims=" %? IN ('EXIT') DO @ECHO %? System32\REG.EXE DELETE "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /V "AutoRun" /F
The operation completed successfully. VERIFY is off. The operation completed successfully.OUCH²: due to the missing parameter
/d
the child
Cmd.exe
process
executes the AutoRuncommand(s) set in the Registry which (can) create additional and typically unwanted output or perform arbitrary nefarious atrocities!
Finally execute the following command line to quit the Command Processor:
EXIT
AutoRunis a well-known weakness, documented as CWE-??: and CWE-??: in the CWE™; it allows well-known attacks like CAPEC-??: documented in the CAPEC™.
1>"‹file›" (‹command›)
FOR /F "UseBackQ" … IN ("‹file›") DO …
ERASE "‹file›"
instead of
FOR /F "UseBackQ" … IN (`‹command›`) DO …
or
FOR /F … IN ('‹command›') DO …
to prevent the execution of AutoRuncommands.
Note: this also saves the execution of a (hidden) instance of the Command Processor!
If
command of the Command Processor
states:
Performs conditional processing in batch programs.[…]
Remarks
- If you use defined, the following three variables are added to the environment: %errorlevel%, %cmdcmdline%, and %cmdextversion%.
%cmdcmdline% expands into the original command line that was passed to Cmd.exe prior to any processing by Cmd.exe. This assumes that there is not an existing environment variable with the name CMDCMDLINE—if there is, you will get the CMDCMDLINE value instead.
Start the Command Processor
Cmd.exe
, then display
the help text
of its internal
Set
command:
SET /?
Environment variable substitution has been enhanced as follows: […] May also specify substrings for an expansion. %PATH:~10,5% would expand the PATH environment variable, and then use only the 5 characters that begin at the 11th (offset 10) character of the expanded result. If the length is not specified, then it defaults to the remainder of the variable value. If either number (offset or length) is negative, then the number used is the length of the environment variable value added to the offset or length specified. %PATH:~-10% would extract the last 10 characters of the PATH variable. %PATH:~0,-2% would extract all but the last 2 characters of the PATH variable. […] If Command Extensions are enabled, then there are several dynamic environment variables that can be expanded but which don't show up in the list of variables displayed by SET. These variable values are computed dynamically each time the value of the variable is expanded. If the user explicitly defines a variable with one of these names, then that definition will override the dynamic one described below: %CD% - expands to the current directory string. %DATE% - expands to current date using same format as DATE command. %TIME% - expands to current time using same format as TIME command. %RANDOM% - expands to a random decimal number between 0 and 32767. %ERRORLEVEL% - expands to the current ERRORLEVEL value %CMDEXTVERSION% - expands to the current Command Processor Extensions version number. %CMDCMDLINE% - expands to the original command line that invoked the Command Processor.
Create the text file
comspec.bat
with the following content in an arbitrary, preferable empty
directory:
REM Copyleft © 2001-2024, Stefan Kanthak <stefan.kanthak@nexgo.de>
SET CMDCMDLINE=
IF NOT DEFINED CMDCMDLINE EXIT /B
SET CMDCMDLINE
REM '%CMDCMDLINE%'
:comspec
IF NOT "%CMDCMDLINE:~33,-3%" == "" GOTO :comspec
SET CMDCMDLINE
IF DEFINED CMDCMDLINE REM '%CMDCMDLINE%'
PAUSE
EXIT /B
Start the batch script comspec.bat
created in
step 2. per double-click:
REM Copyleft © 2001-2024, Stefan Kanthak <stefan.kanthak@nexgo.de>
SET CMDCMDLINE=
IF NOT DEFINED CMDCMDLINE EXIT /B
SET CMDCMDLINE
Environment variable CMDCMDLINE not defined
REM 'C:\Windows\System32\cmd.exe /c ""C:\Users\Stefan\Desktop\comspec.bat" "'
IF NOT "C:\Users\Stefan\Desktop\comspec.bat" == "" GOTO :comspec
IF NOT "" == "" GOTO :comspec
SET CMDCMDLINE
Environment variable CMDCMDLINE not defined
IF DEFINED CMDCMDLINE REM ''
PAUSE
Press any key to continue . . .
EXIT /B
OUCH¹: contrary to the highlighted statement
of the documentation cited above, the CMDCMDLINE
variable is not added to the environment!
OUCH²: extracting a substring from the
CMDCMDLINE
variable sets it to the resulting
substring, i.e. modifies the variable!
Overwrite the text file
comspec.bat
created in step 2. with the following content:
REM Copyleft © 2001-2024, Stefan Kanthak <stefan.kanthak@nexgo.de>
SET CMDCMDLINE=
IF NOT DEFINED CMDCMDLINE EXIT /B
SET CMDCMDLINE
REM '%CMDCMDLINE%'
SETLOCAL ENABLEDELAYEDEXPANSION
:comspec
IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec
SET CMDCMDLINE
IF DEFINED CMDCMDLINE REM '%CMDCMDLINE%'
PAUSE
EXIT /B
Start the batch script comspec.bat
modified in
step 4. per double-click:
REM Copyleft © 2001-2024, Stefan Kanthak <stefan.kanthak@nexgo.de> SET CMDCMDLINE= IF NOT DEFINED CMDCMDLINE EXIT /B SET CMDCMDLINE Environment variable CMDCMDLINE not defined REM 'C:\Windows\System32\cmd.exe /c ""C:\Users\Stefan\Desktop\comspec.bat" "' SETLOCAL ENABLEDELAYEDEXPANSION IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec IF NOT "!CMDCMDLINE:~1,-1!" == "" GOTO :comspec SET CMDCMDLINE Environment variable CMDCMDLINE not defined IF DEFINED CMDCMDLINE REM '' PAUSE Press any key to continue . . . EXIT /BOUCH³: with
delayed expansionenabled same as above!
ON
on OFF
,
the undocumented internal Keys
command
sets the also undocumented environment variable to
this value. When executed without argument, it displays its setting
like the internal
Verify
command, but does not evaluate the environment
variable.
�
KEYS /? KEYS SET KEYS KEYS ON SET KEYS KEYS OFF SET KEYS SET KEYS=ON KEYSNote: the command lines can be copied and pasted as block into a Command Processor window.
Enables or disables command line editing on DOS system
This is present for Compatibility with DOS systems. It has no effect
under Windows, as command line editing is always enabled.
KEYS is off.
Environment variable KEYS not defined
KEYS=ON
KEYS=OFF
KEYS is off.
OOPS: contrary to its help text, the internal
KEYS
command has effect under
Windows – it sets an environment variable!
Mkdir
alias
Md
command of the Command Processor
states:
Creates a directory or subdirectory.The documentation for the internalNote
This command is the same as the mkdir command.
[…]
md [<Drive>:]<Path> mkdir [<Drive>:]<Path>
Rmdir
alias
Rd
command of the Command Processor
states:
Deletes a directory. This command is the same as the rmdir command.[…]
rd [<Drive>:]<Path> [/s [/q]] rmdir [<Drive>:]<Path> [/s [/q]]
help textsof both internal commands wrong.
Start the Command Processor
Cmd.exe
, then display
the help texts
of both internal commands:
MKDIR /? RMDIR /?
Creates a directory. MKDIR [drive:]path MD [drive:]path […] Removes (deletes) a directory. RMDIR [/S] [/Q] [drive:]path RD [/S] [/Q] [drive:]path /S Removes all directories and files in the specified directory in addition to the directory itself. Used to remove a directory tree. /Q Quiet mode, do not ask if ok to remove a directory tree with /S
Create and delete more than a single directory with both internal commands:
MKDIR COMSPEC comspec RMDIR COMSPEC comspec
A subdirectory or file COMSPEC already exists.
Error occurred while processing: COMSPEC.
The system cannot find the file COMSPEC.
Oops: contrary to their documentation cited above
as well as their help texts, both internal commands accept more than a single directory pathname!
Prompt
command of the Command Processor
states:
Changes the Cmd.exe command prompt. If used without parameters, prompt resets the command prompt to the default setting, which is the current drive letter and directory followed by the greater than symbol (>).Note: the documentation but fails to mention that the current setting is stored in the environment variable
PROMPT
.
Start the Command Processor
Cmd.exe
, then execute
the following command lines:
SET PROMPT PROMPT SET PROMPTNote: the command lines can be copied and pasted as block into a Command Processor window.
PROMPT=$P$G Environment variable PROMPT not definedOops¹: when the internal
Set
command is executed without parameters the environment variable
PROMPT
is unset and thus removed from the process
environment block.
Start another instance of the
Command Processor and display its
(default) value of the environment variable PROMPT
:
"%COMSPEC%" /D /C SET PROMPT
PROMPT=$P$GOops²: when a new instance of the Command Processor is started and the environment variable
PROMPT
is not inherited from the
parent process it is preset with the default value $P$G
of the prompt.
Set the environment variable PATHEXT
to an (arbitrary
valid) value:
SET PROMPT=$$$A$B$C$D$E$F$G$L$M$N$P$Q$S$T$V$+$_
$&|(04/27/2012←)><CC:\Users\Stefan\Desktop= 12:34:56,78Microsoft Windows [Version 6.1.7601]Oops³: setting the environment variable
PROMPT
changes the prompt immediately.
Rem
command of the Command Processor
states:
Remarks[…]
You cannot use a redirection character (< or >) or pipe (|) in a batch file comment.
Start the Command Processor
Cmd.exe
, then execute
the following command lines to show undocumented behaviour at the
(interactive) command prompt:
0<. REM /? 1>. REM /? 2>>.. REM /? REM 0<. /? REM 1>. /? REM 2>>.. /? REM /? 0<. REM /? 1>. REM /? 2>..Note: the command lines can be copied and pasted as block into a Command Processor window.
Access denied Access denied Access denied Access denied Access denied Access denied Access denied Access denied Access denied
Oops¹: a redirection operator
<
, >
or >>
following or preceeding the internal
Rem
command with parameter /?
is interpreted – and
vice versa!
Command shell overview
Using command redirection operators
Execute the following command lines to show surprising behaviour:
REM /? & VER REM /?=%RANDOM% REM com/?;spec REM http://www.microsoft.com/?q=comspec
Records comments (remarks) in a batch file or CONFIG.SYS.
REM [comment]
Microsoft Windows [Version 6.1.7601]
12345 was unexpected at this time.
spec was unexpected at this time.
comspec was unexpected at this time.
Oops²: a pipe operator |
or an
ampersand operator &
following the internal
Rem
command with parameter /?
is interpreted – and
vice versa!
Oops³: the internal
Rem
command fails when /?
is followed by arbitrary
characters which include one of the separators space, comma,
semicolon and the undocumented equal sign!
Execute the following command lines which use the special characters not covered in the documentation cited above:
ECHO REM & ECHO & REM && ECHO && REM || ECHO || 0<NUL: 1>NUL: REM ^ comspec (REM ^) )
ECHO is on. More? More?Oops⁴: an ampersand (&) is also not interpreted as special character!
Oops⁵: neither the double ampersand (&&) nor the double pipe (||) are interpreted as conditional operators!
Oops⁶: the caret (^) is but interpreted as special character – it escapes both the newline and the closing parenthesis here!
Oops⁷: neither input nor output redirection are honored, both are ignored completely!
Finally show the bug:
(REM ^)) ) (REM ^)))) )
More? More?OUCH: inside a block started by an opening parenthesis any number of closing parentheses after an escaped one are discarded!
Set
command of the Command Processor
states:
Displays, sets, or removes CMD.EXE environment variables. If used without parameters, set displays the current environment variable settings.[…]
set [<Variable>=[<String>]] set [/p] <Variable>=[<PromptString>] set /a <Variable>=<Expression>
[…]
Parameter Description … … /a Sets String to a numerical expression that is evaluated. <Expression> Specifies a numerical expression. […] /? Displays help at the command prompt. […]
The following table lists the operators supported for /a in descending order of precedence.
Operator Operation performed … … << >> Logical shift.
Start the Command Processor
Cmd.exe
, then
evaluate some constants and expressions:
SET /A 0xFFFFFFFF SET /A ~0 SET /A ~0 ^<^< 32 SET /A 0x80000000 SET /A 0x80000000 ^>^> 99 SET /A -2147483648 SET /A ~2147483647 SET /A ~2147483647 * 2 SET /A ~2147483647 / ~0Note: the command lines can be copied and pasted as block into a Command Processor window.
-1
-1
0
-2147483648
-1
Invalid number. Numbers are limited to 32-bits of precision.
-2147483648
0
Invalid number. Numbers are limited to 32-bits of precision.
OOPS¹: contrary to the first highlighted part
of the documentation cited above, <Variable>
is
but optional with SET /A
; if present
it is set to the signed decimal string form of the resulting value.
Note: shifts are not limited to the size of the internal (32-bit) number width.
OOPS²: contrary to the last highlighted part of the documentation cited above, shifts are performed arithmetical, i.e. right shifts propagate the sign!
Ouch: although valid, a literal −2147483648,
the smallest signed 32-bit integer, is erroneously reported as
invalid number
!
Oops: (signed) integer overflow is detected only for division, other operations wrap around.
Finally demonstrate the bug:
SET /A ~2147483647 % ~0OUCH: on systems with i386 or AMD64 processor, the Command Processor crashes with an integer overflow exception 0xC0000095 when computing the modulus of −2147483648 ÷ −1 (which happens to be 0, the only number smaller in magnitude than the divisor −1)!
Note: dividing −2147483648, the smallest
signed 32-bit integer, by −1 yields the quotient 2147483648,
which is but not representable as signed 32-bit
integer and therefore produces an overflow (really: raises a
divide error exception
alias #DE
) that the
Command Processor fails to handle, i.e.
neither prevents nor catches for the modulus operator, while it does
so for the division operator!
Note: integer overflow and failure to catch the eventually resulting exception are well-known weaknesses, documented as CWE-190: Integer Overflow or Wraparound and CWE-248: Uncaught Exception in the CWE™; they allow well-known attacks like CAPEC-92: Forced Integer Overflow documented in the CAPEC™.
(Optional) If you have the Debugging Tools for Windows installed, execute the Command Processor under the debugger:
CDB.EXE /C g;q /G /g "%COMSPEC%" /D /C SET /A ~2147483647 % ~0Note: if necessary, see the MSDN articles Debugging Using CDB and NTSD and CDB Command-Line Options for an introduction.
Microsoft (R) Windows Debugger Version 6.11.0001.404 X86 Copyright (c) Microsoft Corporation. All rights reserved. CommandLine: "C:\Windows\system32\cmd.exe" /D /C SET /A ~2147483647 % ~0 Symbol search path is: srv* Executable search path is: ModLoad: 4a6d0000 4a71c000 cmd.exe ModLoad: 779c0000 77b40000 ntdll.dll ModLoad: 75610000 75720000 C:\Windows\syswow64\kernel32.dll ModLoad: 752d0000 75317000 C:\Windows\syswow64\KERNELBASE.dll ModLoad: 75540000 755e1000 C:\Windows\syswow64\ADVAPI32.DLL ModLoad: 757a0000 7584c000 C:\Windows\syswow64\msvcrt.dll ModLoad: 77420000 77439000 C:\Windows\SysWOW64\sechost.dll ModLoad: 77300000 773f0000 C:\Windows\syswow64\RPCRT4.dll ModLoad: 750e0000 75140000 C:\Windows\syswow64\SspiCli.dll ModLoad: 750d0000 750dc000 C:\Windows\syswow64\CRYPTBASE.dll ModLoad: 73d10000 73d17000 C:\Windows\SysWOW64\WINBRAND.dll ModLoad: 76f60000 77060000 C:\Windows\syswow64\USER32.dll ModLoad: 764f0000 76580000 C:\Windows\syswow64\GDI32.dll ModLoad: 76580000 7658a000 C:\Windows\syswow64\LPK.dll ModLoad: 76690000 7672d000 C:\Windows\syswow64\USP10.dll ModLoad: 76630000 76690000 C:\Windows\SysWOW64\IMM32.DLL ModLoad: 75470000 7553e000 C:\Windows\syswow64\MSCTF.dll (3314.4098): Integer overflow - code c0000095 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=80000000 ebx=00000025 ecx=00000025 edx=ffffffff esi=003ef680 edi=003ef69c eip=4a6e5176 esp=003ef650 ebp=003ef650 iopl=0 nv up ei ng nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010286 *** ERROR: Module load completed but symbols could not be loaded for cmd.exe cmd+0x15176: 4a6e5176 f77d14 idiv eax,dword ptr [ebp+14h] ss:002b:003ef664=ffffffff 0:000:x86> cdb: Reading initial command 'g;q' (3314.4098): Integer overflow - code c0000095 (!!! second chance !!!) quit:
Microsoft (R) Windows Debugger Version 6.1.7601.17514 AMD64 Copyright (c) Microsoft Corporation. All rights reserved. CommandLine: "C:\Windows\system32\cmd.exe" "/C SET /A ~2147483647 % ~0" Symbol search path is: srv* Executable search path is: ModLoad: 00000000`4aa90000 00000000`4aae9000 cmd.exe ModLoad: 00000000`77800000 00000000`7799f000 ntdll.dll ModLoad: 00000000`775e0000 00000000`776ff000 C:\Windows\system32\kernel32.dll ModLoad: 000007fe`fd510000 000007fe`fd577000 C:\Windows\system32\KERNELBASE.dll ModLoad: 000007fe`fd980000 000007fe`fda5b000 C:\Windows\system32\ADVAPI32.DLL ModLoad: 000007fe`fe1c0000 000007fe`fe25f000 C:\Windows\system32\msvcrt.dll ModLoad: 000007fe`fe260000 000007fe`fe27f000 C:\Windows\SYSTEM32\sechost.dll ModLoad: 000007fe`ff250000 000007fe`ff37c000 C:\Windows\system32\RPCRT4.dll ModLoad: 000007fe`f7520000 000007fe`f7528000 C:\Windows\system32\WINBRAND.dll ModLoad: 00000000`77700000 00000000`777fb000 C:\Windows\system32\USER32.dll ModLoad: 000007fe`fe350000 000007fe`fe3b7000 C:\Windows\system32\GDI32.dll ModLoad: 000007fe`fd970000 000007fe`fd97e000 C:\Windows\system32\LPK.dll ModLoad: 000007fe`fe280000 000007fe`fe34b000 C:\Windows\system32\USP10.dll ModLoad: 000007fe`fdf10000 000007fe`fdf3e000 C:\Windows\system32\IMM32.DLL ModLoad: 000007fe`ff9c0000 000007fe`ffacb000 C:\Windows\system32\MSCTF.dll (44dc.3c10): Integer overflow - code c0000095 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. *** ERROR: Module load completed but symbols could not be loaded for cmd.exe cmd+0x180eb: 00000000`4aaa80eb 41f7f9 idiv eax,r9d 0:000> cdb: Reading initial command 'g;q' (44dc.3c10): Integer overflow - code c0000095 (!!! second chance !!!) quit:
Start
command of the Command Processor
states:
Starts a separate Command Prompt window to run a specified program or command.OUCH: the default value for the PATHEXT environment variable is but[…]
Remarks
You can run nonexecutable files through their file association by typing the name of the file as a command.
When you run a command that contains the string "CMD" as the first token without an extension or path qualifier, "CMD" is replaced with the value of the COMSPEC variable. This prevents users from picking up cmd from the current directory.
When you run a 32-bit graphical user interface (GUI) application, cmd does not wait for the application to quit before returning to the command prompt. This behavior does not occur if you run the application from a command script.
When you run a command that uses a first token that does not contain an extension, Cmd.exe uses the value of the PATHEXT environment variable to determine which extensions to look for and in what order. The default value for the PATHEXT variable is:
Note that the syntax is the same as the PATH variable, with semicolons separating each extension..COM;.EXE;.BAT;.CMD
.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC
!
Start the Command Processor
Cmd.exe
, then execute
the following command lines to display the current setting of the
environment variable PATHEXT
and determine its origin:
SET PATHEXT REG.EXE QUERY "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /V PATHEXTNote: the command lines can be copied and pasted as block into a Command Processor window.
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment PATHEXT REG_SZ .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSCOOPS¹: in the installation images distributed by Microsoft, the environment variable
PATHEXT
is preset with a non-default
value!
Unset the environment variable PATHEXT
to remove it
from the process environment block and start
another
instance of the Command Processor to
display its (default) value of this environment variable:
SET PATHEXT= START /B CMD /D /C SET PATHEXT
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSCOOPS²: the default value of the environment variable
PATHEXT
differs from the value given in the
documentation cited above!
Set the environment variable COMSPEC
to the path name
of an arbitrary application and start
another instance of the
Command Processor:
SET COMSPEC=%SystemRoot%\System32\Reg.exe START /B CMD /D /C ECHONote: the Registry Console Tool Reg.exe is only (ab)used as
canaryhere.
ECHO is on.OUCH¹: contrary to the first highlighted sentence of the documentation cited above, the environment variable
COMSPEC
is not evaluated by the
internal START […] CMD […]
command!
Create an empty file CMD.EXE
in the current directory
and start
another instance of the
Command Processor to prove the first
remark of the documentation cited above completely
wrong:
COPY NUL: CMD.EXE START CMD
1 file(s) copied. Access DeniedOUCH²: contrary to the second highlighted sentence of the documentation cited above, the internal
START […] CMD […]
command executes an
arbitrary application CMD.EXE
that happens to exist
in the CWD!
Rename of the empty file CMD.EXE
to
CMD.COM
and repeat to last command the prove the first
remark of the documentation cited above again
completely wrong:
RENAME CMD.EXE CMD.COM START CMD
Access DeniedOUCH³:
START CMD
also executes an
arbitrary application CMD.COM
that happens to exist in
the CWD!
Delete the empty file CMD.COM
, create the text file
CMD.BAT
with the single (command) line
@VERIFY & EXIT
in the current directory and repeat
the proof from step 4. once more:
ERASE CMD.COM 1>CMD.BAT ECHO @VERIFY & EXIT START /B CMD
VERIFY is off.OUCH⁴:
START […] CMD […]
even executes an
arbitrary batch script CMD.BAT
that happens to exist in
the CWD!
Note: a repetition of the previous step 6.
using other extensions from the PATHEXT
environment
variable is left as an exercise to the reader.
Execute the following command line to show undocumented (mis)behaviour:
START /B EXIT
ERROR: Invalid Argument/Option - '/K'. Type "REG /?" for usage.OUCH⁵: contrary to the documentation cited above, without a first token
CMD
the internal command
START ‹arguments›
evaluates the
(user-controlled) environment variable COMSPEC
and
executes an arbitrary application using the command line
%COMSPEC% /K ‹arguments›
!
Note: properly implemented, the
Command Processor would fetch its own
path name with the Win32 function
GetModuleFileName()
instead to use the value of a user-controlled environment variable!
Delete the environment variable COMSPEC
and repeat the
previous step 7. to show more undocumented (mis)behaviour:
SET COMSPEC= START /B EXIT
The COMSPEC environment variable does not point to CMD.EXE.
Finally clean up and quit the Command Processor:
ERASE CMD.BAT EXIT
CMD.EXE
, CMD.COM
, CMD.BAT
etc. from the
CWD constitutes
a security vulnerability, similar to
CVE-2014-0315
alias
MS14-019
I discovered and reported at the
MSRC
about 10 years ago and which was fixed with security update
2922229
back then.
Note: the post MS14-019 – Fixing a binary hijacking via .cmd or .bat file on Microsoft’s Security Research and Defense Blog provides additional information.
The well-known underlying weakness is documented as CWE-426: Untrusted Search Path and CWE-427: Uncontrolled Search Path Element in the CWE™; the well-known attacks are documented as CAPEC-471: Search Order Hijacking and CAPEC-635: Alternative Execution Due to Deceptive Filenames in the CAPEC™.
The (unintended) execution of a (bogus) application determined by
the value of a (user-controlled) environment variable like
COMSPEC
is another well-known
weakness, documented as
CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
and
CWE-73: External Control of File Name or Path
in the
CWE™;
it too allows well-known attacks like
CAPEC-13: Subverting Environment Variable Values
documented in the
CAPEC™.
They replied with the following statements:
The engineering team has looked over the issue and has stated that this appears to be a documentation error and has been handed over to the team owning that site. In this case this does not appear to be a vulnerability and we will be closing it out on our side. The method of using this information in an attack would require a remote attacker to find malicious program that uses theOUCH: it appears to me that the engineering team is wrong; I recommend to have them read (and understand) especially (the end of) the chapter titledSTART cmdand trick the user to trigger this program as a minimum.
Current Working Directory (CWD) DLL plantingof the blog post Triaging a DLL planting vulnerability and recognise the striking similarity:
A DLL planting issue that falls into this category of CWD DLL planting is treated as an Important severity issue and we will issue a security patch for this.
NoDefaultCurrentDirectoryInExePath
which controls the
Win32 function
NeedCurrentDirectoryForExePath()
with an arbitrary value to remove the (implicit)
.
alias
CWD from (the
front of) the search path for executable files.
CAVEAT: the (internal) command
SET NoDefaultCurrentDirectoryInExePath=
removes this
environment variable from the environment block of the current
instance of the Command Processor and
neutralises the remediation for it and all its future child
processes; the command line
SetX.exe NoDefaultCurrentDirectoryInExePath ""
as well as the
VBScript
statement
WScript.CreateObject("WScript.Shell").Environment("VOLATILE").Item("NoDefaultCurrentDirectoryInExePath") = vbNullString
remove this environment variable from the environment block of the
shell
Explorer.exe
and
neutralise the remediation for all its future child processes!
Use the X.509 certificate to send S/MIME encrypted mail.
Note: email in weird format and without a proper sender name is likely to be discarded!
I dislike
HTML (and even
weirder formats too) in email, I prefer to receive plain text.
I also expect to see your full (real) name as sender, not your
nickname.
I abhor top posts and expect inline quotes in replies.
as iswithout any warranty, neither express nor implied.
cookiesin the web browser.
The web service is operated and provided by
Telekom Deutschland GmbH The web service provider stores a session cookie
in the web
browser and records every visit of this web site with the following
data in an access log on their server(s):