0

Thanks to Abbas, the following code enable us to call a cmd process and pass command to it using PowerShell script.

$psi = New-Object System.Diagnostics.ProcessStartInfo;
$psi.FileName = "cmd.exe"; #process file
$psi.UseShellExecute = $false; #start the process from it's own executable file
$psi.RedirectStandardInput = $true; #enable the process to read from standard input

$p = [System.Diagnostics.Process]::Start($psi);

Start-Sleep -s 2 #wait 2 seconds so that the process can be up and running

$p.StandardInput.WriteLine("dir"); #StandardInput property of the Process is a .NET StreamWriter object

Now, How can I use a CMD process that already exists.

In better words, I want to use the PID of a cmd.exe process that is running and pass the command to it.

Falcon
  • 3
  • 3
  • If you'll allow me to ask the obvious: why do you need cmd if you have PowerShell? What's it going to do for you that PowerShell can't? – Jeroen Mostert Jan 31 '17 at 14:27
  • @JeroenMostert - Certain legacy programs actually don't respond properly when invoked directly from PowerShell; this is mostly because of how PowerShell handles quoting and parameter passing. In general, though, rather than fiddling with processes, I'd write my commands to a batch file, and then call it with `& "CMD /C $batchfilename"`. See [How to run an EXE file in PowerShell with parameters with spaces and quotes](http://stackoverflow.com/questions/1673967/how-to-run-an-exe-file-in-powershell-with-parameters-with-spaces-and-quotes) here on SO. – Jeff Zeitlin Jan 31 '17 at 15:35
  • 1
    @JeffZeitlin: I asked specifically because I can think of only a few scenarios where you'd want to interact with an *existing* cmd instance -- but none in which that is actually the best approach to anything. If it should turn out the use of cmd is completely unnecessary in this case, so much the better. – Jeroen Mostert Jan 31 '17 at 15:39
  • @JeroenMostert - I'm not sure I can think of _any_ scenarios where I'd want to, but I allow that I may be ... unimaginative. I'm fairly sure I can come up with a fairly easy way to get CMD.EXE process(es), but if there are multiple ones out there, I don't see that there's a way to determine which one you might want. – Jeff Zeitlin Jan 31 '17 at 15:43
  • @JeroenMostert- In fact I'm going to write a powershell script that checks for presence of MS15-051 privilege escalation exploit on a system. based on exploit behavior, After the exploit was ran successfully, a CMD prompt with SYSTEM privilege come up. I want to be sure that the CMD is running as SYSTEM, so I decided to pass the "whoami" to it. I also checked the SI (SessionID) for the CMD process, but despite its running as SYSTEM, the SI returned is 1. This is all the scenario. do you have any better idea?? Thanks. – Falcon Feb 01 '17 at 05:21

1 Answers1

0

Based on @Falcon's comment:

I want to be sure that the CMD is running as SYSTEM

I think the code should work, which checks for a command shell running as SYSTEM. It will return true for each matching shell that's running as SYSTEM, with title=TEST:

Get-CimInstance Win32_Process -Filter "name = 'cmd.exe'" | ForEach-Object {
  if ((Get-Process -Id $_.ProcessId).MainWindowTitle -eq 'TEST') {
    (Invoke-CimMethod -InputObject $_ -MethodName GetOwner).User -eq 'SYSTEM'
  }
}

The above code needs running in an elevated shell

The code based on this article checks for the command prompt being elevated:

$p = Get-Process -Name cmd | where {$_.MainWindowTitle -eq 'TEST'} |
  Select Name, @{Name="Elevated"; Expression={ if ($this.Name -notin @('Idle','System')) {-not $this.Path -and -not $this.Handle} } }

The code above needs running in a non-elevated PowerShell instance. It is testing for the absence of a path & handle - which the non-elevated shell can't see for an elevated command prompt. Change the eq 'TEST' condition to match your window.

TechSpud
  • 3,418
  • 1
  • 27
  • 35