diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..68bc17f --- /dev/null +++ b/.gitignore @@ -0,0 +1,160 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +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/ +cover/ + +# 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 +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .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 + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__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/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ diff --git a/PyFuscation.py b/PyFuscation.py index eeb2a5b..945a2bd 100644 --- a/PyFuscation.py +++ b/PyFuscation.py @@ -1,12 +1,5 @@ #!/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 @@ -19,7 +12,6 @@ import string from argparse import ArgumentParser import configparser -import fileinput import banner def printR(out): print("\033[91m{}\033[00m" .format("[!] " + out)) @@ -27,30 +19,39 @@ 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): +def removeJunk(iF, oF): + is_code = True # 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): + with open(iF, 'r') as fin: + script_contents = fin.readlines() + + with open(oF, 'w') as fout: + for line in script_contents: + line = line.lstrip() + + if line.startswith('#') and not line.startswith("#>"): + pass + elif line.startswith("<#"): + is_code = False + elif line.startswith('\n'): + pass + elif line.startswith("#>"): + is_code = True + else: + if is_code: + fout.write(line) + +def replaceObject(DICT, oF): + with open(oF, 'r') as fout: + obfsucated_script_contents = fout.read() + for var in DICT: new = str(DICT.get(var)) - cmd = "sed -i -e \'s/" + var +'\\b' + "/" + new + "/g\' " + oF - realTimeMuxER(cmd) + obfsucated_script_contents = obfsucated_script_contents.replace(var, new) + + with open(oF, 'w') as fout: + fout.write(obfsucated_script_contents) + def THEreplacER(DICT, iF, oF): iFHandle = open(iF, 'r') @@ -207,9 +208,10 @@ def randomString(iFile): string = ''.join(e for e in line if e.isalnum()) return string -def main(): +def obfuscate(): iFile = args.script + time_start = time.time() printR("Obfuscating: " + iFile) ts = time.strftime("%m%d%Y_%H_%M_%S", time.gmtime()) oDir = os.path.dirname(args.script) + "/" + ts @@ -225,24 +227,24 @@ def main(): obfuFUNCs = dict() # Remove White space and comments - removeJunk(oFile) + removeJunk(iFile, oFile) # Obfuscate Variables if (args.var): obfuVAR = findVARs(iFile,vFile) - useSED(obfuVAR, oFile) + replaceObject(obfuVAR, oFile) printP("Obfuscated Variables located : " + vFile) # Obfuscate custom parameters if (args.par): obfuPARMS = findCustomParams(iFile, pFile, obfuVAR) - useSED(obfuPARMS, oFile) + replaceObject(obfuPARMS, oFile) printP("Obfuscated Parameters located : " + pFile) # Obfuscate Functions if (args.func): obfuFUNCs = findFUNCs(iFile, fFile) - useSED(obfuFUNCs, oFile) + replaceObject(obfuFUNCs, oFile) # Print the Functions print("") @@ -255,6 +257,8 @@ def main(): printP("Obfuscated Functions located : " + fFile) printP("Obfuscated script located at : " + oFile) + execution_time = (time.time() - time_start) + printY(f"Executed in: {execution_time}") if __name__ == "__main__": @@ -294,4 +298,4 @@ def main(): printR("Check wordList: " + wordList) exit() - main() + obfuscate() diff --git a/README.md b/README.md index cd57734..21683fd 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # PyFuscation -Requires python3 +Requires python3. Previous versions and the original repo do not state it but +the script relies heavily on sed. This version has replaced sed commands with +pure Python imporving Windows compatibility and future support. -![alt text](https://github.com/CBHue/PyFuscation/blob/master/PyFuscation.png) +![screenshot](screenshot.png) usage: PyFuscation.py [-h] [-f] [-v] [-p] [--ps SCRIPT] diff --git a/__pycache__/banner.cpython-310.pyc b/__pycache__/banner.cpython-310.pyc new file mode 100644 index 0000000..2123336 Binary files /dev/null and b/__pycache__/banner.cpython-310.pyc differ diff --git a/banner.py b/banner.py index 7305268..04c6161 100644 --- a/banner.py +++ b/banner.py @@ -2,25 +2,25 @@ def banner(): print("\033[91m{}\033[00m" .format(""" ------------------------------------------------------------------------------------------------------- -_|_|_| _|_|_|_| _| _| -_| _| _| _| _| _| _| _|_|_| _|_|_| _|_|_| _|_|_|_| _|_| _|_|_| -_|_|_| _| _| _|_|_| _| _| _|_| _| _| _| _| _| _| _| _| _| -_| _| _| _| _| _| _|_| _| _| _| _| _| _| _| _| _| -_| _|_|_| _| _|_|_| _|_|_| _|_|_| _|_|_| _|_| _| _|_| _| _| - _| - _|_| - """)) + ██████╗ ██╗ ██╗███████╗██╗ ██╗███████╗ ██████╗ █████╗ ████████╗ ██████╗ ██████╗ +██╔══██╗╚██╗ ██╔╝██╔════╝██║ ██║██╔════╝██╔════╝██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗ +██████╔╝ ╚████╔╝ █████╗ ██║ ██║███████╗██║ ███████║ ██║ ██║ ██║██████╔╝ +██╔═══╝ ╚██╔╝ ██╔══╝ ██║ ██║╚════██║██║ ██╔══██║ ██║ ██║ ██║██╔══██╗ +██║ ██║ ██║ ╚██████╔╝███████║╚██████╗██║ ██║ ██║ ╚██████╔╝██║ ██║ +╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ + + Reborn! + """)) def printY(out): print("\033[93m{}\033[00m" .format("[+] " + out)) def printP(out): print("\033[95m{}\033[00m" .format("[-] " + out)) def title(): - print("------------------------------------------------------------------------------------------------------") - printY("Tool : PyFuscation") - printY("Author : CB Hue") - printY("Twitter : @_cbhue_") - printY("github : https://github.com/CBHue") - print("------------------------------------------------------------------------------------------------------") + print("✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧") + printY("tTool : Obfuscation for PS scripts") + printY("Author : CB Hue") + printY("Twitter : @_cbhue_") + printY("github : https://github.com/CBHue") + print("✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧✧") print("") \ No newline at end of file diff --git a/PyFuscation.png b/screenshot.png similarity index 100% rename from PyFuscation.png rename to screenshot.png