Decompilacija kompajliranih python binarnih fajlova (exe, elf) - Preuzimanje iz .pyc
Reading time: 7 minutes
tip
Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
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 kompajliranom možete dobiti .pyc pokretanjem:
python pyinstxtractor.py executable.exe
Od .pyc do python koda
Za .pyc podatke ("kompilirani" python) trebali biste početi da pokušavate da izvučete originalni python kod:
uncompyle6 binary.pyc > decompiled.py
Uverite se da binarni fajl ima ekstenziju ".pyc" (ako ne, uncompyle6 neće raditi)
Tokom izvršavanja uncompyle6 mogli biste naići na sledeće greške:
Greška: Nepoznat magični broj 227
/kali/.local/bin/uncompyle6 /tmp/binary.pyc
Unknown magic number 227 in /tmp/binary.pyc
Da biste to popravili, potrebno je da dodate ispravan magični broj na početku generisanog fajla.
Magični brojevi se razlikuju u zavisnosti od verzije pythona, da biste dobili magični broj za python 3.8, potrebno je da otvorite python 3.8 terminal i izvršite:
>> import imp
>> imp.get_magic().hex()
'550d0d0a'
Magični broj u ovom slučaju za python3.8 je 0x550d0d0a
, zatim, da biste ispravili ovu grešku, moraćete da dodate na početak .pyc datoteke sledeće bajtove: 0x0d550a0d000000000000000000000000
Jednom kada ste dodali taj magični zaglavlje, greška bi trebala biti 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: Decompiling generic errors
Druge greške kao što su: 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.
To verovatno znači da niste ispravno dodali magični broj ili da niste koristili ispravan magični broj, pa se pobrinite da koristite ispravan (ili pokušajte novi).
Proverite dokumentaciju o prethodnim greškama.
Automatski alat
python-exe-unpacker alat služi kao kombinacija nekoliko alata dostupnih u zajednici, dizajniranih da pomognu istraživačima u raspakivanju i decompiling 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
Uobičajen problem koji se javlja uključuje nepotpunu Python bytecode datoteku koja je rezultat procesa raspakivanja sa unpy2exe ili pyinstxtractor, koja zatim ne može biti prepoznata od strane uncompyle6 zbog nedostatka broja verzije Python bytecode-a. Da bi se to rešilo, dodata je opcija za preklapanje, koja dodaje neophodan broj verzije Python bytecode-a, olakšavajući proces decompiling-a.
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 asemblera
Ako niste mogli da izvučete "originalni" python kod prateći prethodne korake, možete pokušati da izvučete asembler (ali nije baš opisno, pa pokušajte ponovo da izvučete originalni kod). U ovde sam pronašao vrlo jednostavan kod za dezintegraciju .pyc binarnog fajla (srećno sa razumevanjem toka koda). Ako je .pyc iz python2, koristite python2:
>>> 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šni fajl
Da počnemo, pokažaćemo vam kako se payloadi mogu kompajlirati u py2exe i PyInstaller.
Da kreirate payload koristeći py2exe:
- Instalirajte py2exe paket sa http://www.py2exe.org/
- Za payload (u ovom slučaju, nazvaćemo ga hello.py), koristite skriptu kao što je prikazano na Slici 1. Opcija “bundle_files” sa vrednošću 1 će sve spojiti, uključujući Python interpreter, u jedan exe.
- Kada je skripta spremna, izdaćemo komandu “python setup.py py2exe”. Ovo će kreirati izvršni fajl, 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
Da biste kreirali payload koristeći PyInstaller:
- Instalirajte PyInstaller koristeći pip (pip install pyinstaller).
- Nakon toga, izdaćemo komandu “pyinstaller –onefile hello.py” (podsećanje da je ‘hello.py’ naš payload). Ovo će sve spojiti 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
tip
Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.