🐙
Writeup|picoCTF PIE TIME
PIEとアドレス計算の基本
そもそもバイナリファイルとは?
-
.exeや.outみたいな実行形式のファイル - 中には「CPUに命令するコード」がぎっしり詰まってる
プログラムの本体であり、関数もすべてこの中に存在する
実行されるとどうなる?
- OSがこのファイルを メモリ上に読み込む
- 関数や変数にはそれぞれ メモリ上のアドレス(番地)が割り当てられる
- CPUはそのアドレスに沿って命令を1つずつ実行していく
CTFでの「リモートバイナリ実行」とは?
CTFではよく、問題サーバーに脆弱なバイナリが用意されていて、
nc で接続して、そのプログラムをリモートから操作する形式になっている。
PIEとは
PIE(Position Independent Executable)とは、
実行するたびに関数などのアドレスが変化する仕組みのこと。
セキュリティ強化のために導入されており、アドレスを固定しないことで攻撃を困難にする。
なぜアドレス計算が必要?
PIEが有効なバイナリでは、関数にジャンプしたくても、
実行時の正確なアドレスが毎回変わってしまう。
→ だから「アドレスを計算で求める」必要がある!
バイナリ基本問題の用語
| 用語 | 意味 |
|---|---|
| 実行時のアドレス | 「今この関数がどこにあるか」実行中に決まる(PIEのせい) |
| オフセット | 「バイナリの中での関数の場所」。固定されてる |
| ベースアドレス | 実行時の「バイナリの開始地点」。mainやwinの基準になる |
実行アドレスを求める流れ
1. mainの実行アドレス(ncで表示)をメモ
2. mainのオフセットをnmで調べる
3. ベースアドレス = 実行アドレス - オフセット
4. 実行したいアドレスのオフセットを足す → 実行アドレス完成
補足:他の防御機構(超ざっくり)
| 機能 | 内容 |
|---|---|
| PIE | 関数のアドレスを毎回ランダムに |
| NX | スタックなどに実行権限を与えない |
| Canary | バッファオーバーフロー検知用の値を挿入 |
| RELRO | 関数ポインタの書き換え防止 |
解法
1.リモートプログラムに接続する
nc rescued-float.picoctf.net 51884
picoCTFが立ち上げてくれたリモートのプログラムに自分のPCからアクセスできる。
-
rescued-float.picoctf.net→ 接続先のホスト名(サーバーのアドレス) -
51884→ 接続するポート番号(サーバー内のどのアプリかを指定)
結果:
Address of main: 0x57fd3814b33d
Enter the address to jump to, ex => 0x12345:
-
main関数のアドレスが表示されてる(今いる場所) - 正しいアドレスを入れると
flag()とかが呼ばれてフラグが出る
2.アドレスを取得するためにvuln.cを開く
win() 関数の実行アドレスを入力するとflag.txtが開くとの記載あり
- 入力されたアドレスにジャンプする処理があるから
-
win()のアドレスさえ分かれば、そこに飛ばしてflag.txtを表示できる!
3.main関数とwin関数のアドレスを調べる
nm -n ~/Downloads/vuln
実行ファイル vuln の中にある関数や変数の「アドレス一覧」を、アドレス順(-n)で表示する
結果:
00000000000012a7 T win
000000000000133d T main
| アドレス(オフセット) | シンボルの種類 | 名前 |
|---|---|---|
00000000000012a7 |
T(関数) |
win |
000000000000133d |
T(関数) |
main |
⚠️このアドレスは、実行ファイル内での「相対的な位置(オフセット)」。
実行時にはこのアドレスは ベースアドレスに加算されて実際のアドレスになる!
4.実行時の win() アドレスを計算する
① main の実行アドレスからベースアドレスを出す
ベースアドレス = 実行時の main アドレス - main のオフセット
- 実行時のアドレス →
ncのAddress of main: - オフセット →
nmコマンドで表示されたmainの位置(例:0x133d)
② win の実行アドレスを求める
winのアドレス = ベースアドレス + win のオフセット
- オフセットは同じく
nmで出たもの(例:0x12a7)
5.win関数のアドレスを入力
nc [rescued-float.picoctf.net](http://rescued-float.picoctf.net/) 51884
の結果に4-②で取得したwinの実行アドレスを入力
→flagを取得できる
Discussion