14 KiB
コンパイルされたPythonバイナリ(exe、elf)の逆コンパイル - .pycから取得する
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ企業で働いていますか? HackTricksで会社を宣伝したいですか?または、PEASSの最新バージョンを入手したり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを発見しましょう、私たちの独占的なNFTのコレクション
- 公式のPEASS&HackTricksのグッズを手に入れましょう
- 💬 Discordグループまたはtelegramグループに参加するか、Twitterでフォローする🐦@carlospolopm.
- ハッキングのトリックを共有するには、PRを hacktricks repo と hacktricks-cloud repo に提出してください。
ハッキングのキャリアに興味があり、解読不能なものを解読する - 採用中です!(流暢なポーランド語の読み書きが必要です)。
{% embed url="https://www.stmcyber.com/careers" %}
コンパイルされたバイナリから.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バイナリでコンパイルされた場合、次のコマンドを実行することで**.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ファイルの先頭に次のバイトを追加**する必要があります: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'>
のようなその他のエラーが表示されることがあります。
これはおそらく、正しいマジックナンバーを正しく追加していないか、正しいマジックナンバーを使用していないことを意味しています。したがって、正しいマジックナンバーを使用していることを確認してください(または新しいものを試してみてください)。
前のエラードキュメントを確認してください。
自動ツール
ツールhttps://github.com/countercept/python-exe-unpackerは、Pythonで書かれた実行可能ファイルをアンパックおよびデコンパイルするための研究者を支援するためのいくつかのツールをコミュニティに提供しています(py2exeおよびpyinstallerを使用して作成された実行可能ファイルであることも確認します)。
Pythonで書かれた実行可能ファイルかどうかを判断するためのいくつかのYARAルールが利用可能です(このスクリプトは、実行可能ファイルがpy2exeまたはpyinstallerで作成されたものであるかどうかも確認します)。
ImportError: ファイル名:'unpacked/malware_3.exe/pycache/archive.cpython-35.pyc' が存在しません
現在、unpy2exeまたはpyinstxtractorを使用して得られるPythonバイトコードファイルは完全ではない場合があり、その結果、uncompyle6によってプレーンなPythonソースコードを取得することができません。これは、欠落しているPython バイトコードバージョン番号によるものです。そのため、prependオプションを追加しました。これにより、Pythonバイトコードバージョン番号が含まれ、デコンパイルのプロセスが容易になります。uncompyle6を使用して.pycファイルをデコンパイルしようとするとエラーが返されます。ただし、prependオプションを使用すると、Pythonソースコードが正常にデコンパイルされたことが確認できます。
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
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から実行可能ファイルへ
まず、ペイロードがpy2exeとPyInstallerでコンパイルされる方法を紹介します。
py2exeを使用してペイロードを作成する手順:
- http://www.py2exe.org/からpy2exeパッケージをインストールします。
- ペイロードにはスクリプトを使用します(この場合、hello.pyという名前にします)。図1に示すようなスクリプトを使用します。オプション「bundle_files」の値を1に設定すると、Pythonインタプリタを含むすべてが1つの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
PyInstallerを使用してペイロードを作成する方法:
- pipを使用してPyInstallerをインストールします(pip install pyinstaller)。
- その後、コマンド「pyinstaller --onefile hello.py」を実行します('hello.py'は私たちのペイロードです)。これにより、すべてが1つの実行可能ファイルにバンドルされます。
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.
参考文献
もし ハッキングのキャリア に興味があり、ハックできないものをハックしたい場合 - 採用中です! (流暢なポーランド語の読み書きが必要です).
{% embed url="https://www.stmcyber.com/careers" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ企業で働いていますか? HackTricksで会社を宣伝したいですか?または、最新バージョンのPEASSにアクセスしたり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを見つけてください、私たちの独占的なNFTのコレクション
- 公式のPEASS&HackTricksのグッズを手に入れましょう
- 💬 Discordグループまたはtelegramグループに参加するか、Twitterで私をフォローしてください🐦@carlospolopm.
- ハッキングのトリックを共有するために、PRを hacktricks repo と hacktricks-cloud repo に提出してください。