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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions