Remotely Executing Applications on Behalf of Someone Else

by Jun 20, 2016

When you remotely execute an application, it will run invisibly on the remote system. Here is some code that illustrates how you can run an application remotely and visibly in the context of another user – provided you have local Administrator privileges on the target machine:

function Start-ProcessInteractive 
{
  param(
    $Path = "${env:ProgramFiles(x86)}\Internet Explorer\iexplore.exe",
    
    $Arguments = 'www.powertheshell.com',
    
    [Parameter(Mandatory=$true)]
    $Computername,
    
    [Parameter(Mandatory=$true)]
    $Username
  )


      
  $xml = @"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo />
  <Triggers />
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings />
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>"$Path"</Command>
      <Arguments>$Arguments</Arguments>
    </Exec>
  </Actions>
  <Principals>
    <Principal id="Author">
      <UserId>$Username</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
</Task>
"@
      
  $jobname = 'remotejob{0}' -f (Get-Random)
  $filename = [Guid]::NewGuid().ToString('d')  
  $filepath = "$env:temp\$filename"
  
  $xml | Set-Content -Path $filepath -Encoding Unicode
  
  try
  {
    $ErrorActionPreference = 'Stop'
    schtasks.exe /CREATE /TN $jobname /XML $filepath /S $ComputerName  2>&1
    schtasks.exe /RUN /TN $jobname /S $ComputerName  2>&1
    schtasks.exe /DELETE /TN $jobname /s $ComputerName /F  2>&1
  }
  catch
  {
    Write-Warning ("While accessing \\$ComputerName : " + $_.Exception.Message)
  }
  Remove-Item -Path $filepath
}

Start-ProcessInteractive needs the name (or IP) of a remote system and the user name of a logged on person on that system. It then opens Internet Explorer and shows a webpage. You can try this locally as well if you open a PowerShell with local Administrator prvileges:

 
PS> Start-ProcessInteractive -Computername $env:computername -Username $env:username
SUCCESS: The scheduled task "remotejob271599327" has successfully been created.
SUCCESS: Attempted to run the scheduled task "remotejob271599327".
SUCCESS: The scheduled task "remotejob271599327" was successfully deleted. 
 

If you change -Path and -Argument, you can execute anything remotely, provided the application path you specify is valid on the target system.

This illustrates the immense power local Administrators have: they can execute anything on behalf of any other logged on user. So if an Enterprise Domain Admin was logged into a system controlled by a local Admin, that local Admin can now execute PowerShell code on behalf of the logged on Enterprise Admin.

Always remember: local Admins are king of their kingdom. They could as well install key loggers or exchange system files to trap other users that log into their "kingdom". That's why you should restrict local Admin privileges as much as possible, and instead use new techniques like PowerShell’s "Just Enough Admin" (JEA).

Twitter This Tip! ReTweet this Tip!