Αποσυμπίεση συμπιεσμένων εκτελέσιμων αρχείων python (exe, elf) - Ανάκτηση από .pyc
Reading time: 8 minutes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Από Συμπιεσμένο Εκτελέσιμο σε .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 που έχει μεταγλωττιστεί, μπορείτε να πάρετε το .pyc εκτελώντας:
python pyinstxtractor.py executable.exe
Από .pyc σε κώδικα python
Για τα .pyc δεδομένα ("συμπιεσμένος" python) θα πρέπει να ξεκινήσετε προσπαθώντας να εξαγάγετε τον αρχικό κώδικα python:
uncompyle6 binary.pyc > decompiled.py
Βεβαιωθείτε ότι το δυαδικό αρχείο έχει την επέκταση ".pyc" (αν όχι, το uncompyle6 δεν θα λειτουργήσει)
Κατά την εκτέλεση του uncompyle6 μπορεί να συναντήσετε τα παρακάτω σφάλματα:
Σφάλμα: Άγνωστος μαγικός αριθμός 227
/kali/.local/bin/uncompyle6 /tmp/binary.pyc
Unknown magic number 227 in /tmp/binary.pyc
Για να το διορθώσετε, πρέπει να προσθέσετε τον σωστό μαγικό αριθμό στην αρχή του παραγόμενου αρχείου.
Οι μαγικοί αριθμοί διαφέρουν ανάλογα με την έκδοση της python, για να αποκτήσετε τον μαγικό αριθμό της python 3.8 θα χρειαστεί να ανοίξετε ένα τερματικό python 3.8 και να εκτελέσετε:
>> import imp
>> imp.get_magic().hex()
'550d0d0a'
Ο μαγικός αριθμός σε αυτή την περίπτωση για python3.8 είναι 0x550d0d0a
, στη συνέχεια, για να διορθώσετε αυτό το σφάλμα θα χρειαστεί να προσθέσετε στην αρχή του .pyc αρχείου τα εξής bytes: 0x0d550a0d000000000000000000000000
Μόλις έχετε προσθέσει αυτή την μαγική κεφαλίδα, το σφάλμα θα πρέπει να διορθωθεί.
Έτσι θα φαίνεται μια σωστά προστιθέμενη .pyc python3.8 μαγική κεφαλίδα:
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'>
μπορεί να εμφανιστούν.
Αυτό πιθανώς σημαίνει ότι δεν έχετε προσθέσει σωστά τον μαγικό αριθμό ή ότι δεν έχετε χρησιμοποιήσει τον σωστό μαγικό αριθμό, οπότε βεβαιωθείτε ότι χρησιμοποιείτε τον σωστό (ή δοκιμάστε έναν νέο).
Ελέγξτε την τεκμηρίωση του προηγούμενου σφάλματος.
Αυτόματο Εργαλείο
Το python-exe-unpacker tool λειτουργεί ως συνδυασμός αρκετών εργαλείων διαθέσιμων στην κοινότητα που έχουν σχεδιαστεί για να βοηθήσουν τους ερευνητές στην αποσυμπίεση και αποσυμπίεση εκτελέσιμων αρχείων γραμμένων σε Python, συγκεκριμένα αυτών που δημιουργήθηκαν με py2exe και pyinstaller. Περιλαμβάνει κανόνες YARA για να προσδιορίσει αν ένα εκτελέσιμο είναι βασισμένο σε Python και επιβεβαιώνει το εργαλείο δημιουργίας.
ImportError: Όνομα αρχείου: 'unpacked/malware_3.exe/pycache/archive.cpython-35.pyc' δεν υπάρχει
Ένα κοινό πρόβλημα που συναντάται περιλαμβάνει ένα ατελές αρχείο bytecode Python που προκύπτει από τη διαδικασία αποσυμπίεσης με unpy2exe ή pyinstxtractor, το οποίο στη συνέχεια αποτυγχάνει να αναγνωριστεί από το uncompyle6 λόγω έλλειψης αριθμού έκδοσης bytecode Python. Για να αντιμετωπιστεί αυτό, έχει προστεθεί μια επιλογή prepend, η οποία προσθέτει τον απαραίτητο αριθμό έκδοσης bytecode Python, διευκολύνοντας τη διαδικασία αποσυμπίεσης.
Παράδειγμα του προβλήματος:
# 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
Αν δεν μπορέσατε να εξαγάγετε τον "αρχικό" κώδικα python ακολουθώντας τα προηγούμενα βήματα, τότε μπορείτε να προσπαθήσετε να εξαγάγετε τη συναρμολόγηση (αλλά δεν είναι πολύ περιγραφική, οπότε προσπαθήστε να εξαγάγετε ξανά τον αρχικό κώδικα). Στο εδώ βρήκα έναν πολύ απλό κώδικα για να αποσυναρμολογήσετε το .pyc δυαδικό (καλή τύχη στην κατανόηση της ροής του κώδικα). Αν το .pyc είναι από python2, χρησιμοποιήστε 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 σε Εκτελέσιμο
Για να ξεκινήσουμε, θα σας δείξουμε πώς μπορούν να μεταγλωττιστούν οι payloads σε py2exe και PyInstaller.
Για να δημιουργήσετε μια payload χρησιμοποιώντας py2exe:
- Εγκαταστήστε το πακέτο py2exe από http://www.py2exe.org/
- Για την payload (σε αυτή την περίπτωση, θα την ονομάσουμε hello.py), χρησιμοποιήστε ένα σενάριο όπως αυτό στην Εικόνα 1. Η επιλογή “bundle_files” με την τιμή 1 θα συνδυάσει τα πάντα, συμπεριλαμβανομένου του διερμηνέα Python, σε ένα exe.
- Μόλις το σενάριο είναι έτοιμο, θα εκδώσουμε την εντολή “python setup.py py2exe”. Αυτό θα δημιουργήσει το εκτελέσιμο, ακριβώς όπως στην Εικόνα 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
Για να δημιουργήσετε ένα payload χρησιμοποιώντας το PyInstaller:
- Εγκαταστήστε το PyInstaller χρησιμοποιώντας το pip (pip install pyinstaller).
- Μετά από αυτό, θα εκδώσουμε την εντολή “pyinstaller –onefile hello.py” (υπενθύμιση ότι το ‘hello.py’ είναι το payload μας). Αυτό θα συγκεντρώσει τα πάντα σε ένα εκτελέσιμο αρχείο.
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.
Αναφορές
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.