Skip to content

Path assumptions #21

@jimbobmcgee

Description

@jimbobmcgee

There are some assumptions made with regards either to installation paths, or to applications being on the PATH variable...

  1. /lib/winrm/shells/elevated.rb, line 71

    • For instance, I have an old server instance that has been through the OS upgrade + virtualisation mill, so is actually limping along with a Windows path of E:\WINNT...
    • perhaps replace c:/windows with path determined by remote system, e.g. ask the Powershell shell for the Windows path before uploading the script:
      • Sticking with WINDIR\Temp:

        $uploaddir = [IO.Path]::Combine(($env:SYSTEMROOT, $env:WINDIR, 'c:\windows' -ne $null)[0], 'temp')
        

        (i.e. falling back to c:\windows if neither variable is set)

      • alternatively, use the common (all users) AppData folder in case of a write-permissons failure to C:\Windows (i.e if using an non-admin account)

        $uploaddir = ([Environment]::GetFolderPath('CommonApplicationData'), 'c:\windows\temp' -ne $null)[0]
        
  2. /lib/winrm-elevated/scripts/elevated_shell.ps1, line 54

    • If the PATH variable is trimmed, the literal string cmd will not work (or may allow someone to place another exe called 'cmd.com' in the way, which will be run instead);
    • You can reasonably ask Powershell where cmd.exe is using $env:COMSPEC or [IO.Path]::Combine([Environment]::SystemDirectory, 'cmd.exe')
  3. /lib/winrm-elevated/scripts/elevated_shell.ps1, line 61

    • Similarly, if not on the PATH, the literal string powershell.exe may not work as intended

    • Again, you can ask Powershell where powershell.exe, e.g. "$PSHOME\powershell.exe"

    • If any of the paths folded into your $arguments end up with spaces or special characters in them, you will need to double-quote the path, but you should not double-quote if they don't need it — you are, of course, fighting both Scheduled Tasks's quoting requirements, cmd.exe's quoting requirements and Powershell's quoting requirements all at once...

      $psexe = if ($PSHOME -match '\s') { "`"$PSHOME\powershell.exe`"" } else { "$PSHOME\powershell.exe" }
      

PS: if you are building up XML in Powershell, using user-supplied parameters, you might want to escape them first. Easiest way I can think of is passing through XText, e.g.

Add-Type -AssemblyName System.Xml.Linq
$arguments = "/c $psexe ... 2>&1"
$arguments = (New-Object Xml.Linq.XText($arguments)).ToString()
#> outputs: /c E:\WINNT\system32\WindowsPowerShell\v1.0\powershell.exe ... 2>&1

# or...
$task_xml = $task_xml.Replace("{username}", (New-Object Xml.Linq.XText($username)).ToString())

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions