3

I've created a process handler which starts two types of processes: One that is elevated with administrator username and password Another that runs normally without any username and password input.

I'm struggeling to figure out how I can get output from the elevated process. The application which starts the process, does not require Admin credentials to run, the admin credentials are entered in a seperate encrypted xml file, which the application uses in scripts and other places where admin credentials are required.

Since the application is run with a normal user, accessing elevated processes which the application has started, seems to be out of the question. I can start a process and I can easily check if it has done what it is suppoused to, but I cannot read its action to a string or a log.

public bool CreateProcessWithAdminRights(string filePath, string commandlineArgument, bool log)
{
    if (!string.IsNullOrEmpty(filePath) && !string.IsNullOrEmpty(commandlineArgument) && _user.UserDataExsists())
    {
        var securePassword = GetSecureString(_user.Password);

        ToolsProvider.Logger.Debug("Creating process with the following filepath: {0} and commandline argument: {1}", filePath, commandlineArgument.Replace(_user.Password, "<REPLACED>"));
        ToolsProvider.Logger.Info("Creating Process with admin rights for {0} against {1}", _user.Name );

        _proc = new Process
        {
            StartInfo =
            {
                FileName = @filePath,
                Arguments = commandlineArgument,
                ErrorDialog = false,
                RedirectStandardInput = false,
                RedirectStandardOutput = _log,
                RedirectStandardError = _log,
                UseShellExecute = false,
                CreateNoWindow = true,
                WindowStyle = ProcessWindowStyle.Hidden,
                UserName = _user.Name,
                Password = securePassword,
                Domain = _user.Domain
            }
        };
        _proc.ErrorDataReceived += ErrorDataReceived;
        _proc.OutputDataReceived += OutputDataReceived;
        return true;
    }
    return false;
}

The process is started using:

private bool StartProcess()
{
    if (_proc != null)
    {
        try
        {
            _proc.Start();
            _proc.BeginErrorReadLine();
            _proc.BeginOutputReadLine();
            _proc.WaitForExit();
            _proc.CancelOutputRead();
            _proc.CancelErrorRead();

            if (_standardOutput.Length > 2)
            {
                // use writeline, the builder itself will add the DEBUG / info tag
                ToolsProvider.Logger.WriteLine(_standardOutput.ToString());
            }

            if (_errorBuilder.Length > 2)
            {
                // use writeline, the builder itself will add the DEBUG / info tag
                ToolsProvider.Logger.WriteLine(_errorBuilder.ToString());
            }

            return true;
        }
        catch (Win32Exception ex)
        {
            ToolsProvider.Logger.Error(
                "Missing file while trying to run an action: " + _proc.StartInfo.FileName, ex.Message);
        }
    }
    ToolsProvider.Logger.Error("");
    return false;
}

I've tried starting the process using an Impersonator class as well, with and without the admin credentials added to the process. The impersonator class didn't do anything but tell me that I didn't have acccess, eventhough I was impersonating an administrator ...

I got the Impersonator class from here:

http://freshclickmedia.co.uk/2008/11/programmatic-impersonation-in-c/

So, how do I get standard and erroroutput from an elevated process in a process which isn't elevated?

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321

1 Answers1

2

You can't except by hacking the system and/or exploiting some bug and/or writing some kernel-level code (i.e. driver) to circumvent these security measures...

Just think about what this possibility would mean - elevation would become meaningless since there are always some elevated processes in a system which could be manipulated by such means... so the answer is NO...

What you should be able to do is redirect the output to a file (for example > C:\MyLog.txt) and later on read that file...

Think about a different design which does not require this sort of access...

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • By redirecting the output to a file, what are you thinking about then? By adding it in the command which is runned or in the process object itself? – Harald S. Hanssen Oct 26 '11 at 13:09
  • Tried it out, didn't work. Though, I'm pondering of other ways of starting the application. Is it possible to elevate the application after you've started it as a normal user? Or must it be restarted? – Harald S. Hanssen Oct 28 '11 at 12:34
  • Check [this hack](http://www.codeproject.com/Articles/19165/Vista-UAC-The-Definitive-Guide), although it's in C++. – Masood Khaari Oct 15 '13 at 13:11