Decompile compiled python binaries (exe, elf) - Retreive from .pyc
Reading time: 7 minutes
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
From Compiled Binary to .pyc
Kutoka kwa ELF binary iliyokusanywa unaweza kupata .pyc kwa:
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
Katika python exe binary iliyokusanywa unaweza kupata .pyc kwa kukimbia:
python pyinstxtractor.py executable.exe
Kutoka .pyc hadi msimbo wa python
Kwa data ya .pyc ("imeundwa" python) unapaswa kuanza kujaribu kutoa msimbo wa asili wa python:
uncompyle6 binary.pyc > decompiled.py
Hakika kwamba binary ina kiambatisho ".pyc" (ikiwa sio, uncompyle6 haitafanya kazi)
Wakati wa kutekeleza uncompyle6 unaweza kukutana na makosa yafuatayo:
Kosa: Nambari ya uchawi isiyojulikana 227
/kali/.local/bin/uncompyle6 /tmp/binary.pyc
Unknown magic number 227 in /tmp/binary.pyc
Ili kurekebisha hili unahitaji kuongeza nambari sahihi ya kichawi mwanzoni mwa faili lililotengenezwa.
Nambari za kichawi zinatofautiana kulingana na toleo la python, ili kupata nambari ya kichawi ya python 3.8 unahitaji kufungua terminal ya python 3.8 na kutekeleza:
>> import imp
>> imp.get_magic().hex()
'550d0d0a'
Nambari ya mchawi katika kesi hii kwa python3.8 ni 0x550d0d0a
, kisha, ili kurekebisha kosa hili utahitaji kuongeza mwanzoni mwa .pyc file bytes zifuatazo: 0x0d550a0d000000000000000000000000
Mara tu umepata kuongeza kichwa hicho cha mchawi, kosa linapaswa kurekebishwa.
Hivi ndivyo kichwa cha .pyc python3.8 kilichoongezwa kwa usahihi kitakavyokuwa:
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
Hitilafu: Kuondoa makosa ya jumla
Makosa mengine kama: class 'AssertionError'>; co_code should be one of the types (<class 'str'>, <class 'bytes'>, <class 'list'>, <class 'tuple'>); is type <class 'NoneType'>
yanaweza kuonekana.
Hii huenda inamaanisha kwamba hujazi vizuri nambari ya kichawi au kwamba huja tumia nambari ya kichawi sahihi, hivyo hakikisha unatumia ile sahihi (au jaribu mpya).
Angalia hati za makosa ya awali.
Chombo Kiotomatiki
Chombo cha python-exe-unpacker kinatumika kama mchanganyiko wa zana kadhaa zinazopatikana katika jamii zilizoundwa kusaidia watafiti katika kuondoa na kuondoa makosa ya executable zilizoandikwa kwa Python, hasa zile zilizoundwa na py2exe na pyinstaller. Inajumuisha sheria za YARA kubaini ikiwa executable ni ya msingi wa Python na kuthibitisha chombo kilichotumika kuunda.
ImportError: Jina la faili: 'unpacked/malware_3.exe/pycache/archive.cpython-35.pyc' halipo
Tatizo la kawaida linalokabiliwa linahusisha faili isiyo kamilifu ya bytecode ya Python inayotokana na mchakato wa kuondoa na unpy2exe au pyinstxtractor, ambayo kisha inashindwa kutambuliwa na uncompyle6 kutokana na kukosekana kwa nambari ya toleo la bytecode ya Python. Ili kushughulikia hili, chaguo la kuongezea limeongezwa, ambalo linaongeza nambari inayohitajika ya toleo la bytecode ya Python, kurahisisha mchakato wa kuondoa makosa.
Mfano wa tatizo:
# 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.
Kuchambua mkusanyiko wa python
Ikiwa hujaweza kutoa "kanuni" ya python kufuatia hatua zilizopita, basi unaweza kujaribu kutoa mkusanyiko (lakini siyo wa kueleweka sana, hivyo jaribu kutoa tena kanuni ya asili). Katika hapa nilipata kanuni rahisi sana ya kufanya disassembly ya .pyc binary (bahati njema katika kuelewa mtiririko wa kanuni). Ikiwa .pyc ni kutoka python2, tumia 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 to Executable
Ili kuanza, tutakuonyesha jinsi payloads zinavyoweza kukusanywa katika py2exe na PyInstaller.
Kuunda payload kwa kutumia py2exe:
- Sakinisha pakiti ya py2exe kutoka http://www.py2exe.org/
- Kwa payload (katika kesi hii, tutaiita hello.py), tumia script kama ile katika Mchoro 1. Chaguo “bundle_files” chenye thamani ya 1 kitakusanya kila kitu ikiwa ni pamoja na mfasiri wa Python katika exe moja.
- Mara tu script ikikamilika, tutatoa amri “python setup.py py2exe”. Hii itaunda executable, kama ilivyo katika Mchoro 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
Kuunda payload kwa kutumia PyInstaller:
- Sakinisha PyInstaller kwa kutumia pip (pip install pyinstaller).
- Baada ya hapo, tutatoa amri “pyinstaller –onefile hello.py” (kumbuka kwamba ‘hello.py’ ni payload yetu). Hii itakusanya kila kitu katika executable moja.
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.
Marejeo
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.