pwndbg - GDB/LLDB エクスプロイト開発チートシート
pwndbg(「pwn-dee-bee-gee」と発音)はGDBに、そして現在はLLDBにも読み込まれるPythonプラグインで、エクスプロイト開発とリバースエンジニアリングをはるかに苦しくなくします。ヒープ検査、ROPガジェット検索、レジスタ/スタック/ポインタ「テレスコーピング」、すべての停止時にスマートなコンテキスト表示、およびコアデバッガが提供しなかった数十のコマンドを追加します。これはPEDAの後継であり、GEFの兄弟です。
インストール
| 方法 | コマンド |
|---|
| セットアップスクリプト(推奨) | git clone https://github.com/pwndbg/pwndbg && cd pwndbg && ./setup.sh |
| Nix | nix profile install github:pwndbg/pwndbg |
| Arch (AUR) | yay -S pwndbg |
| 手動GDB読み込み | ~/.gdbinitにsource /path/to/pwndbg/gdbinit.pyを追加 |
| LLDB | ~/.lldbinitにcommand script import /path/to/pwndbg/lldbinit.pyを追加 |
| 確認 | gdbを起動 — pwndbg>プロンプトが表示されるはず |
セッションの開始
| コマンド | 説明 |
|---|
gdb ./binary | pwndbgの下でバイナリを読み込む |
gdb -p PID | 実行中のプロセスにアタッチ |
gdb ./binary core | コアダンプを開いてポストモーテム分析を実行 |
start | 実行してmainで中断 |
entry | 実行してELFエントリーポイントで中断 |
r ARGS | 引数を指定して実行 |
starti | 最初の命令で停止 |
コンテキストとナビゲーション
| コマンド | 説明 |
|---|
context | 完全なコンテキストを再描画(レジスタ、逆アセンブル、スタック、バックトレース) |
context reg | レジスタペインのみを表示 |
ctx-watch EXPR | コンテキストウォッチペインに式を追加 |
nextcall | 次のcall命令までステップ |
nextret | 次のretまでステップ |
stepuntilasm mov | 指定されたニーモニックまでステップ |
xinfo ADDR | アドレスが何にマップされているかを説明(どのマッピング/セクション) |
メモリ検査
| コマンド | 説明 |
|---|
telescope ADDR | ポインタのチェーンをデリファレンス及び「テレスコーピング」 |
telescope $sp 20 | スタックポインタから20エントリをテレスコーピング |
hexdump ADDR | 16進数+ASCII ダンプ(GDBが提供すべきコマンド) |
vmmap | プロセスの仮想メモリマップを表示 |
vmmap libc | メモリマップを名前でフィルタリング |
search -t string "PASS" | メモリから文字列を検索 |
search -t bytes 0xdeadbeef | メモリからバイトパターンを検索 |
distance ADDR1 ADDR2 | 2つのアドレス間のバイト距離 |
p2p MAP1 MAP2 | 2つのマッピング間のポインタチェーンを検出 |
ヒープ分析(glibc)
| コマンド | 説明 |
|---|
heap | ヒープチャンクを列挙 |
bins | すべてのフリービンを表示(fast、tcache、small、large、unsorted) |
tcache | tcacheを検査 |
fastbins | fastbinの内容を表示 |
malloc_chunk ADDR | アドレスのチャンクヘッダをデコード |
top_chunk | トップ(wilderness)チャンクを表示 |
vis_heap_chunks | ヒープレイアウトを色で可視化 |
find_fake_fast ADDR | fastbin偽チャンクターゲットを追跡 |
エクスプロイト開発
| コマンド | 説明 |
|---|
cyclic 200 | De Bruijnパターンを生成(オフセットファインダー) |
cyclic -l 0x6161616c | パターン内の値のオフセットを検索 |
rop --grep "pop rdi" | ROPガジェットを検索 |
ropgadget | ガジェットをダンプ(ROPgadget統合) |
checksec | バイナリの軽減策を表示(NX、PIE、RELRO、canary) |
got | GOTと解決されたアドレスを表示 |
plt | PLTを表示 |
aslr | デバッギー用のASLRを表示/切り替え |
canary | 現在のスタックcanary値を表示 |
ブレークポイントとウォッチポイント
| コマンド | 説明 |
|---|
b *0x401136 | 絶対アドレスで中断 |
b main | シンボルで中断 |
breakrva 0x1136 | RVAで中断(PIEで便利) |
watch GLOBAL | 値が変わるとき中断 |
rwatch ADDR | 読み取りアクセスで中断 |
ignore N COUNT | ブレークポイントをN回無視 |
一般的なワークフロー
# 保存されたリターンアドレスを上書きするための正確なオフセットを見つける
pwndbg> cyclic 200
pwndbg> r # パターンを貼り付け、クラッシュ
pwndbg> cyclic -l $rsp # オフセットを報告
# 軽減策を検査し、ワンガジェットフレンドリーなROPチェーンを探す
pwndbg> checksec
pwndbg> rop --grep "pop rdi"
# ヒープ・ユース・アフター・フリーを追跡する
pwndbg> vis_heap_chunks
pwndbg> bins
pwndbg vs GEF vs PEDA
| 機能 | pwndbg | GEF | PEDA |
|---|
| GDBサポート | あり | あり | あり |
| LLDBサポート | あり | なし | なし |
| ヒープ分析 | 深い(glibc) | 良好 | 制限的 |
| ROPツール | ビルトイン | ビルトイン | ビルトイン |
| アクティブ開発 | あり | あり | 最小限 |
リソース