Decompile gecompileerde python binêre (exe, elf) - Herwin van .pyc
Reading time: 7 minutes
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Van Gecompileerde Binêre na .pyc
Van 'n ELF gecompileerde binêre kan jy die .pyc kry met:
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
In 'n python exe binêre gecompileer kan jy die .pyc kry deur te loop:
python pyinstxtractor.py executable.exe
Van .pyc na python kode
Vir die .pyc data ("gecompileerde" python) moet jy begin probeer om die oorspronklike python kode te onttrek:
uncompyle6 binary.pyc > decompiled.py
Maak seker dat die binêre die uitbreiding ".pyc" het (as nie, gaan uncompyle6 nie werk nie)
Terwyl jy uncompyle6 uitvoer, mag jy die volgende foute teëkom:
Fout: Onbekende magiese nommer 227
/kali/.local/bin/uncompyle6 /tmp/binary.pyc
Unknown magic number 227 in /tmp/binary.pyc
Om dit reg te maak, moet jy die korrekte magiese nommer aan die begin van die gegenereerde lêer voeg.
Magiese nommers verskil met die python weergawe, om die magiese nommer van python 3.8 te kry, sal jy 'n python 3.8 terminal moet oopmaak en uitvoer:
>> import imp
>> imp.get_magic().hex()
'550d0d0a'
Die magic number in hierdie geval vir python3.8 is 0x550d0d0a
, dan, om hierdie fout reg te stel, sal jy moet byvoeg aan die begin van die .pyc file die volgende bytes: 0x0d550a0d000000000000000000000000
Sodra jy daardie magic header bygevoeg het, behoort die fout reggestel te wees.
So sal 'n korrek bygevoegde .pyc python3.8 magic header lyk:
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
Fout: Decompiling generiese foute
Ander foute soos: class 'AssertionError'>; co_code moet een van die tipes (<class 'str'>, <class 'bytes'>, <class 'list'>, <class 'tuple'>); is tipe <class 'NoneType'>
mag verskyn.
Dit beteken waarskynlik dat jy nie korrek die magiese nommer bygevoeg het nie of dat jy nie die korrekte magiese nommer gebruik het nie, so maak verseker jy gebruik die korrekte een (of probeer 'n nuwe een).
Kyk na die vorige fout dokumentasie.
Outomatiese Gereedskap
Die python-exe-unpacker tool dien as 'n kombinasie van verskeie gemeenskap-beskikbare gereedskap wat ontwerp is om navorsers te help met die unpacking en decompiling van uitvoerbare lêers geskryf in Python, spesifiek dié wat met py2exe en pyinstaller geskep is. Dit sluit YARA-reëls in om te identifiseer of 'n uitvoerbare lêer op Python gebaseer is en bevestig die skeppingstoestel.
ImportError: Lêernaam: 'unpacked/malware_3.exe/pycache/archive.cpython-35.pyc' bestaan nie
'n Algemene probleem wat ondervind word, behels 'n onvolledige Python bytecode-lêer wat ontstaan uit die unpacking proses met unpy2exe of pyinstxtractor, wat dan nie deur uncompyle6 erken word nie weens 'n ontbrekende Python bytecode weergawe nommer. Om dit aan te spreek, is 'n prepend opsie bygevoeg, wat die nodige Python bytecode weergawe nommer byvoeg, wat die decompiling proses vergemaklik.
Voorbeeld van die probleem:
# 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.
Analysering python assembly
As jy nie in staat was om die python "oorspronklike" kode te onttrek nie, kan jy probeer om die assembly te onttrek (maar dit is nie baie beskrywend nie, so probeer om die oorspronklike kode weer te onttrek). In hier het ek 'n baie eenvoudige kode gevind om die .pyc binêre te ontbind (sterkte met die verstaan van die kodevloei). As die .pyc van python2 is, gebruik 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 na Uitvoerbare
Om te begin, gaan ons jou wys hoe payloads in py2exe en PyInstaller gekompileer kan word.
Om 'n payload te skep met py2exe:
- Installeer die py2exe-pakket van http://www.py2exe.org/
- Vir die payload (in hierdie geval, gaan ons dit hello.py noem), gebruik 'n skrif soos die een in Figuur 1. Die opsie “bundle_files” met die waarde van 1 sal alles insluit, insluitend die Python-interpretator, in een exe.
- Sodra die skrif gereed is, sal ons die opdrag “python setup.py py2exe” gee. Dit sal die uitvoerbare skep, net soos in Figuur 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
Om 'n payload te skep met PyInstaller:
- Installeer PyInstaller met pip (pip install pyinstaller).
- Daarna sal ons die opdrag “pyinstaller –onefile hello.py” gee (’n herinnering dat ‘hello.py’ ons payload is). Dit sal alles in een uitvoerbare lêer saamvoeg.
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.
Verwysings
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.