Tuesday, April 9, 2013

Poshing the hashes: Using PowerShell to play with hashes

UPDATE: As mentioned here, even after KB2871997, you could still 'Posh' the SID-500-Administrator's hashes.

What do Pen Testers generally do after dumping hashes (or creds)? I asked this question during my workshop at BlackHat Europe. The answer was use of tools like psexec (independent or msf) to replay or pass the hashes to get access to more machines. This could be more fun and useful with a combination of Windows Credential Editor (thanks Hernan!) and Powershell.

I call this Poshing the Hashes.

Update 2: Another post by me explains how to dump hashes using powershell. Current post explains how to use them.

Update: This is for a scenario where you have network access to other computers, like an internal pentest.

Assume we have dumped hashes of a target system using WCE. We can start a powershell session with these credentials using the -s and -c options of WCE.

This powershell session will have privileges of the user whose hashes were used in WCE. Please note that there is nothing which could be flagged by an AV as we are using WCE on our machine and rest of it is Windows' features.

Now, while I was writing this post, someone asked me on twitter if it is possible to check the hashes on multiple systems before trying them, like Keimpx. The solution I gave didn't work, so I wrote Create-MultipleSessions.ps1 which will check the credentials on multiple machines by using a WMI query (which pulls IP addresses on successful authentication).

Here is the source:

Here is Create-MultipleSessions in action against my lab systems.

Nice,we poshed some hashes! the hashes worked on couple of systems. If you want to pass credentials to the script, use -Creds parameter. This will open up a prompt which will ask for credentials.

Now, if powershell remoting is enabled in a target environment, which is generally true in a Windows environment nowadays (it is enabled by default for Server 2012), you can leverage it for your purpose. Since our attacking machine and target machine are not part of same domain, we must add the target to our attacking machines TrustedHosts list. This is designed to stop a user from sending his credentials to a rogue server. Lets just trust everyone :)

In the wce-started powershell window, we can use Enter-PSSession to connect to the target. By default only those users which are part of Local Administrator Group can use powershell remoting.

Bingo! We have an interactive and *elevated* powershell session on the remote machine, as the hashes used were of a local admin. Now we can have more post exploitation fun using Nishang.

Ok, an interactive shell on one computer is fine but what if we want to open sessions on many computers? You can use the -CreateSessions switch of Create-MultipleSessions.ps1 to create sessions to multiple computers.

We can use Enter-PSSession to connect to the session of choice.

Now, what if we want to execute a command or script on hundreds of computers? Powershell has a cmdlet Invoke-Command exactly for this purpose. To execute a command on multiple computers, lets use powershell session started using WCE

Notice that we have sucessfully executed $env:COMPUTERNAME on two computers.

Invoke-Command also supports -Credentials parameter.

Invoke-Command has another very useful parameter -FilePath. Using this you can execute a local script on remote computers, very handy! You can use many payloads available with Nishang using this for post-exploitation neatness ;)

I wrote Run-EXEonRemote which *drops* executables on remote machines and execute those. For example,  lets use Run-EXEonRemote to drop and execute WCE on multiple machines and dump plain text passwords.

Here is the source

Want to run an executable in memory using PowerShell? Some smart people are working on it.

Please note that Execution Policy is not a problem if you use -Filepath with Invoke-Command until the script use things like Import-Module. I have been unable to bypass the Execution Policy in such case. Still, as I have been saying, Execution Policy is not a security control but a user discretionary control.

Invoke-Command could also be used to run scripts as jobs.It could also be used to run scripts using Session parameter so that commands can have state. Use help Invoke-Command to see more. PowerShell help system is very good and really useful.

As we saw, it is better to use PowerShell Remoting if hashes or creds are available. A word of advice, stick with PowerShell v2 while Poshing the Hashes, PowerShell v3 failed me sometimes while connecting to machines with v2, even -Version parameter did not help. I have not looked deeper into the matter but it may be because of modifications in remoting protocol.

Create-MultipleSessions and Run-EXEonRemote have been added to Nishang. Please update your repos.

