Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute script using sysinternals PSExec from Asp.Net Web application

I am trying to execute PSExec from my Asp.Net Web application to connect to a remote server. Somehow it gives "Access Denied Error -5" with no credentials set, and by setting the credentials in the PSEXEC command it gives "2250 Network connection could not be found". I am an admin on the server and i have Windows authentication and Asp.Net Impersonation enabled (IIS7.5). More interestingly when i try to execute this from a console application or a even just using the command prompt it just works fine. I am trying to do just a ping operation as a test.

Here is my code snippet:-

            var startInfo = new ProcessStartInfo{
                CreateNoWindow = true,
                UseShellExecute = false,
                FileName = FilePath,
                Arguments = CommandArgs
            }

            Process vsCommandProcess = Process.Start(startInfo);

            vsCommandProcess.WaitForExit();
            var exitCode = vsCommandProcess.ExitCode;
            if (vsCommandProcess.ExitCode != 0)
            {
                ...rest of the code

Here:-

FilePath --> C:\pstools\psexec.exe
Arguments --> \\servername -accepteula -u domain\userName -p password ipconfig (1)
               \\servername -accepteula ipconfig (2)         

(1) Gives Error 2250 (2) gives Error 5

The same command and code works with a console application. SO i believe it definitely is something to do with the Asp.net application which is not able to carry over the credentials to remote to the machine. I event tried startInfo.LoadUserProfile but for no avail.

Appreciate your help. I tried to look up for similar questions but couldn't find a solution for the problem i am facing.

like image 429
PSL Avatar asked Apr 30 '13 15:04

PSL


1 Answers

Consider taking psexec out of the process. Going to WMI directly may give more insight into what is going wrong:

var connOpts = new ConnectionOptions()
{
// Optional, default is to use current identity
    Username = "username",
    Password = "password"
};

// create a handle to the Win32_Process object on the remote computer
ManagementScope mgmtScope = new ManagementScope(@"\\servername\root\cimv2", connOpts);
ManagementClass w32Process = new ManagementClass(mgmtScope, 
    new ManagementPath("Win32_Process"), new ObjectGetOptions());

// create the process itself
object[] createArgs = new object[] {
    // [in]   string CommandLine,
    "notepad.exe", 
    // [in]   string CurrentDirectory,
    null, 
    // [in]   Win32_ProcessStartup ProcessStartupInformation,
    null, 
    // [out]  uint32 ProcessId
    0};

var result = (int)w32Process.InvokeMethod("Create", createArgs);

switch (result)
{
    case 0: /* no-op, successful start */ break;
    case 2: throw new Exception("Access Denied");
    case 3: throw new Exception("Insufficient Privilege");
    case 8: throw new Exception("Unknown failure");
    case 9: throw new Exception("Path not found");
    case 21: throw new InvalidOperationException("Invalid Parameter");
}

If you still run into problems with impersonation, it may be helpful to dump the contents of HttpContext.Current.User.Identity to verify IIS is configured correctly. Further, if you are using Kerberos (through Negotiate/SPNEGO), you may need to allow the machine to delegate identity. If you know the SPN the machine will be connecting to, you can use constrained delegation, but in many cases it is necessary to allow unconstrained delegation if the targets are not known ahead of time.


Note: if you are remoting to the computer just to run ipconfig, you can get the same information via WMI without having to mess with trying to get the STDOUT output back to the calling computer. Take a look at the Win32_NetworkAdapterConfiguration class.

like image 149
Mitch Avatar answered Sep 27 '22 17:09

Mitch