保護機構をやさしく理解するシリーズ。checksecの見方:最初に見るべき防御情報とは何か(第9回/全10回)
ここまでの保護機構シリーズでは、現代のバイナリに入っている代表的な守りを1つずつ学んできました。
・NXは、データ置き場でそのまま実行しにくくする。
・anaryは、return address の前で異常を見つけやすくする。
・SLRは、場所の予測を難しくする。
・PIEは、プログラム本体も固定で考えにくくする。
・RELROは、大事な表を守る。
そして、それらは「組み合わせ」で考えることが大切
ここまで来ると、次の疑問が出てきます。
・実際のバイナリを前にしたとき、最初に何を見ればいいの?
・そのバイナリに、どんな保護機構が入っているかはどう確認するの?
・頭の中の知識を、現物の確認にどうつなげるの?
この入口としてよく使われるのが、「checksec」です。
[fuki-l]checksec をとてもやさしく言うと、「このバイナリには、どんな守りが入っているかを最初に確認するための道具」です。[/fuki-l]
今回は、
・checksecとは何か。
・なぜ最初に見るのか。
・出てくる項目をどう読めばよいのか。
・何から順番に見ればよいのか。
を、やさしく順番に整理していきます。
※イメージです。
checksecとは何か
checksec とは、簡単に言えば「バイナリに入っている代表的な保護機構を一覧で確認するための道具」です。
たとえば、何かの実行ファイルを前にしたとき、人は見た目だけでは
・NXがあるか。
・Canaryがあるか。
・PIEかどうか。
・RELROは、PartialかFullか。
をすぐには判断できません。
そこでchecksecを使うと、「このファイルには、こういう守りが入っています」という情報をまとめて見やすく表示してくれます。
[fuki-l]簡単にたとえるなら、checksecは「この建物には、どんな防犯設備が付いているかを最初に見るチェック表」のようなものです。[/fuki-l]
建物に入る前に、
・鍵はあるか
・防犯カメラはあるか
・オートロックはあるか
を確認できたほうが、その建物の守り方を理解しやすいですよね。
バイナリでも同じで、まず守りの一覧を見ることで、全体像がつかみやすくなります。
つまり checksec は、いきなり細かい解析に入る前の、最初の地図確認なのです。
なぜ最初にchecksecを見るのか
では、なぜ最初にchecksecを見るのでしょうか。
理由はとてもシンプルで、「守りの有無によって、その後の見方が大きく変わるから」です。
たとえば、同じように見えるバイナリでも、
・Canaryがあるかないか。
・NXがあるかないか。
・PIEがあるかないか。
で、考えるべきことがかなり変わります。
もし、Canaryがあるなら、スタック上の大事な戻り情報に近づく前に異常を見つけられやすくなります。
NXがあるなら、スタック上のデータをそのまま命令として動かしにくくなります。
PIEやASLRがあるなら、場所を固定で考えにくくなります。
つまり、checksecを見ないまま進むと、「このバイナリがどんな守りを持っているか分からないまま考える」ことになってしまいます。
[fuki-l]簡単にたとえるなら、これはスポーツの試合で、相手チームの守備配置を見ずに作戦を立てるようなものです。[/fuki-l]
守りが強い場所もあれば、そうでもない場所もあるかもしれません。
だからまず、どんな守りがあるのかを知る必要があります。
checksec は、その最初の確認にとても役立つのです。
checksecでよく見る項目
ここで、checksecでよく見る代表的な項目を整理しましょう。
初心者のうちは、全部を細かく覚えなくても大丈夫です。
まずは「この表示は、あの保護機構のことなんだ」とつながれば十分です。
1.RELRO
ここでは、
・No RELRO
・Partial RELRO
・Full RELRO
のような表示が出ます。
これは、前回まで学んだ「大事な表をどれくらい守っているか」の情報です。
2.Stack Canary
Canary の有無です。
見張り役がいるかどうかを表しています。
3.NX
NX enabledなどの形で出ることがあります。
これは、データ置き場をそのまま実行しにくくする守りです。
4.PIE
PIE enabled などの形で出ることがあります。
これは、プログラム本体の位置を固定で考えにくくする守りです。
5.その他の項目
環境やツールによっては、さらに細かい情報が出ることもあります。
ですが、保護機構シリーズの今の段階では、まず上の4つをしっかり見られれば十分です。
[fuki-l]簡単にたとえるなら、checksecの画面は「この建物には、鍵・見張り・席替え・表の保護があるか」を並べて見せてくれる一覧表です。[/fuki-l]
サンプルの見方をやさしく考える
ここで、checksec の表示をイメージしやすいように、やさしい例を考えてみます。
1.サンプルプログラムの作成
nano checksec-sample.c
—–
#include <stdio.h>
#include <string.h>
void vuln(char *input) {
char buf[16];
strcpy(buf, input);
printf(“%s\n", buf);
}
int main(int argc, char *argv[]) {
if (argc > 1) {
vuln(argv[1]);
}
return 0;
}
—–
2.コンパイル
gcc checksec-sample.c -o checksec_sample -fstack-protector-all -no-pie -Wl,-z,relro,-z,lazy
3.checksecで確認
pwn checksec ./checksec-sample
pwn checksec ./checksec-sample
—–
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No
—–
意味としては
・Arch: amd64-64-little
これは、64ビットプログラムという意味です。
・RELRO: Partial RELRO
学校の重要書類棚のイメージで説明すると「一部だけ鍵あり」で、守りはあるが、でも最強ではない状態です
・Stack: Canary found
Canaryがいるという意味です。
・NX: NX enabled
NXが有効です。
・PIE: No PIE (0x400000)
PIEが無効です。
・Stripped: No
関数名が残っている(見える)という意味です。
ここで大切なのは、1つずつを読むだけで終わらず、「組み合わせるとどう見えるか」を考えることです。
このサンプルなら、
このプログラムは
・見張り役がいる(Canary)
・データ置き場では動かしにくい(NX)
・大事な表も少し守られている(RELRO)
でも
・プログラム本体の場所は固定気味(No PIE)
という特徴を持っています。
・見張り役がいる(Canary)
・データ置き場では動かしにくい(NX)
・大事な表も少し守られている(RELRO)
でも
・プログラム本体の場所は固定気味(No PIE)
という特徴を持っています。
白猫先生風に言うと、[fuki-l]「このプログラムには、いくつかの守りが付いているけれど、全部が最強ではない状態」です。[/fuki-l]というふうに、全体像を考えやすくなります。
つまり、checksecは、項目を読む道具であると同時に、全体像を組み立てる入口でもあるのです。
初心者はどの順番で見ればよいのか
ここが実践的にとても大切です。
初心者のうちは、checksec を見ても情報が一気に多く感じやすいです。
なので、最初は順番を決めて見ると整理しやすくなります。
おすすめは次の順番です。
1.Canaryを見る
まず、スタック上の大事な戻り情報の前に見張り役がいるかを見ます。
これは Buffer Overflow の基礎ととてもつながりやすいです。
2.NXを見る
次に、その場で実行しにくいかどうかを見ます。
「書ける」と「実行できる」は別、という考え方とつながります。
3.PIEを見る
次に、プログラム本体の位置が固定で考えやすいか、動きやすいかを見ます。
4.RELROを見る
最後に、大事な表がどれくらい守られているかを見ます。
Partial なのか Full なのかも確認します。
5.最後に全体を組み合わせる
ここまで見たら、「このバイナリは、何をしにくくしているのか」をまとめて考えます。
[fuki-l]簡単にたとえるなら、これは「建物に入る前に、防犯設備を順番にチェックする」ようなものです。[/fuki-l]
・見張りはいるか。
・実行できる場所は限られているか。
・建物の配置は固定か。
・大事な書類はどれくらい守られているか。
この順番で見ると、混乱しにくくなります。
保護機構をやさしく理解するシリーズ。checksecの見方:最初に見るべき防御情報とは何かのまとめ
今回学んだ大事なことは、checksecがバイナリに入っている代表的な保護機構を最初に確認するための道具であり、その後の見方を決める入口になるという点です。
checksec を使うことで、RELRO、Canary、NX、PIE などの有無を一覧で確認でき、「このバイナリは何をしにくくしているのか」を整理しやすくなります。大切なのは、表示をただ読むだけではなく、それぞれがどんな守りなのかを理解し、最後に組み合わせて全体像を考えることです。
初心者のうちは、まずCanary、次にNX、そのあとPIE、RELROの順で見ると理解しやすくなります。checksecは、解析の本番そのものではありませんが、最初に守りの地図を確認するためのとても大事な一歩です。