PowerShell Armoury is meant for pentesters, “insert-color-here”-teamers and everyone else who uses a variety of PowerShell tools during their engagements. It allows you to download and store all of your favourite PowerShell scripts in a single, encrypted file.
You do not have to hassle with updating Rubeus, PowerView, manually. Just create a configuration file once or use the default one included with the tool. From now on, you just have to run “New-PSArmoury” before you head to the next engagement. In addition, your new and shiny armoury is encrypted and includes a bypass for AMSI, so you dont have to worry about AV.
Note: you have to provide a valid github account as well as a personal access token, so the script can properly use the github API. Do not use username/password since this will not work anyway if you have MFA enabled (and you should enable MFA). Also accessing the API with basic username/password is deprecated. Follow this guide to create a personal access token.
The config file needs to be a valid json that consists of a single array with one or more objects, where every object is interpreted as a single script source. Every object has the following attributes
Name (Mandatory)
A name of your choice to identify the script included in this object. This is just meant as a reference for yourself.
URL (Mandatory)
The location to get the script content from. This can be a URL to a web resource (https://) or a local path (C:) or a network resource (\…). The URL is thrown into Net.Webclient or Powershells Get-Item respectively. So basically every format that one of those two can handle by default should work.
Type (Mandatory)
This gives a hint about the script location to the armoury creator. There are three valid types:
FileInclusionFilter (Optional)
Will only be interpreted in an object of type “GitHub”. Will be matched with Powershells “like” comparison operator against the whole filename so keep in mind that you need to include the wildcards yourself. Don’t forget to include a star (*) if you want to match part of a filename. “*.ps1” means all files that end with “.ps1” but “.ps1” just means “.ps1”.
You don’t have to include a filter but if you do, you have to use it. An empty InclusionFilter means no files.
FileExclusionFilter (Optional)
Like the InclusionFilter but obviously the other way round. Exclusion takes precedence.
See inline Powershell help (man -full New-PSArmoury) for more details.
-Path
The path to your new armoury file. The default ist “.\MyArmoury.ps1”
-FromFile
Load your Powershell scripts directly from a local folder or file and you don’t have to provide a config file.
-Config
The path to your JSON-config file. Have a look at the sample that comes with this script for ideas.
-Password
The password that will be used to encrypt your armoury. If you do not provide a password, the script will generate a random one.
Please note: the main goal of encryption in this script is to circumvent anti-virus. If confidentiality is important to you, use the “-OmitPassword” switch. Otherwise your password and salt will be stored in your armoury in PLAINTEXT!
-Salt
The salt that will be used together with your password to generate an AES encryption key. If you do not provide a salt, the script will generate a random one.
Please note: the main goal of encryption in this script is to circumvent anti-virus. If confidentiality is important to you, use the “-OmitPassword” switch. Otherwise your password and salt will be stored in your armoury in PLAINTEXT!
-OmitPassword
This switch will remove the plaintext password from the final armoury script. Use this if confidentiality is important to you.
-ValidateOnly
Use this together with “-Config” to let the script validate the basic syntax of your JSON config file without executing it.
-Use3DES
Encrypts with 3DES instead of AES.
-EnhancedArmour
Instructs your armoury to require a protectecd PowerShell process. Therefore on first execution, your armoury will not load but spawn a new PowerShell that is set to run with BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON process mitigation. This prevents non-microsoft DLLs (e.g. AV/EDR products) to load into PowerShell. Shamelessly copied from the great @_rastamouse: https://gist.github.com/rasta-mouse/af009f49229c856dc26e3a243db185ec
You can find a very brief introduction below. Also have a look a these two blog posts here and here.
Evading Aniti virus With Powershell Armoury
TL;DR;
PSArmoury is a PowerShell script that allows you to easily get the newest versions of all your favourite offensive PowerShell craft and automatically put it together in a single, encrypted .ps1-file. Think of it like a “yum update” that pipes the result in an encrypted container to take it with you. AMSI and EDR bypass included 🙂
PSArmoury
I wrote my “Powershell Armoury” script a while ago to tackle two issues I often encountered during engagements:
So I created PSArmoury, which allows me to do the following:
Let’s have a look at that. You can find PSArmoury on Github. Just download or clone and you’re ready to go. First, let’s have a look at the config. PSArmoury comes with a sample configuration file called PSArmoury.json that already references some well-known tools like PowerSploit or Inveigh. You can use this for inspiration. The configuration file is just a JSON array containing the different script files you want to include. An array member looks like this.
Every config item consists of a name, an URL, a type and optional inclusion/exclusion filter. The major difference here is the type and there are three differen types available.
So in the example above, the configuration instructs PSArmoury to download all files from Kevin Robertsons repostory “Invoke-TheHash” that match the inclusion filter “*.ps1”.
Once you have created your configuration, you can simply run
. .\New-PSArmoury.ps1
New-PSArmoury -Path .\MyShinyNewArmoury.ps1 -Config .\PSArmoury.json
Note that it will require you to enter credentials to use the GitHub API. You have to enter your username and a personal access token.
Here’s a screenshot using the sample config that comes with PSArmoury.
The output above mentions a password. This has been generated randomly and is included in cleartext in the resulting armoury file. This is not a problem since we use encryption only as a means of obfuscation here and not for confidentiality. Still, if you want to remove the password from your armoury you can use the -OmitPassword
switch to do so. If you want to use a custom password or salt you can do this too by using the -Password
and -
Salt
parameters.
Now, how do you use your new and shiny armoury? It’s actually very simple, just open powershell on the host of your choice and load the .ps1 file like this.
cat -raw .\MyShinyNewArmoury.ps1 | iex
And that’s it. This will disable AMSI, load all encrypted blobs into powershell and then decrypt and load them in memory. Happy Hacking.
PS Armoury 1.4 – Now With Even More Armour
TL;DR;
I recently added some improvements to PSArmoury, which I like to share with you in this post
Still reading? Great, let’s go.
Introducing BlockDLL process mitigation
Thanks to the great C# port of @_RastaMouse it was very easy to implement a process mitigation, that was actually meant to protect processes from malicious injections. By setting a special flag in the extended startup info of a new process, we can prevent any non-microsoft DLL from loading into that process. This can prevent certain EDR solutions from detecting well-known tools inside powershell.
To use this with PSArmoury, just create your armoury with the -EnhancedArmour
switch like shown below.
Note that this will change your user experience a bit. If you try to load an enhanced Armoury it will not decrypt it’s content but start a new, protected powershell process and ask you to run it in there manually again. This might seem a bit cumbersome at first but the reasons are simple:
So to use it, just run your armoury as usual and it will guide you through the rest of the process as shown below.
Choose github branch
Every item of type “GitHubRepo” in your configuration file can now contain an attribute called “Branch”. If it exists, PSArmoury will try to use the branch name supplied in this attribute. If it does not exist, it will use the default branch as before. In the sample config you find on github, we use this attribute to download the dev branch of PowerSploit instead of the master.
{
“Name”: “PowerSploit”,
“Type”: “GitHubRepo”,
“URL”: “https://api.github.com/repos/PowerShellMafia/PowerSploit”,
“Branch”: “dev”,
“FileInclusionFilter”: “.ps1″, “FileExclusionFilter”: [“.tests.ps1″]
}
Create armoury from file
PSArmoury now offers a simple way to create an armoury from a local file. This comes in handy if you just want to quickly protect one (or many) powershell scripts you have on your disk without the need to create a config file. Just run PSArmoury with the -FromFile
switch and pass it the path to a file or folder containing powershell scripts. You can omit the -Config
-switch but note that only files with an extension of *.ps1
will be included.
Inventory
I occassionally find myself in the situation where I don’t remember what scripts I put inside an armoury, espescially when it’s been some time since I created it. Since everything of relevance is encrypted in the file on disk, it is not so easy to get that information. Therefore every armoury now contains an inventory function called Get-PSArmoury
, which will print the names of all files included to stdout. This function is built dynamically during creation of the armoury.
That’s it for now. If you are using PSArmoury and experience any issues or have ideas for new features, I would be happy to hear from you. Just send me a mail or open an issue on github.
Use the following commands to create an armoury with all default settings. You can start with the sample config file in this repository for inspiration.
. .\New-PSArmoury.ps1
New-PSArmoury -Config .\PSArmoury.json
This will create an encrypted .ps1 file called “MyArmoury.ps1” in the current working directory. Password and salt for encryption are randomly generated and included in cleartext in the file. (note that we use encryption only to prevent detection on disk and not for confidentiality)
You can load the armoury into your current session by using
cat -raw .\MyArmoury.ps1 | iex
Loading your armoury invokes the following steps:
After that, all powershell code you put in the armoury will be available. Just invoke the cmdlets as usual like this
Invoke-Rubeus -Command “kerberoast /stats”
Invoke-Bloodhound
Get-DomainGroupMember -Identity “Domain Admins” -Recurse
If it happens that you don’t remember what you put inside the armoury, just load it and call the inventory 🙂
Get-PSArmoury
Kali Linux 2024.4, the final release of 2024, brings a wide range of updates and…
This Go program applies a lifetime patch to PowerShell to disable ETW (Event Tracing for…
GPOHunter is a comprehensive tool designed to analyze and identify security misconfigurations in Active Directory…
Across small-to-medium enterprises (SMEs) and managed service providers (MSPs), the top priority for cybersecurity leaders…
The free and open-source security platform SecHub, provides a central API to test software with…
Don't worry if there are any bugs in the tool, we will try to fix…