Wapac
Wapac

Reputation: 4178

Windows 10 runas escaping

This is more of theoretical construct, or an interesting problem, rather than a real world scenario - in which case I would use a batch file to prevent escaping problems.

  1. Let's say we want to run runas on Windows 10 in a way:

    runas /user:John "cmd.exe /k echo %path%"
    

    this does not work because %path% is expanded and we get error:

    Attempting to start cmd.exe /k echo C:\Program Files (x... ... RUNAS ERROR: Unable to run - cmd.exe /k ech... ... 1734: The array bounds are invalid.

    Is it possible to solve this? I.e. how to escape %? If we try

    runas /user:John "cmd.exe /k echo ^%path^%"
    

    the output in the new shell window is just

    %path%
    

    which is not what we want (we want the value of the PATH variable to be printed to the console).

  2. Let's say we want some other thing and we need to use " in our command:

    runas /user:John "cmd.exe /k dir c:\Program Files"
    

    This does not work - obviously because the space between Program and Files, the new shell window that appears says twice "File Not Found".

    One would expect that the solution for this would be

    runas /user:John "cmd.exe /k dir ^"c:\Program Files^""
    

    But that does not work (runas prints usage help). The question is why?

    The real solution here is using \":

    runas /user:John "cmd.exe /k dir \"c:\Program Files\""
    

    This escaping can be seen in runas usage help Examples section. But this is not a common way for escaping quotes, is it? The question here - why ^" does not work?

Upvotes: 2

Views: 1400

Answers (1)

Ross Presser
Ross Presser

Reputation: 6265

We have three entities involved:

  • the outer cmd shell, in which you are typing runas ...
  • runas.exe, which gets the creds, starts a new process, etc.
  • the inner cmd shell, which is what runas was told to execute

When you type runas ... "cmd.exe /k echo %path%"

  • the outer shell sees %path% and expands it
  • runas takes the expanded command, starts the inner shell with that as arguments
  • the inner shell echos what it saw

When you type runas ... "cmd.exe /k echo ^%path^%"

  • the outer shell sees ^%path^% in quotes, and interprets the carets as escaping the percent signs, so it doesn't expand path and leaves the carets in place
  • runas sees the command to be run as cmd.exe /k echo %^path^%
  • the inner shell sees echo ^%path^% and you see %path% in the new window.

So when the carets are inside quotes, they are retained. But if no quotes are used, runas won't work -- the command must be seen as a single parameter. What to do?

One way is to use a batch file, like you said.

Another is to use a different environment variable:

set aa=echo ^%path^%
runas /user:rpres "cmd.exe /k %aa%"
  • The outer shell sees the carets not in quotes in the set command, and produces a variable with the value echo %path%
  • The outer shell sees a variable to be expanded on the runas line, and expands it. ONCE. The inner %path% is not expanded
  • runas sees the command as cmd.exe /k echo %path% and runas that
  • the inner shell sees echo %path%. It expands the path. You see the expanded path in the new window.

A final way to do it is to get OUT of the quotes before escaping the carets: runas.exe ... "cmd.exe /k echo "^%path^% It is important that there be no spaces that are not in quotes, though!

  • The outer shell sees the carets not in quotes on the runas line, and escapes the percent signs while removing the carets.
  • runas sees the command as cmd.exe /k echo %path% and runas that
  • the inner shell sees echo %path%. It expands the path. You see the expanded path in the new window.

Note that you can "get back in the quotes" after finishing the escaped percents. e.g. runas /user:rpres "cmd.exe /k echo here is my path :::"^%path^%":::" will display here is my path followed by the path enclosed in three colon signs.

Upvotes: 3

Related Questions