hacktricks/forensics/basic-forensic-methodology/specific-software-file-type.../.pyc.md

14 KiB
Raw Blame History

コンパイルされたPythonバイナリexe、elfの逆コンパイル - .pycから取得する

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

ハッキングのキャリアに興味があり、解読不能なものを解読する - 採用中です!(流暢なポーランド語の読み書きが必要です)。

{% 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を使用してペイロードを作成する手順

  1. http://www.py2exe.org/からpy2exeパッケージをインストールします。
  2. ペイロードにはスクリプトを使用しますこの場合、hello.pyという名前にします。図1に示すようなスクリプトを使用します。オプション「bundle_files」の値を1に設定すると、Pythonインタプリタを含むすべてが1つのexeにバンドルされます。
  3. スクリプトが準備できたら、「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を使用してペイロードを作成する方法

  1. pipを使用してPyInstallerをインストールしますpip install pyinstaller
  2. その後、コマンド「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 🎥