Tuesday, June 15, 2004

PsExec - How Do They *Do* That?

I was over at SysInternals yesterday, downloading a new version of the most excellent Process Explorer, and I had a bit of a look around to see what else was cool. The answer, of course, is...everything. But I was particularly impressed by PsExec, a tool that gives you telnet-like shell connectivity to another machine without having to install anything on the remote machine!! I just run


psexec \\avalon cmd.exe


and like magic I have a command prompt that displays on my local machine that is actually executing commands over on the remote machine (avalon in my example). I repeat: without having to install anything on the remote machine. You can launch GUI applications, but they show up on the remote machine. Regardless, it's still killer for command-line guys like me.


I love it, but how the hell do they do that?

38 comments:

  1. Here's how it probably works:

    They call CreateService on the target machine, pointing the image back through a file share to your copy of PSEXEC.EXE (I've never tried wiring up a service to an EXE image on a shared drive, but if that doesn't work, they could just as easily copy the EXE to the remote machine in a temp directory).

    Then they call StartService to start the server running. To redirect a command prompt, all you really are doing is tying a socket to a command interpreter, which is super easy to do (check out rootkit.com for examples ;-)

    This wouldn't work if you weren't using SMB (for example, on a hardened web server where you've removed the client and workstation services).

    Now Craig will have to run NetMon and tell me if I was even close!

    Keith

    ReplyDelete
  2. One thing I forgot to mention: a service can delete itself. This is a tricky way to bootstrap something like this (cmdasuser.exe used to do this). When a service deletes itself (deletes its service entry from the registry by calling DeleteService), as soon as the service process terminates, the SCM removes the registry key for the service.

    They might also be using the trick of having their service simply launch a raw copy of the same EXE image and terminate immediately so that they reduce the window of time in which a service appears on the remote system. I used to play this game with cmdasuser as well.

    The ability to do this should scare anyone who runs as a network admin all the time! Malware can play these sorts of games just as easily as PSEXEC can.

    Keith

    ReplyDelete
  3. Between the time I posted and the time I read your post, Keith, I came to much the same conclusion (helped along by a few clever observations from my wife...I can't get away with anything around here). However, my assumption is that they push the service exe to the remote machine via (say) the C$ file share, rather than pulling it from the source machine.

    Checking...

    Yep, the service winds up in C:\windows\system32 on the remote machine, which suggests to me that it pushes it via the winnt$ share.

    It looks like the service deletes both the service entry and the executable when the task finishes. Which certainly is scary, but is also quite clever.

    I haven't run netmon yet, but one thing I'd be curious about is to see whether there's any attempt at channel encryption. I really doubt it, which would be disappointing, but unsurprising.

    ReplyDelete
  4. Why do programmers have to come up with elaborate solutions and conclusions when the answer is right in front of you: gnomes.

    I would now like to apologize to craig for that last comment.

    ReplyDelete
  5. Fool! It's pixies, not gnomes.

    :)

    ReplyDelete
  6. PSExec is really a magic tool.

    But there is an issue when I tried to use cmdasuer.exe.Can I use cmdasuser.exe existing on remote computer?I means, I have two computer, one computer has cmdasuser.exe, and on the other computer,I mapped a Network drive to the position where the cmdasuser.exe exists, and try to run the cmdasuer.exe, but failed.

    I used a command like "cmdasuser localsystem", but I got an error "StartService failed: The system cannot find the path specified".



    Anybody know this, please reply my comments.



    Thanks in advance.









    ReplyDelete
  7. I'm not quite sure why they won't work together, but you shouldn't need cmdasuser: psexec has a pair of switches (-u and -p) that let you set the username and password to login with on the remote computer.

    ReplyDelete
  8. Craiq, thanks a lot. It is very kind of you to answer my question so quickly.

    but using the way what you have said will run the exe or something else on the remote computer which has the exe, e.g. cmdasuser.exe exists on computer A,using PsExec.exe which exists on computer B, run PsExec.exe will start the cmdasuser.exe on A, but I want to see it on computer B. Maybe it is strange but it is what I need.

    ReplyDelete
  9. I don't understand. If you want to run cmdasuser on the local computer, why not just run it? Why do you need psexec at all?

    ReplyDelete
  10. you could probably also use the -c switch pointing at where you have the cmdasuser.exe sitting. We (the IT staff at a small company) use this to install a quick vnc server on a machine so that we can take a look. Especially handy for older machines that we didn't put it on.



    There is alot more to this that just using the command line on another computer, though it certainly would be enough.

    ReplyDelete
  11. I cant even get it to work ! i put the commands exactly as they are but nothing !

    ReplyDelete
  12. I thought nothing had happened first time i tried it, but later realised the command prompt was now on the remote machine.

    echo %computername% will confirm.

    I was a bit dissapointed that when i ran mspaint as a test it didnt spring up on the remote machine(although it was showing as a process in task manager ) so whats the idea there?

    I did manage to use it to start the SMS software inventory on the CEOs machine, rather than disturb him, which was good :)

    ReplyDelete
  13. The reason it didn't show up on the remote machine is that you must have started it in a noninteractive window station.

    ReplyDelete
  14. Hi

    I am trying to access a word file on a remote machine. i get "systen could not start z: on abc-3-1 system canot find path specified. Although.. i am authenticated correctly when i issue the pw

    i issue the cmd:



    psexex \\abc-3-1 -u:domain\user1 -p pwsd z:\test.doc

    ReplyDelete
  15. Z is a mapped drive, I assume? That's not necessarily going to exist on the remote machine. Try using the UNC path (\\server\share) instead.

    ReplyDelete
  16. Thanks Craig..

    But i do need to access the drive on the remote machine

    Teh case is map two clients to a common share that be [z] and the try to open the same file remotely

    ReplyDelete
  17. Then you'll need to do it some other way - it doesn't look like the login that psexec gives you is giving you access to the user's full environment.



    You can either switch from using a drive letter to using UNC paths or try to figure out how drives get mapped - maybe it's stored in the registry somewhere.

    ReplyDelete
  18. What I am having an issue with is when a limited account issues the psexec. I get access is denied, but Admin works.



    What are the permissions required on the host?



    Both are Win2003.

    ReplyDelete
  19. I have no idea. Have you tried contacting SysInternals?

    ReplyDelete
  20. I have a foxpro exe at linux server. Which I would like to run at third computer from my computer. Which command I should use?



    Presently I have applied in the way but not working:

    psexec \\10.2.1.175 \\10.2.1.6\hngroot\sales\hobakcup\ho.exe smodak ellora



    PsExec could not start \\10.2.1.6\hngroot\sales\hobackup\ho.exe on 10.2.1.175: Access is denied.



    I have full Administrative Right.

    ReplyDelete
  21. By default, the process you execute on the remote system impersonates the account from which you run PsExec on the local system. Impersonation is somewhat restricted from the perspective of security—the remote process doesn't have access to any network resources, even those that your account typically would be able to access. (http://www.windowsitpro.com/Windows/Articles/ArticleID/42919/pg/2/2.html)

    ReplyDelete
  22. Found a state in which the "Access denied" also occurs: In some circumstance the psexecsvc in C:\Windows won't be deleted on the remote machine after finishing.



    The next attempt to connect fails because the pstools can't create this file.



    greets

    ReplyDelete
  23. Hi all,



    I'm looking for a way to remotely collect system information from our servers world wide.



    What I' looking for right now is a tool to substract the 'ipconfig /all' information from remote servers without needing the 'Administrative' access rights.



    So, I tought this could be accomplished using the '-s' parameter hereby using the local 'SYSTEM'. But I still receive the 'Access is denied' error message. When I put myself in the 'Administrators' group, the access is granted and the output is shown correctly on the screen.



    Can anyone explain why the '-s' parameter does not give the expected result?



    Thanks in Advance.



    ReplyDelete
  24. You can't use the -s switch in that way because it uses the system account only as what user the service runs as. You still need admin rights to create the service that will then run as system.

    ReplyDelete
  25. Hi, I am a beginner with the tool psexec.

    want to copy n run a vbscript file from my location to a remote PC.
    I have used command listed belol
    psexec \\yourPC -c test.vbs
    But its throwing an error.

    Where I have to store test.vbs?
    To which location this file is gettin copied in remotePC.

    pls help me....

    ReplyDelete
  26. I’m trying to run psexec with an exe that contains this line of code:
    gfx.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight), CopyPixelOperation.SourceCopy);

    It will hit an exception when run on a remote computer, but runs fine locally.

    This is the exception:
    Unhandled Exception: System.ComponentModel.Win32Exception: The handle is invalid

    at System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32
    destinationX, Int32 destinationY, Size blockRegionSize)
    at TakeScreenShot.Program.Main(String[] args)
    c:\browsershotsexes\TakeScreenShot.exe exited on TestVistaErtang with error code
    -532459699.

    Thanks, Eric


    PS This is all the code for the exe:

    using System;
    using System.Collections;
    using System.Text;
    using System.Drawing.Imaging;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    //using SnipLib;
    //using MS.Internal.Test.Tools

    namespace TakeScreenShot
    {
    class Program
    {
    #region Console Window property stuff
    [DllImport("kernel32.dll", ExactSpelling = true)]
    private static extern IntPtr GetConsoleWindow();

    private static IntPtr ThisConsole = GetConsoleWindow();

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    private const int HIDE = 0;
    private const int MAXIMIZE = 3;
    private const int MINIMIZE = 6;
    private const int RESTORE = 9;
    #endregion
    static void Main(string[] args)
    {

    ShowWindow(ThisConsole, HIDE); //Hides Console Window
    Console.WriteLine("Minimizing the Current Console Window...");
    System.Threading.Thread.Sleep(2000);
    Rectangle scrBounds = Screen.GetBounds(new Point(0, 0));
    int screenWidth = scrBounds.Width;
    Console.WriteLine(screenWidth);
    int screenHeight = scrBounds.Height;
    Console.WriteLine(screenHeight);
    using (Bitmap bmpScreenShot = new Bitmap(screenWidth, screenHeight))
    {
    using (Graphics gfx = Graphics.FromImage((Image)bmpScreenShot))
    {

    Console.WriteLine(Environment.MachineName);
    gfx.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight), CopyPixelOperation.SourceCopy);
    bmpScreenShot.Save("\\\\ankursi-vista\\a-ertang\\" + Environment.MachineName + "_" + screenWidth.ToString() + "x" + screenHeight.ToString() + "_test.png", ImageFormat.Png);
    }
    }
    ShowWindow(ThisConsole, RESTORE);
    }
    }
    }

    ReplyDelete
  27. The code is being run in a service on the remote machine. It's probably not legal to run the code you're running in a non-interactive login.

    ReplyDelete
  28. Trying to run an install .exe on a remote PC. How can this be done in passive mode, so that all default options are used and the program installs? So far, I can only get the Welcome Page for the install program to appear.

    Thanks.

    ReplyDelete
  29. Now will this only work on a host thats on the same network, or can you run it on an outside computer?

    ReplyDelete
  30. I don't think it has anything to do with what network the computers are on, but rather whether the RPC ports are open and possibly whether a trust relationship can be established between the two. Generally, I would assume those things are not going to be true between two computers with a firewall between them.

    ReplyDelete
  31. I am trying to un-install one .msi as psexec \\remote_machine -u -p "msiexec /x \\sscewttct01\WTTInstall\Client\Clientx86.msi /passive".

    msi is stored on a network location (\\sscewttct01\WTTInstall\Client\Clientx86.msi). I am able to access this share from the remote machine, and logged in credentials on all the machines(Machine from which i am running, machine on which msi is kept, and remote machine) is same and that is in Admin group on all the machine.

    Here is what i see
    C:\New_Folder>psexec \\full-localmp -u fareast\idcsqlce -p msiexec /x
    "\\sscewttct01\WTTInstall\Client\Clientx86.msi" /passive

    PsExec v1.94 - Execute processes remotely
    Copyright (C) 2001-2008 Mark Russinovich
    Sysinternals - www.sysinternals.com

    Couldn't access full-localmp:
    The network path was not found.

    Make sure that the default admin$ share is enabled on full-localmp.

    i would really appreciate a quick help

    ReplyDelete
  32. Is the default admin$ share enabled on the remote machine?

    What happens if you do this:

    net use \\full-localmp\ipc$ /user:fareast\idcsqlce *

    ReplyDelete
  33. in order for psexec to connect to your remote computer, you have to allow file and print sharing on the remote computer's firewall.

    ReplyDelete
  34. When I run psexec as administrator, ir works for both w2K servers and W2K3 servers. If I run psexec as a limited user account, even with the -u adminuser -p adminpassord switches, it works for W2K server but not for W2K3 server. any ideas?

    ReplyDelete
  35. I am running the command >psexec -accepteula \\VirualMachineVM3 -u phx\userName -p Password cmd
    this is working fine eventhough in this machine \\VirualMachineVM3 PSEXESVC service is not running.

    But I was not able to connect >psexec -accepteula \\VirualMachineVM5 -u phx\userName -p Password cmd
    But in this machine PSEXESVC service is running

    Error message is


    Error communicating with PsExec service on VirualMachineVM5 No process is on the other end of the pipe.

    Need help..thnks in advacne

    ReplyDelete
  36. PSEXEC not Working: Error communicating with PsExec service on VirualMachineVM5 No process is on the other end of the pipe.

    I have had this issue before and if I am not mistaken i got around it by using the local admin account of the remote machine so:

    psexec -accepteula \\VirualMachineVM5 -u localhost\administrator -p cmd

    I know this is just a work around but hopefully its a limited issue.

    I know its been a while since your post but hope this helps someone

    ReplyDelete
  37. re: the guy who wants to run cmdasuser locally almost at the top of the comments thread -- can't you just use runas.exe?

    ReplyDelete
  38. Run -> control userpasswords2
    If exist an entry in Advanced -> Manage Passwords and if the remote user who is running inside psexecsvc service is the same, then, that user are actually using that entry to access network resources. The remote user from psexec does not see net use shares or any mapping from previous or even existing accounts even he is allow to interact with the desktop.

    Impersonate delegate credential

    ReplyDelete