Decompile compiled python binaries (exe, elf) - Retreive from .pyc
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Bug bounty tip: sign up for Intigriti, a premium bug bounty platform created by hackers, for hackers! Join us at https://go.intigriti.com/hacktricks today, and start earning bounties up to $100,000!
From an ELF compiled binary you can get the .pyc with:
In a python exe binary compiled you can get the .pyc by running:
For the .pyc data ("compiled" python) you should start trying to extract the original python code:
Be sure that the binary has the extension ".pyc" (if not, uncompyle6 is not going to work)
While executing uncompyle6 you might find the following errors:
To fix this you need to add the correct magic number at the beginning of the generated file.
Magic numbers vary with the python version, to get the magic number of python 3.8 you will need to open a python 3.8 terminal and execute:
The magic number in this case for python3.8 is 0x550d0d0a
, then, to fix this error you will need to add at the beginning of the .pyc file the following bytes: 0x0d550a0d000000000000000000000000
Once you have added that magic header, the error should be fixed.
This is how a correctly added .pyc python3.8 magic header will look like:
Other errors like: class 'AssertionError'>; co_code should be one of the types (<class 'str'>, <class 'bytes'>, <class 'list'>, <class 'tuple'>); is type <class 'NoneType'>
may appear.
This probably means that you haven't added correctly the magic number or that you haven't used the correct magic number, so make sure you use the correct one (or try a new one).
Check the previous error documentation.
The python-exe-unpacker tool serves as a combination of several community-available tools designed to assist researchers in unpacking and decompiling executables written in Python, specifically those created with py2exe and pyinstaller. It includes YARA rules to identify if an executable is Python-based and confirms the creation tool.
A common issue encountered involves an incomplete Python bytecode file resulting from the unpacking process with unpy2exe or pyinstxtractor, which then fails to be recognized by uncompyle6 due to a missing Python bytecode version number. To address this, a prepend option has been added, which appends the necessary Python bytecode version number, facilitating the decompiling process.
Example of the issue:
If you weren't able to extract the python "original" code following the previous steps, then you can try to extract the assembly (but it isn't very descriptive, so try to extract again the original code).In here I found a very simple code to disassemble the .pyc binary (good luck understanding the code flow). If the .pyc is from python2, use python2:
To start, we’re going to show you how payloads can be compiled in py2exe and PyInstaller.
Install the py2exe package from http://www.py2exe.org/
For the payload (in this case, we will name it hello.py), use a script like the one in Figure 1. The option “bundle_files” with the value of 1 will bundle everything including the Python interpreter into one exe.
Once the script is ready, we will issue the command “python setup.py py2exe”. This will create the executable, just like in Figure 2.
Install PyInstaller using pip (pip install pyinstaller).
After that, we will issue the command “pyinstaller –onefile hello.py” (a reminder that ‘hello.py’ is our payload). This will bundle everything into one executable.
Bug bounty tip: sign up for Intigriti, a premium bug bounty platform created by hackers, for hackers! Join us at https://go.intigriti.com/hacktricks today, and start earning bounties up to $100,000!
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)