public asyncExecutionResultViaFile(remoteExecution host, execFileSet fileSet) { _host = host; _stdOutFilename = fileSet.stdOutFilename; _stdErrFilename = fileSet.stdErrFilename; _returnCodeFilename = fileSet.returnCodeFilename; }
public override IAsyncExecutionResult startExecutableAsyncInteractively(string toExecute, string args, string workingDir = null) { if (workingDir != null) { throw new NotSupportedException(); } string tempDir = string.Format("C:\\users\\{0}\\", _username); execFileSet fileSet = base.prepareForExecution(toExecute, args, tempDir); // Use a scheduled task to run interactively with the remote users desktop. // Shell out to create it. string scheduledTaskName = Guid.NewGuid().ToString(); using (hypervisor_localhost local = new hypervisor_localhost()) { executionResult taskCreation = local.startExecutable("schtasks.exe", string.Format( "/f /create /s {0} /tr \"'{1}'\" /it /sc onstart /tn {4} /u {2} /p {3} ", _guestIP, fileSet.launcherPath, _username, _password, scheduledTaskName)); if (taskCreation.resultCode != 0) { throw new hypervisorExecutionException("Couldn't create scheduled task, stdout " + taskCreation.stdout + " / stderr " + taskCreation.stderr); } executionResult taskStart = local.startExecutable("schtasks.exe", string.Format( "/run /s {0} /tn {3} /u {1} /p {2}", _guestIP, _username, _password, scheduledTaskName)); if (taskStart.resultCode != 0) { throw new hypervisorExecutionException("Couldn't start scheduled task, stdout " + taskStart.stdout + " / stderr " + taskStart.stderr); } } return(new asyncExecutionResultViaFile(this, fileSet)); }
public override IAsyncExecutionResult startExecutableAsync(string toExecute, string args, string workingDir = null) { string tempDir = String.Format("C:\\users\\{0}\\", _spec.kernelVMUsername); if (workingDir == null) { workingDir = tempDir; } execFileSet fileSet = prepareForExecution(toExecute, args, tempDir); NamePasswordAuthentication auth = new NamePasswordAuthentication { Username = _spec.kernelVMUsername, Password = _spec.kernelVMPassword, InteractiveSession = true }; VimClientImpl _vClient = conn.getConnection(); VirtualMachine _underlyingVM = conn.getMachine(); GuestOperationsManager gom = (GuestOperationsManager)_vClient.GetView(_vClient.ServiceContent.GuestOperationsManager, null); GuestAuthManager guestAuthManager = (GuestAuthManager)_vClient.GetView(gom.AuthManager, null); guestAuthManager.ValidateCredentialsInGuest(_underlyingVM.MoRef, auth); GuestProcessManager guestProcessManager = _vClient.GetView(gom.ProcessManager, null) as GuestProcessManager; GuestProgramSpec progSpec = new GuestProgramSpec { ProgramPath = fileSet.launcherPath, Arguments = "", WorkingDirectory = workingDir }; guestProcessManager.StartProgramInGuest(_underlyingVM.MoRef, auth, progSpec); return(new asyncExecutionResultViaFile(this, fileSet)); }
public IAsyncExecutionResult _startExecutableAsync(string toExecute, string args, string workingDir, bool runInteractively) { string tempDir = string.Format("C:\\users\\{0}\\", _username); if (workingDir == null) { workingDir = tempDir; } // We do this by creating two batch files on the target. // The first contains the command we're executing, and the second simply calls the first with redirection to the files // we want our output in. This simplifies escaping on the commandline via psexec. execFileSet fileSet = base.prepareForExecution(toExecute, args, tempDir); // Now execute the launcher.bat via psexec. string psExecArgs = string.Format("\\\\{0} {5} {6} -accepteula -u {1} -p {2} -w {4} -n 5 -h \"{3}\"", _guestIP, _username, _password, fileSet.launcherPath, workingDir, "-d", runInteractively ? " -i " : ""); ProcessStartInfo info = new ProcessStartInfo(findPsexecPath(), psExecArgs); info.RedirectStandardError = true; info.RedirectStandardOutput = true; info.UseShellExecute = false; info.WindowStyle = ProcessWindowStyle.Hidden; //Debug.WriteLine(string.Format("starting on {2}: {0} {1}", toExecute, cmdArgs, _guestIP)); using (Process proc = Process.Start(info)) { // We allow psexec a relatively long window to start the process async on the host. // This is because psexec can frequently take a long time to operate. Note that we // supply "-n" to psexec so we don't wait for a long time for non-responsive machines // (eg, in the poweron path). if (!proc.WaitForExit((int)TimeSpan.FromSeconds(65).TotalMilliseconds)) { try { proc.Kill(); } catch (Exception) { } return(null); } // Now we can scrape stdout and make sure the process was started correctly. string psexecStdErr = proc.StandardError.ReadToEnd(); if (psexecStdErr.Contains("The handle is invalid.")) { return(null); } if (!psexecStdErr.Contains(" started on " + _guestIP + " with process ID ")) { return(null); } if (psexecStdErr.Contains("The specified service has been marked for deletion.")) { // Oh no!! This means that psexec, on the target machine, is left in a non-functional state. Attempts to use // it to start any processes will fail D: // I can't fid a way to recover from this, so we have to force a machine reboot here DDD: Hopefully it only // happens during deployment of the fuzzer (?), in which case we can recover just by deploying again. // I think we need a better way to execute remotely, PSExec may not be the best :( throw new targetNeedsRebootingException(psexecStdErr, proc.ExitCode); } // Note that we can't check the return status here, since psexec returns a PID :/ return(new asyncExecutionResultViaFile(this, fileSet)); } }
public override IAsyncExecutionResult startExecutableAsync(string toExecute, string args, string workingDir = null) { var connOpts = new ConnectionOptions(); connOpts.Username = _username; connOpts.Password = _password; string tempDir = string.Format("C:\\users\\{0}\\", _username); if (workingDir == null) { workingDir = tempDir; } // // We do things a bit differently to what we'd expect here. // We don't use WMI by calling the WMI API. Instead, we shell out to wmic.exe. // This is for a few reasons: // 1) Poor timeout support on the ManagementScope API // There's no real way to change the timeout used by ManagementScope.Connect. The best we can do is to make a // task which runs it async, and then to give up if it doesn't complete in time. Messy, and we can't stop it // from throwing when it fails. // 2) Unsubstantiated reports online of people encountering memory leaks, particularly when using multithreading // 3) I just saw an AccessViolationException in the method 'Connectnsecureiwbemservices', as called by this WMI // stuff // 4) I'm seeing weird failiures to run things at unpredictable times and suspect this will fix things. // We execute by creating two batch files on the target. // The first contains the command we're executing, and the second simply calls the first with redirection to the files // we want our output in. execFileSet fileSet = base.prepareForExecution(toExecute, args, tempDir); string wmicArgs = string.Format("/node:\"{0}\" /user:\"{1}\" /password:\"{2}\" process call create \"cmd /c {3}\",\"{4}\"", _guestIP, _username, _password, fileSet.launcherPath, workingDir); ProcessStartInfo info = new ProcessStartInfo("wmic.exe", wmicArgs); info.RedirectStandardError = true; info.RedirectStandardOutput = true; info.UseShellExecute = false; info.WindowStyle = ProcessWindowStyle.Hidden; using (Process proc = Process.Start(info)) { if (!proc.WaitForExit((int)TimeSpan.FromSeconds(60).TotalMilliseconds)) { try { proc.Kill(); } catch (Exception) { } return(null); } // WMIC will return zero on success, or an error code if (proc.ExitCode != 0) { switch ((uint)proc.ExitCode) { case 0x800706ba: // "The RPC server was unavailable" return(null); case 0x800706b5: // "The interface is unknown" return(null); case 0x80070005: // "Access is denied" return(null); case 0x80131500: case 0x80010108: // "Object invoked has disconnected from its clients" return(null); default: throw new Win32Exception(proc.ExitCode); } } // stdout will return something similar to the following: // // Executing (Win32_Process)->Create() // Method execution successful. // Out Parameters: // instance of __PARAMETERS // { // ProcessId = 2176; // ReturnValue = 0; // }; string stdout = proc.StandardOutput.ReadToEnd(); if (!stdout.Contains("Method execution successful") || !stdout.Contains("ReturnValue = 0;")) { return(null); } return(new asyncExecutionResultViaFile(this, fileSet)); } }