#この記事の読み方
#はじめに
- このシリーズの目標は、pyrebox独特の部分をなるべく解説し、読んだ方が普通のpythonモジュールの使い方を勉強するかの如くpyrebox scriptingを勉強していけるようにすることです。
- この記事は、**超入門1,2を読んだ方向けです。**また、基本的にこのPDFを見つつ書いたので、さらなる情報はそちらを見てください。この記事を見ればそこまで読むのに苦労しないはずです。(それを目標に作ってます。)
#1. スクリプトの置き場とロード方法
スクリプトの置き場は、pyrebox/scripts/
が一般的と思われます。
ロードの方法は大きく分けて二つあります。
###pyrebox.confに記述しておく方法
pyrebox/scripts/script_example.py
をロードしたいなら、pyrebox.conf
の[module]
セクションに以下のように書きます。
[MODULES]
scripts.script_example_min: True
[VOL]
(以下略)
###qemu monitorからインポートする方法
pyrebox/scripts/script_example.py
をロードしたいなら、qemu monitor で以下のように入力
(qemu) import_module scripts.script_example
また、list_moduleでモジュールを確認
(qemu) list_module
+-----+----------------------------+--------+
| Hdl | Module name | Loaded |
+-----+----------------------------+--------+
| 1 | scripts.script_example_min | Yes |
| 2 | scripts.script_helloworld | No |
| 3 | scripts.script_example | Yes |
| 4 | plugins.guest_agent | Yes |
+-----+----------------------------+--------+
アンロード、リロードは上の表のHdl番号で指定します。具体的には、
アンロード:(qemu) reload_module 2
リロード:(qemu) reload_module 2
#2. スクリプティングのルール、知っておくといいこと
全てのpyreboxスクリプトは以下の二つを含まなければなりません。
- initialize_callbacks()の定義:読み込み時に実行される関数です。
- clean()の定義:アンロードするときに実行される関数です。
こう聞くととっつきにくいと思うかもしれませんが、pyrebox/scripts/script_example_min.py
が雛形用に提供されているので、はじめはそれを使えば問題ないです。また、pyrebox/scripts/script_exapmple.py
がチュートリアルを含んでいるので、自分で何か書く前にそれを読むと参考になると思います。さらに、pyrebox/pyrebox_test/
下にデモンストレーションがいくつかあるので参考にできるはずです。
#3. 自前のコマンドを定義してみよう
まずはpyrebox shell上から使えるコマンドを新たに作ってみましょう。
これのためには以下のような形式に従います。
def do_”コマンド名”(line):
```カンタンなコマンドの説明
```
以下あなたのコマンドの処理
カンタンなコマンドの説明は、標準的なpython docstringです。pyreboxがロード時に勝手に読み込んでくれるのできちんと書きましょう。
また、line はpyrebox shellから渡されるコマンドライン引数です。
百聞は一見に如かず、やってみるのが手っ取り早いと思います。
scripts
ディレクトリに移動して、雛形をコピー
$ cd ~/pyrebox/scripts/
$ cp script_example_min.py script_helloworld.py
script_helloworld.pyの87行目に以下のような部分があるはずです。
def do_my_command(line):
''' Short description of the custom command.
Long description of the custom command
'''
global pyrebox_print
global cm
# Implementation of the command functionality
pyrebox_print("This is a custom command")
この部分を以下のように変更してください。
def do_helloworld(line):
''' This is my helloworld script!.
This just print first argument
and "Hello World".
'''
global pyrebox_print
if line:
arg_list = line.split()
pyrebox_print("first_arg: %s" % (arg_list[0]))
pyrebox_print("Hello World!")
pyrebox 仮想マシンを起動してqemu monitor で以下のようにして実行できます。
(qemu) list_modules
+-----+----------------------------+--------+
| Hdl | Module name | Loaded |
+-----+----------------------------+--------+
| 1 | scripts.script_example_min | Yes |
+-----+----------------------------+--------+
(qemu) import_module scripts.script_helloworld
[*] Loading python module scripts.script_helloworld
[scripts.script_helloworld] [*] Initializing callbacks
[scripts.script_helloworld] [*] Initialized callbacks
(qemu) list_modules
+-----+----------------------------+--------+
| Hdl | Module name | Loaded |
+-----+----------------------------+--------+
| 1 | scripts.script_example_min | Yes |
| 2 | scripts.script_helloworld | Yes |
+-----+----------------------------+--------+
(qemu) sh
[1] pyrebox> %list_commands
(~中略~)
Use custom <command> <args..>
helloworld - This is my helloworld script!.
my_command - Short description of the custom command.
[2] pyrebox> custom helloworld They are arg for this command.
[scripts.script_helloworld] first_arg: They
[scripts.script_helloworld] Hello World!
list_commnad
の出力に、docstringであるThis is my helloworld script!.
が見えると思います。
#4. callbackを作成してみよう
callbackを指定する、というのは、要はなんか起きたとき実行する関数を指定するということです。(投げやり)
pyreboxでコールバックを設定/除去するには、以下のフォーマットに従います。
from api import CallbackManager
CallbackManager(Module_hdl).add_callback(CallbackManager.”コールバックの種類”, ”呼び出す関数の名前”, name=”コールバック名”)
CallbackManager(Module_hdl).rm_callback(”コールバック名”)
ただしscripts/script_example_min
等では、cmという変数でCallbackManager(Module_hdl)を参照できるように書かれているので、これをひな形として使うのなら、以下のようにするだけでOKです。また、name
は任意です。
global cm
cm.CallbackManager(Module_hdl).add_callback(CallbackManager.”コールバックの種類”, ”呼び出す関数の名前”)
CallbackManager(Module_hdl).rm_callback(”コールバック名”)
pyreboxが提供するコールバックのリストはpyrebox documentathon(pdf)に譲るとして、ここではキー入力を監視するコールバックマネージャを使って簡単なキーロガーを作ってみようと思います。
まずはひな形をコピーするところから
$ cd ~/pyrebox/scripts/
$ cp script_example_min.py keylogger.py
keylogger.pyの最後のほうに以下のような部分があるので削除してください。
def do_my_command(line):
''' Short description of the custom command.
Long description of the custom command
'''
global pyrebox_print
global cm
# Implementation of the command functionality
pyrebox_print("This is a custom command")
次に以下のコードを末尾に追加してください。
def dump_key(keycode):
'''callback function for key logger.
'''
pyrebox_print("Keystroke occured. keycode: 0x%x\n" % keycode)
def do_start_keylogger(line):
'''set keylogger that print keycode
'''
global cm
cm.add_callback(CallbackManager.KEYSTROKE_CB, dump_key, name="keystroke")
def do_stop_keylogger(line):
'''stop keykdump
'''
global cm
cm.rm_callback("keystroke")
では実際に起動してみましょう
(qemu) import_modules scripts.keylogger
[*] Loading python module scripts.keylogger
[scripts.keylogger] [*] Initializing callbacks
[scripts.keylogger] [*] Initialized callbacks
(qemu) list_modules
+-----+----------------------------+--------+
| Hdl | Module name | Loaded |
+-----+----------------------------+--------+
| 1 | scripts.script_example_min | Yes |
| 2 | scripts.keylogger | Yes |
+-----+----------------------------+--------+
(qemu) sh
[1] pyrebox> custom start_keylogger
[2] pyrebox> q
これだけ打ってからVNCクライアントでキーをガチャガチャ押せば、出力が見られるはずです。keyloggerを止めるには、
(qemu) sh
[3] pyrebox> custom stop_keylogger
[4]q
(qemu)
とすれば大丈夫です。
#5. 終わりに さらに進むのに読むといい資料
ここまでで、pyrebox独特の話題はほとんど出せたと思います。あとは、普通のpython moduleの使い方を調べるようにして調べていけるはずです。具体的にどこを見るかですが、被ってるのもありますが、ここにまとめておきます。
- 何度も紹介したpyrebox documentation(PDF): これにつきます。
-
pyrebox/scripts/
下の.pyファイル: 書かれているコメントがチュートリアルになっています。script_example.py
から読むのがおすすめ。 -
pyrebox/pyrebox_test
下のファイル: これも使用例として使えます。
お疲れさまでした。m(_ _)m
#補足1 お試し環境導入法
ここでは、試してみたい人向けにお試し環境を導入する方法をササッと書きます。コマンドの意味は言わないので知りたい人は超入門1、超入門2を見てください。(結構読むの大変だと思います。)また、現在のところインストーラによるインストールは提供されていないのですが、ひょっとしたら将来されるかもなんで、一度公式リポジトリを見てみるといいかもです。
Debian系(apt-getが使える)OS向けです。また、仮想マシンを扱うので、メモリが1GBないと苦しいかもしれません2GBあれば安心。
まずはpyreboxをクローン
$ cd ~/
$ git clone:https://github.com/Cisco-Talos/pyrebox
次に必要なパッケージをインストールしてください。
# apt-get install build-essential zlib1g-dev pkg-config libglib2.0-dev binutils-dev libboost-all-dev autoconf libtool libssl-dev libpixman-1-dev libpython-dev python-pip virtualenv python-capstone
pyreboxディレクトリに移動してpyrebox用のvirtualenvを作成して必要なモジュールなどをインストール
$ cd ~/pyrebox/
$ virtualenv pyrebox_venv
$ source pyrebox_venv/bin/activate
$ pip install -r requirements.txt
以降pyreboxを使うときは忘れずにvirtualenvをactivateしてください。
$ source pyrebox_venv/bin/activate
最後にビルド
$ ./build.sh
これでインストールは完了です。
次に起動したいISOを~/Download/
下に用意(この記事ではこちらから手に入れたarch のISOを使用します。)
ファイルを二つ以下の名前で~/pyrebox/
下に作って以下の内容を書き込んでください。
[MODULES]
[VOL]
profile: NA
#!/bin/bash
cp pyrebox.conf.arch pyrebox.conf
./pyrebox-x86_64 -monitor stdio -m 1024 -cdrom ../Downloads/archlinux-2017.10.01-x86_64.iso -boot d
あとは仮想マシンを起動
$ cd ~/pyrebox/
$ ./start_archlinux.sh
[*] Loading python component initialization script
[*] Platform: x86_64-softmmu
[*] Starting python module initialization
[*] Reading configuration from 'pyrebox.conf'
[*] Searching for KDBG...
[*] Initializing scripts...
[*] Finished python module initialization
QEMU 2.10.0 monitor - type 'help' for more information
(qemu) VNC server running on 127.0.0.1:5900
一番最後の行にある通りVNCサーバーが127.0.0.1:5900らへんに立ってるのでVNCクライアントで接続。(ポート番号は出力見て変えてください)
$ vncvvncviewer -encodings raw 127.0.0.1:5900
これで仮想マシンを起動できるはずです。(ハードディスクなしでライブ起動してる状態ですが、この記事の内容を試す分に問題ないです。)
あと、pyrebox shellの起動方法を書いておきます。..といっても (qemu)
のプロンプトでsh
と打つだけです。
$ ./start_archlinux.sh
[*] Loading python component initialization script
[*] Platform: x86_64-softmmu
[*] Starting python module initialization
[*] Reading configuration from 'pyrebox.conf'
[*] Searching for KDBG...
[*] Initializing scripts...
[*] Finished python module initialization
QEMU 2.10.0 monitor - type 'help' for more information
(qemu) VNC server running on 127.0.0.1:5901
sh
[1] pyrebox> q
(qemu) q
$
これで準備は終わりです。本格的にqemuを導入する場合この章と少しかぶりますが超入門1、超入門2を読んだほうがいいとおもいます。(ステマ)