Decompile compiled python binaries (exe, elf) - Retreive from .pyc

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Kutoka Binary Iliyokusanywa hadi .pyc

Kutoka kwenye binary ya ELF iliyokusanywa unaweza kupata .pyc kwa:

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

Katika python exe binary iliyokusanywa unaweza kupata .pyc kwa kuendesha:

python pyinstxtractor.py executable.exe

Kutoka .pyc hadi python code

Kwa data ya .pyc (“iliyokompyuliwa” python) unapaswa kuanza kujaribu kutoa asili python code:

uncompyle6 binary.pyc  > decompiled.py

Hakikisha kwamba binary ina extension.pyc” (kama si hivyo, uncompyle6 haitafanya kazi)

Wakati unapotekeleza uncompyle6 unaweza kukutana na makosa yafuatayo:

Error: Unknown magic number 227

/kali/.local/bin/uncompyle6 /tmp/binary.pyc
Unknown magic number 227 in /tmp/binary.pyc

Ili kurekebisha hili unahitaji kuongeza magic number sahihi mwanzoni mwa faili iliyotengenezwa.

Magic numbers zinatofautiana kulingana na toleo la python, ili kupata magic number ya python 3.8 utahitaji kufungua terminal ya python 3.8 na utekeleze:

>> import imp
>> imp.get_magic().hex()
'550d0d0a'

Nambari ya kichawi katika kesi hii kwa python3.8 ni 0x550d0d0a, hivyo, ili kurekebisha kosa hili utahitaji kuongeza katika mwanzoni mwa faili ya .pyc bajeti zifuatazo: 0x0d550a0d000000000000000000000000

Mara baada ya kuongeza kichwa hicho cha magic, kosa linapaswa kurekebishwa.

Hivi ndivyo kichwa kilichoongezwa kwa usahihi cha .pyc python3.8 magic header kitakavyoonekana:

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

Hitilafu: Decompiling generic errors

Makosa mengine kama: class 'AssertionError'>; co_code should be one of the types (<class 'str'>, <class 'bytes'>, <class 'list'>, <class 'tuple'>); is type <class 'NoneType'> yanaweza kuonekana.

Hii pengine inamaanisha kuwa wewe hujaongeza kwa usahihi the magic number au kwamba wewe hamtumi the correct magic number, hivyo hakikisha unatumia ile sahihi (au jaribu mpya).

Angalia nyaraka za hitilafu zilizotangulia.

Chombo Otomatiki

The python-exe-unpacker tool inafanya kazi kama mchanganyiko wa zana kadhaa zinazopatikana kwa jamii iliyoundwa kusaidia watafiti katika unpacking na decompiling ya executables zilizoandikwa kwa Python, hasa zile zilizotengenezwa na py2exe na pyinstaller. Inajumuisha sheria za YARA kutambua kama executable ni ya Python na kuthibitisha zana iliyotumika kutengeneza.

ImportError: File name: ‘unpacked/malware_3.exe/pycache/archive.cpython-35.pyc’ doesn’t exist

Tatizo la kawaida ni faili isiyokamilika ya Python bytecode inayotokana na unpacking process with unpy2exe or pyinstxtractor, ambayo kisha inashindwa kutambuliwa na uncompyle6 kutokana na kukosekana kwa nambari ya toleo la Python bytecode. Kutatua hili, chaguo la prepend limeongezwa, ambalo linaongeza nambari inayohitajika ya toleo la Python bytecode, likirahisisha mchakato wa decompiling.

Mfano wa tatizo:

# 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.

Kuchambua python assembly

