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

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Savet za bug bounty: registrujte se za Intigriti, premium platformu za bug bounty kreiranu od hakera, za hakere! Pridružite nam se na https://go.intigriti.com/hacktricks danas, i počnite da zarađujete nagrade do $100,000!

Od Kompajliranog Binarnog Fajla do .pyc

Iz ELF kompajliranog binarnog fajla možete dobiti .pyc sa:

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

U python exe binarnom fajlu možete dobiti .pyc pokretanjem:

python pyinstxtractor.py executable.exe

Od .pyc do python koda

Za .pyc podatke ("kompajlirani" python) trebalo bi da počnete sa pokušajem izvlačenja originalnog python koda:

uncompyle6 binary.pyc  > decompiled.py

Proverite da li binarni fajl ima ekstenziju ".pyc" (ako nema, uncompyle6 neće raditi)

Prilikom izvršavanja uncompyle6 mogu se pojaviti sljedeće greške:

Greška: Nepoznat broj magičnog broja 227

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

Da biste to popravili, treba da dodatе tačan magični broj na početku generisanog fajla.

Magični brojevi variraju sa verzijom python-a, da biste dobili magični broj za python 3.8 treba da otvorite python 3.8 terminal i izvršite:

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

U ovom slučaju, magični broj za python3.8 je 0x550d0d0a, zatim, da biste ispravili ovu grešku, moraćete dodati na početak .pyc datoteke sledeće bajtove: 0x0d550a0d000000000000000000000000

Kada dodate taj magični zaglavlje, greška bi trebalo da bude ispravljena.

Ovako će izgledati ispravno dodato .pyc python3.8 magično zaglavlje:

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

Greška: Dekompilacija generičkih grešaka

Druge greške poput: class 'AssertionError'>; co_code should be one of the types (<class 'str'>, <class 'bytes'>, <class 'list'>, <class 'tuple'>); is type <class 'NoneType'> mogu se pojaviti.

Ovo verovatno znači da nisu pravilno dodati magični brojevi ili da niste koristili ispravan magični broj, pa se uverite da koristite ispravan (ili pokušajte sa novim).

Proverite dokumentaciju prethodne greške.

Automatski alat

Alat python-exe-unpacker služi kao kombinacija nekoliko alata dostupnih zajednici, dizajniranih da pomognu istraživačima u raspakivanju i dekompilaciji izvršnih datoteka napisanih u Pythonu, posebno onih kreiranih sa py2exe i pyinstaller. Uključuje YARA pravila za identifikaciju da li je izvršna datoteka zasnovana na Pythonu i potvrđuje alat za kreiranje.

ImportError: Ime datoteke: 'unpacked/malware_3.exe/pycache/archive.cpython-35.pyc' ne postoji

Čest problem koji se javlja uključuje nepotpunu Python bajtkod datoteku koja proizilazi iz procesa raspakivanja sa unpy2exe ili pyinstxtractor, što onda nije prepoznato od strane uncompyle6 zbog nedostajućeg broja verzije Python bajtkoda. Da biste rešili ovo, dodata je opcija prepend, koja dodaje neophodan broj verzije Python bajtkoda, olakšavajući proces dekompilacije.

Primer problema:

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

Analiza python montaže

Ako niste uspeli da izvučete "originalni" Python kod prateći prethodne korake, možete pokušati da izvučete montažu (ali nije veoma opisna, pa pokušajte ponovo da izvučete originalni kod). U ovde sam pronašao veoma jednostavan kod za raspakivanje .pyc binarnog fajla (srećno sa razumevanjem toka koda). Ako je .pyc fajl iz Python 2, koristite Python 2:

>>> 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('<H', magic[:2])
>>> timestamp = struct.unpack('<I', timestamp)
>>> code = marshal.loads(code)
>>> magic, timestamp, code
((62211,), (1425911959,), <code object <module> at 0x7fd54f90d5b0, file "hello.py", line 1>)
>>>
>>> # Verify if the magic number corresponds with the current python version
>>> struct.unpack('<H', imp.get_magic()[:2]) == magic
True
>>>
>>> # Disassemble the code object
>>> dis.disassemble(code)
1           0 LOAD_CONST               0 (<code object hello_world at 0x7f31b7240eb0, file "hello.py", line 1>)
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

Python u izvršnu datoteku

Da bismo počeli, pokazaćemo vam kako se payloadi mogu kompajlirati u py2exe i PyInstaller.

Za kreiranje payloada korišćenjem py2exe:

  1. Instalirajte paket py2exe sa http://www.py2exe.org/

  2. Za payload (u ovom slučaju, nazvaćemo ga hello.py), koristite skriptu poput one u Figuri 1. Opcija "bundle_files" sa vrednošću 1 će uključiti sve, uključujući Python interpretera, u jednu izvršnu datoteku.

  3. Kada je skripta spremna, izdaćemo komandu "python setup.py py2exe". Ovo će kreirati izvršnu datoteku, baš kao na slici 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

Za kreiranje payload-a korišćenjem PyInstaller-a:

  1. Instalirajte PyInstaller korišćenjem pip-a (pip install pyinstaller).

  2. Nakon toga, izdaćemo komandu "pyinstaller --onefile hello.py" (napomena da je 'hello.py' naš payload). Ovo će sve upakovati u jedan izvršni fajl.

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.

Reference

Savet o nagradi za otkrivanje grešaka: Prijavite se za Intigriti, premijum platformu za otkrivanje grešaka kreiranu od strane hakera, za hakere! Pridružite nam se na https://go.intigriti.com/hacktricks danas, i počnite da zarađujete nagrade do $100,000!

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Last updated