Derlenmiş python ikili dosyalarını decompile et (exe, elf) - .pyc'den al

Reading time: 7 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin

Derlenmiş İkili Dosyadan .pyc'ye

Bir ELF derlenmiş ikili dosyasından .pyc'yi alabilirsiniz:

bash
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

Bir python exe ikili dosyasında .pyc almak için şunu çalıştırabilirsiniz:

bash
python pyinstxtractor.py executable.exe

.pyc'den python koduna

.pyc verisi ("derlenmiş" python) için orijinal python kodunu çıkarma denemeye başlamalısınız:

bash
uncompyle6 binary.pyc  > decompiled.py

Kesin olun ki, ikili dosyanın uzantısı ".pyc"dir (değilse, uncompyle6 çalışmayacaktır)

uncompyle6 çalıştırırken aşağıdaki hatalarla karşılaşabilirsiniz:

Hata: Bilinmeyen sihirli sayı 227

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

Bunu düzeltmek için oluşturulan dosyanın başına doğru sihirli numarayı eklemeniz gerekiyor.

Sihirli numaralar python sürümüne göre değişir, python 3.8'in sihirli numarasını almak için bir python 3.8 terminali açmanız ve şunu çalıştırmanız gerekecek:

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

Bu durumda python3.8 için magic number 0x550d0d0a'dır, ardından bu hatayı düzeltmek için .pyc dosyasının başına şu baytları eklemeniz gerekecek: 0x0d550a0d000000000000000000000000

Oluşturduğunuzda o magic başlığı eklenmiş olmalıdır, hata düzeltilmiş olmalıdır.

Doğru bir şekilde eklenmiş .pyc python3.8 magic header şu şekilde görünecektir:

bash
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

Hata: Genel Hataları Decompile Etme

Diğer hatalar şunlar gibi: class 'AssertionError'>; co_code bir türlerden biri olmalıdır (<class 'str'>, <class 'bytes'>, <class 'list'>, <class 'tuple'>); tür <class 'NoneType'> görünebilir.

Bu muhtemelen büyülü numarayı doğru eklemediğiniz veya doğru büyülü numarayı kullanmadığınız anlamına gelir, bu yüzden doğru olanı kullandığınızdan emin olun (veya yeni bir tane deneyin).

Önceki hata belgelerini kontrol edin.

Otomatik Araç

python-exe-unpacker aracı, Python ile yazılmış yürütülebilir dosyaları, özellikle py2exe ve pyinstaller ile oluşturulanları açmak ve decompile etmek için araştırmacılara yardımcı olmak amacıyla tasarlanmış birkaç topluluk tarafından sunulan aracın bir kombinasyonu olarak hizmet eder. Python tabanlı bir yürütülebilir dosyanın tanımlanması için YARA kuralları içerir ve oluşturma aracını doğrular.

ImportError: Dosya adı: 'unpacked/malware_3.exe/pycache/archive.cpython-35.pyc' mevcut değil

Karşılaşılan yaygın bir sorun, unpy2exe veya pyinstxtractor ile açma işlemi sonucunda oluşan eksik bir Python bytecode dosyasıdır; bu dosya daha sonra eksik bir Python bytecode sürüm numarası nedeniyle uncompyle6 tarafından tanınmamaktadır. Bunu çözmek için, gerekli Python bytecode sürüm numarasını ekleyen bir prepend seçeneği eklenmiştir, bu da decompile etme sürecini kolaylaştırır.

Sorunun örneği:

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
python
# 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 montajını analiz etme

Eğer önceki adımları takip ederek python "orijinal" kodunu çıkaramadıysanız, o zaman montajı çıkarmayı deneyebilirsiniz (ama çok açıklayıcı değil, bu yüzden orijinal kodu tekrar çıkarmayı deneyin). Burada .pyc ikili dosyasını dağıtmak için çok basit bir kod buldum (kod akışını anlamakta iyi şanslar). Eğer .pyc python2'den ise, python2 kullanın:

bash
>>> 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'ı Çalıştırılabilir Hale Getirme

Başlamak için, payload'ların py2exe ve PyInstaller ile nasıl derleneceğini göstereceğiz.

py2exe kullanarak bir payload oluşturmak için:

  1. http://www.py2exe.org/ adresinden py2exe paketini yükleyin.
  2. Payload için (bu durumda, hello.py adını vereceğiz), Şekil 1'deki gibi bir script kullanın. “bundle_files” seçeneği 1 değeri ile, Python yorumlayıcısı da dahil olmak üzere her şeyi tek bir exe dosyasında birleştirecektir.
  3. Script hazır olduğunda, “python setup.py py2exe” komutunu vereceğiz. Bu, Şekil 2'deki gibi çalıştırılabilir dosyayı oluşturacaktır.
python
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,
)
bash
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

PyInstaller kullanarak bir payload oluşturmak için:

  1. PyInstaller'ı pip ile kurun (pip install pyinstaller).
  2. Daha sonra “pyinstaller –onefile hello.py” komutunu vereceğiz (hatırlatma olarak ‘hello.py’ payload'ımızdır). Bu, her şeyi tek bir çalıştırılabilir dosya haline getirecektir.
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.

Referanslar

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin