黒ネコと学ぶエクスプロイト基礎 プロセスとメモリ(episode-04)
黒ネコと学ぶ・論理的エクスプロイト開発への道
エクスプロイト開発を学び始めると、必ず出てくる言葉があります。
それが「プロセス」と「メモリ」です。
でも、初心者のうちはこう思うかもしれません。
「プログラムを動かすのと、メモリって何が関係あるの?」と。
実は、エクスプロイトとは、「動いているプログラム(=プロセス)のメモリの使われ方を理解し、
想定外の動きをさせる技術」なんです。
つまり、プロセスとメモリを知らずにエクスプロイトは語れないということですね。
episode-04では、くろちゃんと白猫先生と一緒に、プロセスとは何か、メモリの中はどうなっているのかを、図を思い浮かべながらやさしく理解していきましょう。
※イメージです
プロセスとは
くろちゃん
白猫先生、「プロセス」ってよく聞くけど……プログラムと何が違うの?
白猫先生
いい質問ね。プログラムは「設計図」、プロセスは「動いている実体」よ。
わかりやすく解説すると
・プログラム
→ディスクに保存されている実行ファイル
・プロセス
→ プログラムを実行した瞬間に作られる「動作中の存在」
たとえば同じ `hello` プログラムでも、
./hello
./hello
と2回実行すれば、2つのプロセスが同時に存在することになります。
エクスプロイトが狙うのは、この「動いているプロセス」です。
くろちゃん
じゃあ、プロセスの中には何が入ってるの?
白猫先生
一番大事なのはね……「自分専用のメモリ空間」よ。
プロセスが持つ主な要素は、
・プロセスID(PID)
・レジスタの状態
・ファイル情報
・メモリ空間(超重要)
エクスプロイトは、このメモリ空間をどう操作できるかを考えることになります。
メモリって何? ざっくり全体像
くろちゃん
メモリって、ただの箱みたいなもの?
白猫先生
ええ。でも中は、ちゃんと区画整理されているの。
・メモリのイメージ
プロセスのメモリは、ざっくりこう分かれています。
(高いアドレス)
+----------+
| stack | ← 関数・戻り先
+----------+
| heap | ← 動的確保
+----------+
| data | ← 初期化済み変数
+----------+
| bss | ← 未初期化変数
+----------+
| text | ← プログラム本体
+----------+
(低いアドレス)
この配置の理解が、後のバッファオーバーフロー、ROP、heap exploitなど。すべての基礎になります。
スタックとヒープを少しだけ覗く
くろちゃん
名前は聞いたことあるけど、スタックとヒープって何が違うの?
白猫先生
役割がまったく違うのよ。
スタック(stack)とは
・関数の呼び出しで使われる
・ローカル変数、戻りアドレスを保存
・自動で増えて自動で消える
※スタックオーバーフローで使われる。
ヒープ(heap)とは
・malloc` などで動的に確保。
・プログラマが管理する領域。
・解放ミスが起きやすい。
※Use-After-Free / Heap Overflowで使われる。
なぜエクスプロイトで重要なのか?
くろちゃん
普通にプログラム動かすだけなら、メモリのことなんて気にしなくていいよね?
白猫先生
そう。でも攻撃者は違う。
攻撃者の視点(攻撃者はこう考えます。)
・この入力は、どのメモリに入る?
・境界チェックはある?
・スタックか?ヒープか?
・戻りアドレスを書き換えられる?
論理的エクスプロイト思考 とは、「メモリ上で何が起きるか」を順番に想像する力なのです。
GDBで「見える世界」に変わる
くろちゃん
頭で考えるだけじゃ、難しいかも……
白猫先生
だから、GDBを使うのよ。
GDBを使うと、
・レジスタ
・スタックの中身
・メモリアドレス
が、目で見えるようになります。
よって、次回以降、「GDBでスタックをのぞく」「メモリを書き換える」という実践につながっていきます。
黒ネコと学ぶエクスプロイト基礎 プロセスとメモリのまとめ
今回は、エクスプロイト開発の土台となる「プロセスとメモリ」について学びました。
ポイントは以下の通りです。
・プログラムは設計図、プロセスは実体
・プロセスは自分専用のメモリ空間を持つ
・メモリは text / data / bss / heap / stack に分かれている
・攻撃者は「入力がどこに入るか」を考える
・GDBは「見えないメモリ」を見える世界に変える
エクスプロイトは魔法ではありません。
メモリの構造を理解し、論理的に積み上げる技術です。
次回は、「GDBでスタックをのぞいてみよう」になります。
いよいよ本格的に「中身」を見ていきます。