कम्पाइल्ड python बाइनरीज़ (exe, elf) को Decompile करें - .pyc से पुनःप्राप्त करें
Tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
कम्पाइल्ड बाइनरी से .pyc तक
एक ELF कम्पाइल्ड बाइनरी से आप .pyc प्राप्त कर सकते हैं:
pyi-archive_viewer <binary>
# The list of python modules will be given here:
[(0, 230, 311, 1, 'm', 'struct'),
(230, 1061, 1792, 1, 'm', 'pyimod01_os_path'),
(1291, 4071, 8907, 1, 'm', 'pyimod02_archive'),
(5362, 5609, 13152, 1, 'm', 'pyimod03_importers'),
(10971, 1473, 3468, 1, 'm', 'pyimod04_ctypes'),
(12444, 816, 1372, 1, 's', 'pyiboot01_bootstrap'),
(13260, 696, 1053, 1, 's', 'pyi_rth_pkgutil'),
(13956, 1134, 2075, 1, 's', 'pyi_rth_multiprocessing'),
(15090, 445, 672, 1, 's', 'pyi_rth_inspect'),
(15535, 2514, 4421, 1, 's', 'binary_name'),
...
? X binary_name
to filename? /tmp/binary.pyc
किसी कम्पाइल किए गए python exe binary में, आप निम्न कमांड चलाकर get the .pyc प्राप्त कर सकते हैं:
python pyinstxtractor.py executable.exe
.pyc से python code तक
आपको .pyc डेटा (“कम्पाइल किया हुआ” python) के लिए original python code को extract करने की कोशिश शुरू करनी चाहिए:
uncompyle6 binary.pyc > decompiled.py
सुनिश्चित करें कि binary में extension “.pyc” है (यदि नहीं, uncompyle6 काम नहीं करेगा)
जब आप uncompyle6 चला रहे होते हैं तो आपको निम्नलिखित त्रुटियाँ मिल सकती हैं:
Error: Unknown magic number 227
/kali/.local/bin/uncompyle6 /tmp/binary.pyc
Unknown magic number 227 in /tmp/binary.pyc
इसे ठीक करने के लिए आपको जेनरेट की गई फ़ाइल की शुरुआत में सही magic number जोड़ना होगा।
Magic numbers python version के साथ भिन्न होते हैं, python 3.8 का magic number पाने के लिए आपको python 3.8 टर्मिनल खोलकर निष्पादित करना होगा:
>> import imp
>> imp.get_magic().hex()
'550d0d0a'
इस मामले में python3.8 के लिए magic number 0x550d0d0a है, इसलिए इस त्रुटि को ठीक करने के लिए आपको .pyc file के beginning में निम्नलिखित बाइट्स add करने होंगे: 0x0d550a0d000000000000000000000000
एक बार आपने वह magic header जोड़ दिया है, तो त्रुटि ठीक हो जानी चाहिए।
सही तरीके से जोड़ा गया .pyc python3.8 magic header इस तरह दिखेगा:
hexdump 'binary.pyc' | head
0000000 0d55 0a0d 0000 0000 0000 0000 0000 0000
0000010 00e3 0000 0000 0000 0000 0000 0000 0000
0000020 0700 0000 4000 0000 7300 0132 0000 0064
0000030 0164 006c 005a 0064 0164 016c 015a 0064
त्रुटि: डीकम्पाइलिंग सामान्य त्रुटियाँ
अन्य त्रुटियाँ जैसे: class 'AssertionError'>; co_code should be one of the types (<class 'str'>, <class 'bytes'>, <class 'list'>, <class 'tuple'>); is type <class 'NoneType'> दिखाई दे सकती हैं।
इसका सम्भावित अर्थ यह है कि आपने मैजिक नंबर सही तरीके से जोड़ना नहीं किया है या आपने सही मैजिक नंबर उपयोग नहीं किया है, इसलिए सुनिश्चित करें कि आप सही वाला उपयोग करें (या नया आज़माएँ)।
पिछली त्रुटि दस्तावेज़ देखें।
स्वचालित टूल
The python-exe-unpacker tool कई समुदाय-उपलब्ध टूल्स के संयोजन के रूप में काम करता है, जो शोधकर्ताओं को Python में लिखे executables, विशेषकर py2exe और pyinstaller से बनाए गए, को अनपैक और डीकम्पाइल करने में मदद करते हैं। यह YARA rules शामिल करता है ताकि यह पहचान सके कि कोई executable Python-आधारित है और किस टूल से बनाया गया था।
ImportError: फ़ाइल का नाम: ‘unpacked/malware_3.exe/pycache/archive.cpython-35.pyc’ मौजूद नहीं है
एक सामान्य समस्या यह है कि unpacking process with unpy2exe or pyinstxtractor के कारण Python bytecode फ़ाइल अधूरी रहती है, जो फिर uncompyle6 द्वारा पहचानी नहीं जाती क्योंकि Python bytecode version number गायब होता है। इसे संबोधित करने के लिए, एक prepend विकल्प जोड़ा गया है, जो आवश्यक Python bytecode version number जोड़ देता है और डीकम्पाइलिंग प्रक्रिया को सुगम बनाता है।
Example of the issue:
# Error when attempting to decompile without the prepend option
test@test: uncompyle6 unpacked/malware_3.exe/archive.py
Traceback (most recent call last):
...
ImportError: File name: 'unpacked/malware_3.exe/__pycache__/archive.cpython-35.pyc' doesn't exist
# Successful decompilation after using the prepend option
test@test:python python_exe_unpack.py -p unpacked/malware_3.exe/archive
[*] On Python 2.7
[+] Magic bytes are already appended.
# Successfully decompiled file
[+] Successfully decompiled.
python assembly का विश्लेषण
यदि आप पिछले स्टेप्स का पालन करने के बाद python “original” कोड निकालने में सक्षम नहीं थे, तो आप extract करके assembly को देखने की कोशिश कर सकते हैं (लेकिन iयह बहुत वर्णनात्मक नहीं है, इसलिए कोशिश करें कि मूल कोड को फिर से निकालें)। here में मुझे .pyc बाइनरी को disassemble करने का एक बहुत सरल कोड मिला (code flow समझना आसान नहीं होगा)। यदि .pyc python2 से है, तो python2 का उपयोग करें:
Disassemble a .pyc
```python >>> import dis >>> import marshal >>> import struct >>> import imp >>> >>> with open('hello.pyc', 'r') as f: # Read the binary file ... magic = f.read(4) ... timestamp = f.read(4) ... code = f.read() ... >>> >>> # Unpack the structured content and un-marshal the code >>> magic = struct.unpack(' at 0x7fd54f90d5b0, file "hello.py", line 1>)
>>>
>>> # Verify if the magic number corresponds with the current python version
>>> struct.unpack('>>
>>> # Disassemble the code object
>>> dis.disassemble(code)
1 0 LOAD_CONST 0 ()
3 MAKE_FUNCTION 0
6 STORE_NAME 0 (hello_world)
9 LOAD_CONST 1 (None)
12 RETURN_VALUE
>>>
>>> # Also disassemble that const being loaded (our function)
>>> dis.disassemble(code.co_consts[0])
2 0 LOAD_CONST 1 ('Hello {0}')
3 LOAD_ATTR 0 (format)
6 LOAD_FAST 0 (name)
9 CALL_FUNCTION 1
12 PRINT_ITEM
13 PRINT_NEWLINE
14 LOAD_CONST 0 (None)
17 RETURN_VALUE
```
PyInstaller raw marshal & Pyarmor v9 static unpack workflow
- Extract embedded marshal blobs:
pyi-archive_viewer sample.exe और raw objects एक्सपोर्ट करें (उदाहरण के लिए, एक फ़ाइल जिसका नाम vvs). PyInstaller bare marshal streams स्टोर करता है जो 0xe3 (TYPE_CODE with FLAG_REF) से शुरू होते हैं बजाय पूरे .pyc फाइलों के। सही 16-byte .pyc header (embedded interpreter version का magic + zeroed timestamp/size) prepend करें ताकि decompilers इसे स्वीकार करें। Python 3.11.5 के लिए आप magic imp.get_magic().hex() से ले सकते हैं और marshal payload के पहले dd/printf से patch कर सकते हैं।
- Decompile with version-aware tools:
pycdc -c -v 3.11.5 vvs.pyc > vvs.py या PyLingual का उपयोग करें। यदि केवल आंशिक कोड चाहिए, तो आप AST में ट्रैवर्स करके (उदाहरण के लिए, ast.NodeVisitor) विशिष्ट arguments/constants निकाल सकते हैं।
- Parse the Pyarmor v9 header ताकि crypto parameters recover हो सकें: signature
PY<license> पर 0x00, Python major/minor पर 0x09/0x0a, protection type 0x09 जब BCC enabled हो (0x08 अन्यथा), ELF start/end offsets पर 0x1c/0x38, और 12-byte AES-CTR nonce जो 0x24..0x27 और 0x2c..0x33 में विभाजित है। वही पैटर्न embedded ELF के बाद भी दोहराया जाता है।
- Account for Pyarmor-modified code objects:
co_flags में bit 0x20000000 सेट होता है और एक extra length-prefixed field रहता है। parsing के दौरान CPython का deopt_code() disable करें ताकि decryption failures से बचा जा सके।
- Identify encrypted code regions: bytecode
LOAD_CONST __pyarmor_enter_*__ … LOAD_CONST __pyarmor_exit_*__ से wrap होता है। enclosed blob को AES-128-CTR से runtime key (उदाहरण: 273b1b1373cf25e054a61e2cb8a947b8) का उपयोग करके decrypt करें। per-region nonce derive करने के लिए payload-specific 12-byte XOR key (Pyarmor runtime से) को __pyarmor_exit_*__ marker में मौजूद 12 bytes के साथ XOR करें। Decryption के बाद आप __pyarmor_assert_*__ (encrypted strings) और __pyarmor_bcc_*__ (compiled dispatch targets) भी देख सकते हैं।
- Decrypt Pyarmor “mixed” strings: constants जो
0x81 से prefixed हैं वे AES-128-CTR से encrypted होते हैं (plaintext में 0x01 उपयोग होता है)। वही key और runtime-derived string nonce (उदाहरण: 692e767673e95c45a1e6876d) उपयोग करके लंबे string constants recover करें।
- Handle BCC mode: Pyarmor
--enable-bcc कई functions को companion ELF में compile करता है और Python stubs छोड़ देता है जो __pyarmor_bcc_*__ को कॉल करते हैं। उन constants को ELF symbols के साथ map करें ऐसे tooling से जैसे bcc_info.py, फिर रिपोर्ट किए गए offsets पर ELF को decompile/analyze करें (उदाहरण: __pyarmor_bcc_58580__ → bcc_180 at offset 0x4e70)।
Python to Executable
To start, हम दिखाएँगे कि payloads को py2exe और PyInstaller में कैसे compile किया जा सकता है।
To create a payload using py2exe:
- Install the py2exe package from http://www.py2exe.org/
- Payload के लिए (इस मामले में, हम इसका नाम
hello.py रखेंगे), Figure 1 जैसा script उपयोग करें। option “bundle_files” का value 1 सब कुछ bundle कर देगा, जिसमें Python interpreter भी शामिल है, एक single exe में।
- जब script तैयार हो जाए, तो command चलाएँ “python setup.py py2exe”. इससे executable बनेगा, ठीक Figure 2 की तरह।
from distutils.core import setup
import py2exe, sys, os
sys.argv.append('py2exe')
setup(
options = {'py2exe': {'bundle_files': 1}},
#windows = [{'script': "hello.py"}],
console = [{'script': "hello.py"}],
zipfile = None,
)
C:\Users\test\Desktop\test>python setup.py py2exe
running py2exe
*** searching for required modules ***
*** parsing results ***
*** finding dlls needed ***
*** create binaries ***
*** byte compile python files ***
*** copy extensions ***
*** copy dlls ***
copying C:\Python27\lib\site-packages\py2exe\run.exe -> C:\Users\test\Desktop\test\dist\hello.exe
Adding python27.dll as resource to C:\Users\test\Desktop\test\dist\hello.exe
PyInstaller का उपयोग करके एक payload बनाने के लिए:
- pip का उपयोग करके PyInstaller इंस्टॉल करें (pip install pyinstaller).
- उसके बाद, हम कमांड “pyinstaller –onefile hello.py” चलाएंगे (याद रहे कि ‘hello.py’ हमारा payload है)। इससे सब कुछ एक executable में बंडल हो जाएगा.
C:\Users\test\Desktop\test>pyinstaller --onefile hello.py
108 INFO: PyInstaller: 3.3.1
108 INFO: Python: 2.7.14
108 INFO: Platform: Windows-10-10.0.16299
………………………………
5967 INFO: checking EXE
5967 INFO: Building EXE because out00-EXE.toc is non existent
5982 INFO: Building EXE from out00-EXE.toc
5982 INFO: Appending archive to EXE C:\Users\test\Desktop\test\dist\hello.exe
6325 INFO: Building EXE from out00-EXE.toc completed successfully.
संदर्भ
- https://blog.f-secure.com/how-to-decompile-any-python-binary/
- VVS Discord Stealer Using Pyarmor for Obfuscation and Detection Evasion
Tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:
HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।