Ikiwa haukuweza kupata msimbo wa “asili” wa python ukifuata hatua zilizotangulia, basi unaweza kujaribu kutoa assembly (lakini si ya kueleza sana, kwa hivyo jaribu tena kupata msimbo wa asili). In here nilipata mfano rahisi wa msimbo wa disassemble wa binari .pyc (bahati njema kuelewa mtiririko wa msimbo). Ikiwa .pyc ni kutoka python2, tumia 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('>> timestamp = struct.unpack('>> code = marshal.loads(code) >>> magic, timestamp, code ((62211,), (1425911959,), 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

  • Toa blob za marshal zilizoambatishwa: pyi-archive_viewer sample.exe and export raw objects (e.g., a file named vvs). PyInstaller huhifadhi bare marshal streams ambazo huanza na 0xe3 (TYPE_CODE with FLAG_REF) badala ya faili kamili za .pyc. Prepend the correct 16-byte .pyc header (magic ya toleo la embedded interpreter + timestamp/size zilizosetwa kwa sifuri) ili decompilers zikubali. Kwa Python 3.11.5 unaweza kupata magic kupitia imp.get_magic().hex() na kuipatch kwa dd/printf kabla ya marshal payload.
  • Decompile with version-aware tools: pycdc -c -v 3.11.5 vvs.pyc > vvs.py or PyLingual. Ikiwa unahitaji tu sehemu ya msimbo, unaweza kutembea AST (kwa mfano, ast.NodeVisitor) ili kuchota hoja/konstanti maalum.
  • Parse the Pyarmor v9 header ili kurejesha parametri za crypto: signature PY<license> at 0x00, Python major/minor at 0x09/0x0a, protection type 0x09 when BCC is enabled (0x08 otherwise), ELF start/end offsets at 0x1c/0x38, and the 12-byte AES-CTR nonce split across 0x24..0x27 and 0x2c..0x33. Mchoro ule ule unajirudia baada ya embedded ELF.
  • Zingatia code objects zilizobadilishwa na Pyarmor: co_flags ina bit 0x20000000 imewekwa na uwanja wa ziada uliowekwa na length-prefix. Zima CPython deopt_code() wakati wa parsing ili kuepuka kushindwa kwa decryption.
  • Tambua maeneo ya msimbo yaliyosimbwa: bytecode imefunikwa na LOAD_CONST __pyarmor_enter_*__LOAD_CONST __pyarmor_exit_*__. Decrypt the enclosed blob with AES-128-CTR using the runtime key (e.g., 273b1b1373cf25e054a61e2cb8a947b8). Derive the per-region nonce by XORing the payload-specific 12-byte XOR key (from the Pyarmor runtime) with the 12 bytes in the __pyarmor_exit_*__ marker. Baada ya decryption, pia unaweza kuona __pyarmor_assert_*__ (encrypted strings) na __pyarmor_bcc_*__ (compiled dispatch targets).
  • Decrypt Pyarmor “mixed” strings: constants prefixed with 0x81 ni AES-128-CTR encrypted (plaintext uses 0x01). Tumia key ile ile na runtime-derived string nonce (e.g., 692e767673e95c45a1e6876d) ili kupata konstanti ndefu za string.
  • Shughulikia BCC mode: Pyarmor --enable-bcc inakuwa compile functions nyingi kwenye companion ELF na inaacha Python stubs zinazopiga __pyarmor_bcc_*__. Ramani hizo konstanti kwa ELF symbols kwa zana kama bcc_info.py, kisha decompile/analyze ELF kwenye offsets zilizoripotiwa (e.g., __pyarmor_bcc_58580__bcc_180 at offset 0x4e70).

Python to Executable

Kuanza, tutakuonyesha jinsi payloads zinavyoweza kukusanywa (compiled) katika py2exe na PyInstaller.

To create a payload using py2exe:

  1. Sakinisha package ya py2exe kutoka http://www.py2exe.org/
  2. Kwa payload (katika kesi hii, tutaiita hello.py), tumia script kama ile kwenye Figure 1. The option “bundle_files” with the value of 1 itaburuta kila kitu ikiwa pamoja na Python interpreter katika exe moja.
  3. Mara script itakapokuwa tayari, tutaendesha amri “python setup.py py2exe”. Hii itaunda executable, kama katika 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

Kuunda payload kwa kutumia PyInstaller:

  1. Sakinisha PyInstaller kwa kutumia pip (pip install pyinstaller).
  2. Baada yake, tutatoa amri “pyinstaller –onefile hello.py” (kumbuka kwamba ‘hello.py’ ni payload yetu). Hii itafanya kila kitu kiwe katika faili linaloweza kutekelezwa moja.
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.

Marejeo

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks