Powershell script that git-clones, compiles, obfuscates, donuts, and encrypts .NET assemblies. This project is pretty much a (scuffed and worse) powershell port of OffensivePipeline.
You probably want to use an actual CI/CD pipeline instead of this half-baked powershell script. At most this would be useful for homelabs and personal use.
For a real CI/CD pipeline, consider using something with Azure like @Flangvik's SharpCollection
All credits goes to :
- @domchell and his mind-blowing CovertToolsmith presentation (galaxy brain)
- @Aetsu's Offensive Pipeline. This project is pretty much a (scuffed and worse) powershell port of OffensivePipeline.
- @FuzzySec's Discerning Finch - For environmental keying and decrypting - inspired to add encrytion
(From OffensivePipeline README)
- Build Tools for Visual Studio 2019: https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16
- Install .NET Desktop build tools
-
nuget.exe, Confuser.CLI.exe, git.exe, donut.exe
in yourPATH
environment. The script will download/recommend these binaries, but you have to manually put these in your PATH. -
.NET 3.5.1 for some tools
-
Turn off Windows Defender you dummy!
-
Check all the requirements
-
Modify the tools.json's output directory
{
"outDir": "c:\\dev\\testo\\",
"tools": [
. . .
- Start a powershell console with execution policy bypassed, and have fun!
powershell -exec bypass
. ./Invoke-PrepareAssembly
- Currently "arch" is broken. Suggest just keeping it as
Any CPU
. If you specifically want x64 or x86, change it inside Visual studio. Need to research how to do this programmatically, tbd.
JSON file mode - RECOMMENDED
# All switches at the same time
Invoke-PrepareAssembly -jsonfile ./tools.json -gitclone -compile -obfuscate
Invoke-PrepareAssembly -jsonfile ./tools.json -compile -obfuscate
# One switch at a time
Invoke-PrepareAssembly -jsonfile ./tools.json -gitclone
Invoke-PrepareAssembly -jsonfile ./tools.json -compile
Invoke-PrepareAssembly -jsonfile ./tools.json -obfuscate
Invoke-PrepareAssembly -jsonfile ./tools.json -encrypt -key "single key encrypting all tools ohnononono"
# Only specific tool - Ex. Seatbelt
Invoke-PrepareAssembly -jsonfile ./tools.json -toolname SeatBelt -gitclone -compile -obfuscate -encrypt -key "encryptmeplease"
Invoke-PrepareAssembly -jsonfile ./tools.json -toolname SeatBelt -compile -obfuscate
Single file mode - Currently NOT implemented, half broken.
Invoke-PrepareAssembly -gitlink <git> -gitclone
Invoke-PrepareAssembly -slnPath <path_to_sln_file> -outDir <output_directory> -compile
Invoke-PrepareAssembly -inFile <path_to_assembly> -outDir <output_directory> -obfuscate
Invoke-PrepareAssembly -inFile <path_to_assembly> -outDir <output_directory> -encrypt -key "Hello World"
Invoke-PrepareAssembly -infile <path_to_assembly> -donut
Invoke-PrepareAssembly -infile <path_to_assembly> -donut -donutArgs <donut.exe_arguments>
- TBH this is half implemented half broken, suggest using the jsonFile mode.
Switches | Mandatory Flags | Optional Flags |
---|---|---|
-gitclone | -gitLink, -outDir | N/A |
-compile | -slnPath, -outDir | -arch, -outputType, -dotnetVersion |
-obfuscate | -inFile, -slnPath, -outDir | -confuserConfig, -level |
-encrypt | -key | |
-donut | -inFile | -donutArgs |
- Configure the config in the source code (for now)
[Parameter(Mandatory=$false, HelpMessage='ConfuserEx configuration XML file path. If not provided, use a default one.')]
[string] $confuserConfig =
@"
<project outputDir="{{OUTPUT_DIR}}" baseDir="{{BASE_DIR}}" xmlns="http://www.google.com">
<packer id="compressor" />
<rule pattern="true" preset="{{LEVEL}}" inherit="false">
<protection id="anti ildasm" />
<protection id="anti debug" action="remove" /> <!-- this breaks Assembly.Load. Maybe just use donut? -->
<protection id="anti dump" />
<protection id="anti tamper" action="remove" /> <!-- this breaks Assembly.Load. Maybe just use donut? -->
<protection id="invalid metadata" />
<protection id="resources" />
<protection id="constants" />
<protection id="ctrl flow" />
<protection id="rename" action="remove" /> <!-- This just killed seatbelt for some reason -->
</rule>
<module path="{{MODULE_PATH}}" />
<!-- CopyReferences will add more modules and close off the </project> element -->
"@,
I am a wheel re-inventing addict and I wanted to practice writing powershell scripts.
- Simple C# binary that will load or decrypt+load assembly. Use for sanity check after obfuscating and encrypting through
Invoke-PrepareAssembly
.
PS> .\decryptTest.exe
ERROR(S):
Required option 'f, file' is missing.
-f, --file Required. File to load and execute
-k, --key Key for decrypting. Automatically AES256 decrypt, load, and execute
-p, --parameters Optional parameter when executing the assembly
--help Display this help screen.
--version Display version information.
.\decryptTest.exe
.\decryptTest.exe -f <confused/compiled Assembly>
.\decryptTest.exe -f <confused/compiled Assembly> -p <parameter>
.\decryptTest.exe -f <confused/compiled Assembly> -k "decryptKey"
.\decryptTest.exe -f <confused/compiled Assembly> -k "decryptKey" -p <parameter>
ex.
.\decryptTest.exe -f C:\dev\test3\Confused\Rubeus_49an72dz.exe
.\decryptTest.exe -f C:\dev\test3\Confused\Rubeus_49an72dz.exe -p triage
.\decryptTest.exe -f C:\dev\test3\Confused\Rubeus_49an72dz.exe.aes -k "testooo"
.\decryptTest.exe -f C:\dev\test3\Confused\Rubeus_49an72dz.exe.aes -k "testooo" -p "triage"
- Couldn't figure out a way to input tac/dash/hyphen into parameter.
- ex)
.\decryptTest.exe -f <seatbelt.exe> -p "-group=user"
won't work. I did some research and foundenableDashDash
for commandlineparser, but the struggle was too real. Skipping this for now.
- ex)
Implement and fix donut
Add confuserEx config to tools.json
instead?
Support base64 output for compile, obfuscate, encrypt
Support @rastamouse's dnlib adding assembly to resources to another assembly?