Saturday 10 December 2016

Remote Execution

Executing an application on a remote machine without opening a remote terminal or a remote desktop is a pretty powerful feature that probably is not widely known. I had done it in a [from Windows to Windows] scenario many years ago, and I've needed it lately in a [from Windows to Linux] scenario. I'll give an overview of how the thing goes.

Windows to Linux

All you need is SSH. Assuming that you have an ssh server installed on your Linux machine, you can leverage the ssh client software on you local machine to open a connection, run some code and exit in just one go. Using the plink application that comes with putty you just do:

plink.exe -ssh -2 -pw myPassword myUser@myRemoteMachine -m commands.txt

Here I'm passing as parameter a file containing the commands to run (commands, the command line for launching a script/application...). In principle if it's just a command you could directly type it there:

plink.exe -ssh -2 -pw myPassword myUser@myRemoteMachine 'ls -la /tmp'

But I don't know why it is not working on my system.

You'll get the remote standard output on your local machine, so you can imagine how powerful this is. In some scenarios it can save you writing and deploying a server application on the remote machine. You just copy a few scripts/applications there, launch them remotely and get their output. The remote scripts/applications have to be present on the remote machine, plink is not copying them there, just running them. If you have a one shot scenario (run once and that's all, leaving no traces). You could run a squence of:
pscp to copy the code
plink to run it
plink "delete the remote script that I have just coopied"

Windows to Windows

For this you just need the so powerful Sysinternals psexec tool. Maybe you have used this tool to do a sort of advanced "run as" providing the password as parameter, so you can automate stuff not being prompted for typing the password (of course this use of psexec poses risks). The thing is that you can also use it to run a remote application (or to open a remote command line! sort of getting a telnet without having a telnet server installed!). The amazing thing is that you don't need to install anything on the remote machine, but you need to be an admin there, and have the Windows sharing ports opened, so that psexec can do its magic).

What happens when you type: psexec \\target -u adminuser -p passw some_executable is pretty well explained here:

The PSExec utility requires a few things on the remote system: the Server Message Block (SMB) service must be available and reachable (e.g. not blocked by firewall); File and Print Sharing must be enabled; and Simple File Sharing must be disabled.

The Admin$ share must be available and accessible. It is a hidden SMB share that maps to the Windows directory is intended for software deployments. The credentials supplied to the PSExec utility must have permissions to access the Admin$ share.

PSExec has a Windows Service image inside of its executable. It takes this service and deploys it to the Admin$ share on the remote machine. It then uses the DCE/RPC interface over SMB to access the Windows Service Control Manager API. It turns on the PSExec service on the remote machine. The PSExec service then creates a named pipe that can be used to send commands to the system.

and here

psexec connects to \\target and authenticates as adminuser.
If this does not work, psexec will show an error message and exit.
Next psexec copies psexesvc.exe to \\target\Admin$ and launches it as a temporary service.
If this does not work, psexec will show an error message and exit.
psexesvc on \\target launches some_executable.
psexec and psexesvc use pipes to handle keyboard input and screen output.
Once some_executable finishes, psexesvc will terminate, too, and remove itself from the services list.
psexec will exit.

This is rather impressive, at first it sounds a bit like magic, but well, it's not that they are using any hacking techniques, they just use standard windows features, but features that are not so well known to many. In principle, one can think that to install a Windows Service on a remote machine and start it you would have to open a telnet/ssh/RD session, but as you see it's not like that, you can connect remotely to the Service Control Manager, not only to start/stop services, but also to install them, i.e:
sc \\remotecomputer create newservice binpath= C:\Windows\System32\Newserv.exe start= auto obj= DOMAIN\username password= pwd
I guess things like this explain why it's not so common to have a telnet or ssh server installed on a Windows machine. For certain common tasks you can get by without it, and for others you already need a GUI and hence Remote Desktop.

This other site mentions something very interesting:

When you specify a username the remote process will execute in that account, and will have access to that account's network resources.

If you omit username the remote process will run in the same account from which you execute PsExec, but because the remote process is impersonating it will not have access to network resources on the remote system.

This is all related to the double-hop issue. If you pass your current credentials (meaning that you are using the authentication that you have already done on your local machine), the remote machine can not pass those credentials to a third machine. If you pass the user and password, the remote machine will use them to obtain the credentials, and then it will be able to pass those credentials to a third machine.

Notice that you can use this option:
-c Copy the program (command)to the remote system for execution.

so in one go you can install the remote service (psexecsvc), copy a local application there and tell the service to start this freshly copied application. I guess when the application is finished it will get removed (as the psexecsvc service)

No comments:

Post a Comment