Esempio n. 1
0
 public asyncExecutionResultViaFile(remoteExecution host, execFileSet fileSet)
 {
     _host               = host;
     _stdOutFilename     = fileSet.stdOutFilename;
     _stdErrFilename     = fileSet.stdErrFilename;
     _returnCodeFilename = fileSet.returnCodeFilename;
 }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        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));
            }
        }
Esempio n. 5
0
        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));
            }
        }