Impacket psexec.py
Back to the category index / Back to the command index
Overview
Section titled “Overview”Uploads and starts the RemCom service binary on the target, then runs commands or an interactive shell through named pipes.
| Item | Details |
|---|---|
| Implementation | examples/psexec.py |
| Category | Remote execution / WMI / services |
| Size | 677 lines |
| Distribution | Installed as a script through scripts=examples/*.py in setup.py |
CLI and input
Section titled “CLI and input”Run python examples/psexec.py -h for the current option definitions.
| Argument | Description |
|---|---|
target | [[domain/]username[:password]@] |
command | Command to run on the target (without a path), or arguments when using -c (default: cmd.exe) |
-c | Copy a file for later execution; pass its arguments in the command option |
-path | Path of the command to run |
-file | Alternative RemCom binary (it must not require the CRT) |
-ts | Add a timestamp to each log message |
-debug | Enable debug output |
-codec | Help text generated dynamically from the runtime value |
-hashes | NTLM hashes in LMHASH:NTHASH format |
-no-pass | Do not prompt for a password (useful with -k) |
-k | Use Kerberos authentication. Look for matching credentials in the ccache file named by KRB5CCNAME; if none are valid, use those specified on the command line |
-aesKey | AES key for Kerberos authentication (128 or 256 bits) |
-keytab | Read SPN keys from a keytab file |
-dc-ip | Domain controller IP address; if omitted, use the domain name (FQDN) from the target parameter |
-target-ip | Target machine IP address; if omitted, use the target value. Useful when a NetBIOS target name cannot be resolved |
-port | Destination SMB server port (choices: 139, 445; default: 445) |
-service-name | Name of the service used to trigger the payload |
-remote-binary-name | Name of the executable uploaded to the target |
Related technology: named pipes in SMB and SCMR in DCE/RPC.
Detailed processing flow
Section titled “Detailed processing flow”After establishing an SMB session, ServiceInstall places the service binary on a share and creates and starts an SCMR service. The main pipe carries execution requests, while three pipe threads relay stdin, stdout, and stderr. On exit, the tool removes the service and uploaded binary. -c provides a path for transferring an additional executable.
How it works
Section titled “How it works”The PSEXEC path has two stages. First, it uses a normal SMB session to place the RemCom service binary on a writable share and creates and starts a temporary service through SCMR. It then connects to the named pipes exposed by that service to exchange execution requests and standard input and output, combining RPC service control with SMB pipe transport.
The main communication pipe carries a RemComMessage with the machine name,
process ID, command, working directory, and other fields. Stdin, stdout, and stderr
use separate pipes. RemoteStdInPipe and output threads handle them concurrently.
File uploads and downloads in the interactive shell use another SMB connection,
keeping large file data separate from the command stream.
This implementation has many partial states: a pipe connection may fail after the service starts, an output thread may disconnect alone, or a command may fail after an additional executable is transferred. Stop and delete the service, remove the binary, close pipes and threads independently, and handle collisions when reusing a remote binary or service name. The exit code comes from the RemCom response.
Key implementation elements
Section titled “Key implementation elements”| Symbol | Location | Where to trace its responsibility |
|---|---|---|
RemComMessage | 45 | Structure or constant definition |
RemComResponse | 55 | Structure or constant definition |
PSEXEC | 67 | __init__(), run(), openPipe(), doStuff() |
Pipes | 226 | __init__(), connectPipe() |
RemoteStdOutPipe | 265 | __init__(), run() |
RemoteStdErrPipe | 383 | __init__(), run() |
RemoteShell | 471 | __init__(), connect_transferClient(), do_help(), do_shell(), do_lget(), do_lput(), do_lcd(), emptyline(), default(), send_data() |
RemoteStdInPipe | 580 | __init__(), run() |
Dependencies
Section titled “Dependencies”Within Impacket
Section titled “Within Impacket”| Module | Main names used |
|---|---|
impacket.examples | logger, remcomsvc, serviceinstall |
impacket | smb, version |
impacket.smbconnection | SMBConnection |
impacket.dcerpc.v5 | transport |
impacket.structure | Structure |
impacket.examples.utils | parse_target |
impacket.krb5.keytab | Keytab |
External packages (used directly)
Section titled “External packages (used directly)”| Import name | Distribution package | Import path and declaration status |
|---|---|---|
six | six | Imported directly; declared |
Output, side effects, and required privileges
Section titled “Output, side effects, and required privileges”- Some operations change the target’s state. Check the target name, SID, and path before making changes.
- Some paths use temporary resources such as remote services, tasks, files, shares, and WMI/RPC resources. Cleaning them up after an abnormal exit is part of the behavior contract.
Failure paths and cleanup
Section titled “Failure paths and cleanup”- On failure, use protocol status codes to determine whether name resolution, connection, authentication, service state, or permissions caused the stop.
- Even without an explicit cleanup function, check for
finally-equivalent paths and closure or deletion of protocol handles.
When changing the implementation
Section titled “When changing the implementation”The code depends on SMBConnection, dcerpc.v5.transport, examples.remcomsvc, serviceinstall, and threading. The connection order and cleanup of PSEXEC, Pipes, and each stream class matter.
Verification
Section titled “Verification”- Syntax:
python -m py_compile examples/psexec.py - CLI:
python examples/psexec.py -h - Related test:
tests/misc/test_dcerpc_v5_ndr.py - Related test:
tests/misc/test_structure.py