Hope this would be useful. Please leave comments and feedback.


  1. Hi, Nikhil! Very cool stuff you have here.

    I've tried replicating your implementation on Windows 8 (PowerShell 3.0), Windows 2008 R2 (PowerShell 2.0), and on a Windows 7 box running PowerShell 2.0.

    I've had the best luck with Windows 7 but am running into an issue once I try to Enter-PSSession from the WCE-started PowerShell session: Once I feed the target machine I immediately get prompted with a credentials box. I can of course, manually insert my username and password and then proceed to invoke commands on the target machine... but in your example, you were able to remotely connect with just the -computername from the WCE shell.

    Any thoughts on this? I poked around on MSDN and made sure that my account (who's hashed credentials I'm using) is an admin on the target box.

    Thanks a bunch!
    - Rob

  2. Hi Rob,

    That is strange. I never faced such an issue. Even if you have no admin access on remote machine it would say "Access Denied" or throw some error. I have not seen the WCE-started session asking for credentials. Are you sure you are not using the -Credential parameter with Enter-PSSession? Have you tried using Invoke-Command? Very unlikely, but this *may* happen if you are trying to connect from v3 to v2.

    If the problems persists give me more details and we would try to resolve it together.


  3. Thanks for the quick response, Nikhil! I hope you had a great weekend.

    I've tried running through the steps again and here's some additional information: I've successfully dumped the hash via WCE and used the -s and -c switches to fire up the new powershell console. My screen looks similar to your step-by-step screenshots-- my powershell console shows that info for the new logon session using NTLM credentials...

    I've used your script to see if I can connect to the target machine and everything is good. When I try the Enter-PSSession with no crendetial switch, I get the following error: "Connecting to remote server failed with the following message: Logon failure: unknown user name or bad password."

    It looks like there is some sort of issue with the new logon session using the LMHash and NTHash I got from WCE... Interesting!

    Thanks again for your input and time-- much appreciated!

    1. No problem.

      Can you do one quick check? While using WCE use the hash in this format

      .\wce.exe -s Rob::LM:NT

      Unlike, screenshot in above post which shows
      .\wce.exe -s Rob:.:LM:NT

  4. That's how I was using it: ROB:DOMAIN:LM:NT :)

    No luck thus far... very strange!

    1. Ok, ome more thing (and if it solves your problem than its my fault for not mentioning it in the post). You have to trust the target by using this from an elevated powershell:

      Set-Item WSMan:\localhost\Client\TrustedHosts -value

      or to trust all target computers

      Set-Item WSMan:\localhost\Client\TrustedHosts -value *

  5. Yup-- you mentioned this in your article. I've added the value " * " and I've also tried with the specific name of the target, and I was prompted with a [Y] or [N] to make sure I wanted to add the target machine. But once I start the WCE session and try to Enter-PSSession I'm still getting the same login failure error.

    Very interesting!

  6. Thank you so much for such interesting posts. I'm trying to follow along but I'm getting the most frustrating error when I try to use wce.exe. I have Google-d high and low, but nobody seems to have the same problem as me:

    WCE v1.3beta (Windows Credentials Editor) - (c) 2010,2011,2012 Amplia Security - by Hernan Ochoa (hernan@ampliasecurity.com)
    Use -h for help.

    CrossSessionCreateRemoteThread: Cannot create new thread

    I'm hoping you can shed some light on this error?! It happens no matter what options I pass to wce. FYI, I am running the command from an Administrator's command prompt. Thank you.

    1. Thank you for reading my post!

      Looks like you are running 32-bit version of WCE from a 64-bit machine. Try using the 64 bit version (or universal version). Please let me know if this sovles your problem.

    2. Hey Nikhil, you were absolutely right. I downloaded the universal version and it works a treat. Thank you very much.

  7. Anyone tried this across non domain joined machines ? I'm interested in making this work on Azure VM.

    1. It works fine with non-domain machines. You just need to trust the target machine. Use this on your (attacking) machine:
      Set-Item wsman:localhost\client\trustedhosts -Value

    2. My tests weren't successful but the event log indicates that the right target user is trying to access which is a start. I get the following event log

      Logon Type: 3

      Account For Which Logon Failed:
      Security ID: NULL SID
      Account Name: user
      Account Domain: TARGET

      Failure Information:
      Failure Reason: Unknown user name or bad password.
      Status: 0xC000006D
      Sub Status: 0xC000006A

      Process Information:
      Caller Process ID: 0x0
      Caller Process Name: -

      Network Information:
      Workstation Name: ATTACKER
      Source Network Address: -
      Source Port: -

      Detailed Authentication Information:
      Logon Process: NtLmSsp
      Authentication Package: NTLM
      Transited Services: -
      Package Name (NTLM only): -
      Key Length: 0

    3. Are you using the bulit-in Administrator account? This could be because of KB2871997 and KB2928120. See the update.

  8. is there a way to dump hashes from a w2k12 dc with powershell?

    1. Have you tried Get-PassHashes? It should do the job.

  9. While inside the ambitious setting, every newly coming interconnection reasons the most well-known partially link with become taken out (can change this habits for you to hit-or-miss drop mode).
    Buy Generic Viagra