-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a381bc6
commit 4667acc
Showing
75 changed files
with
22,293 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Sphinx build info version 1 | ||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. | ||
config: 1578ef87507dede10c7c46d5761c5c1d | ||
tags: 645f666f9bcd5a90fca523b33c5a78b7 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
```{include} ../CHANGELOG.md | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Contributing | ||
|
||
If you find PowerHub useful and want to give back, there are a number of options: | ||
|
||
* **Say thanks.** It means more than you might think. | ||
* **Spread the word.** It's motivating to see your product being used. | ||
* **Report bugs.** Help make PowerHub better. | ||
* **Create pull requests.** Bug reports that come with a solution are the best | ||
reports. | ||
|
||
## Creating bug reports | ||
|
||
Like any other software, PowerHub has bugs. If something doesn't work right, | ||
the best and probably quickest way to solve is to try to fix it yourself. | ||
See the notes on [troubleshooting](sec_troubleshooting) first. | ||
|
||
Since PowerHub is obfuscating everything under the sun, debugging can be | ||
hard. Even more so if I as the developer cannot reproduce what is going | ||
on. | ||
|
||
To make bug reports more useful, run PowerHub in debug mode by using the | ||
`--debug` flag. This will make PowerHub somewhat more susceptible to | ||
detection, so let's hope that this doesn't interfere. | ||
|
||
Before you execute the download cradle, run `$ErrorActionPreference="Stop"`. | ||
Usually the first error is the most important one. If you think the first | ||
error is not helpful, run `$ErrorActionPreference="Continue"`, but try to | ||
trim the output and only submit the first three PowerShell errors or so. | ||
|
||
It would be helpful it you could pin down the issue to the first problematic | ||
line. For this, open the URL in a browser or with `curl` and execute | ||
portions of the script in blocks. Again, using `--debug` makes this more | ||
feasible because it preserves whitespace and does not obfuscate the | ||
parameter names. | ||
|
||
Finally, include the output of the Python program as well in the bug report; | ||
in particular exceptions including a full traceback. Don't forget to use | ||
code fences (three backticks) to format the output properly, or else it will | ||
become unreadable. You may trim the Python output to the relevant parts as | ||
well, but when in doubt, err on the side of more verbosity. In PowerShell, | ||
the first error message is usually the only useful, while in Python the last | ||
part of the traceback is most important (but all parts are useful or | ||
sometimes even necessary). | ||
|
||
Besides the versions of all software packages involved (on both machines), | ||
the download cradle parameters will be particularly important. | ||
|
||
In short, try to include everything so the issue can be reproduced. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
# Antivirus Evasion Techniques | ||
|
||
Let's discuss some common antivirus detection techniques and how PowerHub | ||
attempts to bypass them. | ||
|
||
## Network Monitoring | ||
|
||
### Technique | ||
|
||
Antivirus detection does not necessarily have to happen on the endpoint. | ||
It's common to check files transferred from the network for malicious code | ||
before it even reaches the endpoint. Usually, this happens in web proxies. | ||
|
||
### Our Bypass | ||
|
||
PowerHub support HTTPS. Since some antivirus products perform TLS | ||
inspection, almost all data is encrypted on an additional layer using either | ||
RC4 or AES. Yes, RC4 is insecure, but practical attacks are still | ||
sufficiently difficult for antivirus products. | ||
|
||
## File System Monitoring | ||
|
||
### Technique | ||
|
||
Whenever a file is written to disk, antivirus checks it against known | ||
malware. | ||
|
||
### Our Bypass | ||
|
||
Easy: Don't write anything to disk. PowerShell makes it possible to execute | ||
code entirely in-memory. | ||
|
||
## AMSI | ||
|
||
### Technique | ||
|
||
Whenever PowerShell executes a script, it is first passed to the antivirus | ||
product which checks it for malicious code. This check is often quite | ||
primitive, such that it was at some point sufficient to replace | ||
`Invoke-Mimikatz` with `Invoke-Mimidogz`. The mere presence of some IT | ||
security researcher's name is sometimes enough to trigger an antivirus. | ||
|
||
### Our Bypass | ||
|
||
PowerHub doesn't use any novel AMSI bypass. There are long | ||
[lists](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell) of AMSI | ||
bypasses, because PowerShell is so powerful, it can modify its own behavior. | ||
|
||
The challenge is to get one of the bypasses by AMSI itself, because the | ||
bypasses are obviously immediately detected if executed naively. Some | ||
bypasses are quite short and the only suspicious thing about them are some | ||
strings. For example, this is one of the first bypasses by Matt Graeber and | ||
it fits in a Tweet: | ||
|
||
```powershell | ||
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true) | ||
``` | ||
|
||
In fact, Windows Defender will consider this malicious simply because it | ||
contains the string `AmsiUtils`. Try it out: Open a PowerShell and type | ||
`"AmsiUtil"`. Then type `"AmsiUtils"`: | ||
|
||
![AmsiUtils are malicious](docs/img/amsiutils.png) | ||
|
||
Imagine we replaced the strings: | ||
|
||
```powershell | ||
[Ref].Assembly.GetType($string1).GetField($string2,$string3).SetValue($Null,$True) | ||
``` | ||
|
||
Surely this line cannot be considered malicious, or else it would probably break | ||
legitimate scripts. So if we manage to obfuscate the original strings, we | ||
should be good. There are infinite ways to obfuscate a string. You can split | ||
them up, rearrange them using format strings, put them together from bytes, | ||
work with replacement rules, and much, much more. | ||
Daniel Bohannon has worked out a [whole bunch of obfuscation | ||
methods](https://github.com/danielbohannon/Invoke-Obfuscation), not only for | ||
strings, but also for other PowerShell "tokens". | ||
|
||
In PowerHub, we take an even more systematic approach: Strings are | ||
"obfuscated" using the RC4 encryption algorithm. It's simple enough so it | ||
can be implemented in a couple of lines of pure PowerShell, and while | ||
technically broken, still strong enough to throw off automated detection | ||
techniques, especially if they are supposed to work in the background | ||
without affecting the user's workflow. | ||
|
||
|
||
## Entropy Analysis | ||
|
||
### Technique | ||
|
||
Overly obfuscated code looks *weird*. You'd be able to spot it a mile away. | ||
Machines can be made to recognize it as well, by means of frequency analysis | ||
of individual letters or, more generally, entropy analysis. Daniel Bohannon, | ||
who worked on obfuscating code, also suggested ways to [defeat code | ||
obfuscation](https://www.blackhat.com/docs/us-17/thursday/us-17-Bohannon-Revoke-Obfuscation-PowerShell-Obfuscation-Detection-And%20Evasion-Using-Science-wp.pdf) together with Lee Holems. | ||
|
||
### Our Bypass | ||
|
||
We (optionally) wrap our code in legit PowerShell code. Downloaded from one of | ||
Microsoft's GitHub repositories, PowerHub has hundreds of modules that do | ||
nothing and which will be randomly chosen to pad suspicious code. Plus, | ||
instead of using randomly generated variable names, PowerHub can use | ||
variable names inspired by real code to make it look more natural. | ||
|
||
We will still have large encoded binary blobs in our code, but we must | ||
assume that it won't be feasible for antivirus products to block all scripts | ||
with blobs in them. There is no way around this -- I think. | ||
|
||
## API Hooking | ||
|
||
### Technique | ||
|
||
Hooking certain routines, such as the AES decryption routine, actually makes | ||
sense. If a process decrypts data that contains naughty strings like | ||
`Mimikatz`, it is killed immediately by some antivirus products. | ||
|
||
### Our Bypass | ||
|
||
PowerHub has the option to stick to RC4, which doesn't use any APIs. It's | ||
noticeably slower but should be stealthier at the same time. | ||
|
||
## Static Analysis | ||
|
||
### Technique | ||
|
||
Malicious code such as the cradle itself could be detected simply by | ||
blocking code which contains both `DownloadString` and `Invoke-Expression`. | ||
|
||
(incremental_delivery)= | ||
### Our Bypass | ||
|
||
PowerHub has two approaches. One is the "incremental delivery", by which | ||
pieces of the stager are loaded incrementally. To avoid the cradle itself | ||
being detected, PowerHub knows the option "split cradle". You will then have | ||
to execute two commands in the same PowerShell session, which may not always | ||
be possible. | ||
|
||
## Behavior Analysis | ||
|
||
### Technique | ||
|
||
Some actions that malware typically performs are inherently suspicious: | ||
Process hollowing, accessing honey tokens, getting a handle on the LSASS | ||
process, etc. | ||
|
||
These actions are detectable in principle, and that's one of the techniques | ||
employed by modern antivirus products. The only issue is that not all | ||
actions are inherently suspicious but still considered malware. Whatever | ||
[BloodHound](https://github.com/BloodHoundAD/BloodHound) does, for example. | ||
|
||
### Our Bypass | ||
|
||
Yeah I got nothing. Dear friends from Kaspersky, Palo Alto and Windows | ||
Defender: That's where I'd focus. Good luck. | ||
|
||
## Counter measures | ||
|
||
So what you can do as a defender about software like PowerHub? | ||
|
||
It's simple: | ||
|
||
* Enable constrained language mode | ||
* Make sure PowerShell version 2 is disabled | ||
* Block all executables in user-writable directories as well as [these LOLBINs](https://learn.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/microsoft-recommended-block-rules) | ||
* Fine, also allow signed binaries matching a fixed list of product names like | ||
"Microsoft Teams" even if they are located in writable directories | ||
|
||
(Hey, no one said it would be easy, I only said it was simple ...) | ||
|
||
And don't get too hung up on this tool. These techniques are not new and not | ||
unique to PowerHub. Antivirus products can *always* be tricked. They are | ||
insufficient and you should apply application control instead, for example | ||
using AppLocker or Application Guard. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Welcome to PowerHub's documentation! | ||
|
||
```{toctree} | ||
:hidden: | ||
:maxdepth: 2 | ||
:caption: "Contents:" | ||
|
||
installation | ||
philosophy | ||
new | ||
changelog | ||
evasion | ||
usage | ||
troubleshooting | ||
contrib | ||
``` | ||
|
||
|
||
```{include} ../README.md | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Installation and Quickstart | ||
|
||
It's a Python package hosted on [PyPI](https://pypi.org/project/PowerHub/). You install it like any other | ||
Python package: | ||
|
||
```console | ||
$ python3 -m pip install powerhub | ||
``` | ||
|
||
Installation from the GitHub repository should be avoided, unless you are | ||
willing to test out new features. You will be more likely to encounter bugs | ||
than if you install the releases. | ||
|
||
To build the [binary payloads](binary_payloads), you will need the MinGW GCC and Mono C# | ||
compilers. On Debian-like systems, you can install them with `apt-get | ||
install mono-mcs gcc-mingw-w64-x86-64 gcc-mingw-w64-i686`. | ||
|
||
After the installation, two new executables will be placed in `~/.local/bin`: | ||
|
||
1. `powerhub` | ||
2. `power-obfuscate` | ||
|
||
Execute `powerhub <CALLBACK HOST> --auth powerhub:<PASSWORD>`, where | ||
`<CALLBACK HOST>` is an IP address or hostname from which the victim system | ||
can reach your system and `<PASSWORD>` is a strong password of your choice. | ||
Then, browse to `https://<CALLBACK HOST>:8443` either from your system or | ||
the victim system and accept the self-sigend certificate. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# New in PowerHub 2.0 | ||
|
||
PowerHub grew over the years from a small script™ meant for personal | ||
experiments or even learning exercises to a tool that many people use, so | ||
with version 2.0 come some well-deserved changes, like proper documentation, | ||
packaging and a more fleshed-out implementation of some ideas I had in the | ||
beginning. | ||
|
||
## Documentation | ||
|
||
Documentation is now hosted by GitHub pages; the GitHub wiki is disabled. | ||
|
||
## Packaging | ||
|
||
The `powerhub.py` and `requirements.txt` have been removed. The `setup.py` | ||
has been replaced with a `pyproject.toml`. PowerHub is now a first-class | ||
Python package and should be treated as such. Like any other Python package, | ||
it should be installed with `pip install`, which will place executables in | ||
`~/.local/bin`. | ||
|
||
## No more dev branch | ||
|
||
Development will happen directly on the master branch. Releases will be | ||
tagged and made available on PyPI. Installing directly from the repository | ||
is not recommended, unless you want to test out the latest changes or you | ||
want to contribute to the project. I will be less inclined to help out with | ||
issues if you use a bleeding edge version. Bug reports will always be | ||
welcome, though! | ||
|
||
## Workspace directory | ||
|
||
There is now a clearer separation of files that belong to the workspace | ||
directory. To be precise, the database and most directories in | ||
`$XDG_DATA_HOME/powerhub` have been moved into a new subdirectory named | ||
`workspace`. As a side effect, this may make your clipboard and uploads | ||
files appear empty. This fixes that (assuming `$XDG_DATA_HOME` is | ||
undefined): | ||
|
||
```console | ||
$ cd ~/.local/share/powerhub | ||
$ mv powerhub_db.sqlite upload webdav* workspace/ | ||
``` | ||
|
||
## Key exchange | ||
|
||
In PowerHub 1.0, the key was simply embedded in the stager. In principle, | ||
this is a vulnerability, as specialized antivirus products could use the key | ||
to inspect the higher order stages. PowerHub 2.0 performs a Diffie-Hellman | ||
key exchange by default (but no server verification on top of the TLS | ||
handshake) and also supports an out-of-band key exchange, meaning the key is | ||
pasted on the command line. | ||
|
||
## Pre-loaded modules | ||
|
||
It's now possible to deliver the PowerHub payload with some modules | ||
pre-loaded. This is interesting for environments without network access. If | ||
the key is also embedded in the stager, you can deliver it manually e.g. via | ||
USB to the target and use the modules. | ||
|
||
## power-obfuscate | ||
|
||
Installing PowerHub will yield a new executable: `power-obfuscate`. This | ||
makes it possible to use the obfuscation techniques of PowerHub on arbitrary | ||
PowerShell scripts or .NET executables without having to use the web | ||
application. | ||
|
||
## Depreciation of Load-HubModule | ||
|
||
It was confusing to have both `Load-HubModule` and `Get-HubModule`. We had | ||
to execute the former to be able to use the latter. Now there is only | ||
`Get-HubModule`. It performs lazy loading over the network when needed, | ||
which means that the code of the module is transferred the first time you | ||
execute `Get-HubModule` or if you explicitely pass the `-Reload` switch. | ||
|
||
## Depreciation of the Loot tab | ||
|
||
Dumping LSASS is too much of a moving target and should be left to specialty | ||
tools. The idea was that dumping LSASS is possible with only | ||
[LOLBINs](https://lolbas-project.github.io/), so it seemed like a small | ||
addition to endow PowerHub with this capability, but things have gotten | ||
complicated lately. AVs are quarantining the dump file, the LSASS process is | ||
protected by various mechanisms, etc. It's better to use specialized tools | ||
as outlined [here](https://s3cur3th1ssh1t.github.io/Reflective-Dump-Tools/) | ||
and references therein. |
Oops, something went wrong.