保護機構をやさしく理解するシリーズ。保護機構から逆算する攻撃方針の立て方(最終回/全10回)
ここまでの保護機構シリーズでは、現代のバイナリを守る代表的な仕組みを順番に学んできました。
・NXは、データ置き場でそのまま命令を動かしにくくする
・Stack Canaryは、return address の前で異常を見つけやすくする
・ASLRは、場所の予測を難しくする
・PIEは、プログラム本体の位置も固定で考えにくくする
・RELROは、大事な表を守る
・checksecは、その守りの全体像を見る入口になる
ここまで来ると、最後に大切になるのが「では、これらの守りを見て、どう考えを組み立てるのか」という視点です。
初心者のうちは、ついCanaryがある、NXもある、PIEもある、もう何もできなさそう。
あるいは逆に、Canaryがない、なら簡単そうというふうに、1つの情報だけで全部を判断したくなります。
ですが本当に大切なのは、保護機構を見て、“どんな難しさがあり、何を先に整理すべきか”を逆算することです。
今回は、悪用の具体手順ではなく、守りを見て解析方針を立てるための、論理的な見方をやさしく整理していきます。
※イメージです。
「逆算する」とは何か
まず、「保護機構から逆算する」とはどういうことでしょうか。
これは簡単に言えば、やりたいことから考えるのではなく、先に“何ができないようにされているか”を見ることです。
たとえば、何かの問題を解くときに、いきなり答えを決め打ちするよりも、
・何が条件か。
・何が禁止されているか。
・どこに制限があるか。
を見たほうが、考えやすいですよね。
バイナリ解析でも同じです。
まず見るべきなのは、
・このバイナリは何を難しくしているのか。
・どこに壁があるのか。
・どんな種類の壁が重なっているのか。
です。
つまり「逆算する」とは、
1.保護機構を見る。
2.その保護機構が何を難しくしているか整理する。
3.その結果、どんな確認が必要か考える。
という流れです。
[fuki-l]簡単にたとえるなら、これは迷路のゴールへ向かう前に、「どこが行き止まりか」を先に見るようなものです。[/fuki-l]
行きたい方向だけを見るのではなく、「通れない道を先に知る。」
それが「逆算する」という考え方です。
まず「何を難しくしているか」を見る
保護機構を見たとき、最初にやるべきことは、名前を見ることではなく、その守りが何を難しくしているかを考えることです。
たとえば、これまで学んだ内容を整理すると、こうなります。
「NXがある」
その場で実行することが難しい。
「Canaryがある」
return address の手前まで届くような大きな破壊が見つかりやすい。
「ASLRがある」
スタックやライブラリなどの場所を固定で考えにくい。
「PIEがある」
プログラム本体の関数位置も固定で考えにくい。
「RELROがFull」
大事な表の書き換えがより難しい。
つまり、保護機構を見るとは、「禁止されている行動」を一覧にすることに近いです。
ここで大事なのは、「NX があるから終わり」「Canary がないから全部簡単」のように単純化しすぎないことです。
本当に見るべきなのは、「何が難しいのか、どこがまだ見えていないのか」です。
この見方ができるようになると、保護機構はただの用語集ではなく、考えるためのヒント集になります。
checksecの結果から考える順番
ここで、checksec の結果を見たときに、どんな順番で考えると整理しやすいかをまとめます。
1.Canaryはあるか
まず、スタック上の大きな破壊が見つかりやすいかを考えます。
これがあると、return address の近くまで届くような異常は気づかれやすい、という見方ができます。
2.NXはあるか
次に、書けることと実行できることを分けて考えます。
NX があるなら、データ置き場をそのまま実行場所として見る考え方は通りにくくなります。
3.PIEはあるか
次に、プログラム本体の関数位置を固定で見てよいのかを考えます。
PIE があるなら、本体も固定地図としては見にくくなります。
4.ASLRの影響を考える
さらに、スタックやライブラリなどの位置が毎回変わりやすいかを考えます。
前回の実行結果をそのまま当てにしにくいかどうかを見るわけです。
5.RELROはどこまで強いか
最後に、大事な表の守り方が Partial か Full かを見ます。
表の書き換えに関する壁の強さをここで整理します。
この順番で見ると、「このバイナリは何をしにくくしているのか」が頭の中で並びやすくなります。
[fuki-l]簡単にたとえるなら、これは「試験問題を見る前に、持ち込み禁止・時間制限・使用できる道具を確認する」のに似ています。[/fuki-l]
先に条件を見ると、考え方がぶれにくくなります。
サンプルの読み方をやさしく整理する
ここで、checksecの結果を例として、どう整理するかを見てみます。
たとえば、次のような結果があったとします。
—–
RELRO: Full RELRO
Canary: Yes
NX: Enabled
PIE: Enabled
—–
この表示を見て、初心者はまず「守りがいっぱいある」と思うはずです。
それで大丈夫です。
次に、その守りを日本語に言い換えていきます。
・Full RELRO
大事な表はかなりしっかり守られている。
・Canary: Yes
スタックの大事な戻り情報の手前に見張りがいる。
・NX: Enabled
データ置き場をそのまま実行しにくい。
・PIE: Enabled
プログラム本体の位置も固定で考えにくい。
ここまで整理すると、次のように考えられます。
このバイナリは、
・スタックの大きな破壊を見つけやすくしている。
・その場実行をしにくくしている。
・本体位置を固定で見にくくしている。
・大事な表も強く守っている。
つまり、「何となく進める」やり方は通りにくいということです。
ここで大切なのは、「では具体的に何をするか」ではなく、「何を前提にできないか」を整理できることです。
それが、保護機構から逆算する第一歩です。
初心者がやりがちなミスと、正しい考え方
ここで、初心者がやりがちなミスを整理しておきます。
1つの項目だけで全部を判断する
たとえば、
・Canaryがない → すごく簡単そう
・NXがある → もう無理そう
という考え方です。
でも実際は、他の保護機構も重なっています。
1つだけで全体は決まりません。
2.名前を覚えて満足する
NX、Canary、PIE という単語だけ覚えても、何を難しくしているかがわからないと実際のバイナリを見たときに使えません。
3.すぐ手順を探そうとする
大切なのは、最初から「やり方」を探すことではなく、どんな壁があるかを先に知ることです。
では、正しい考え方は何でしょうか。
それは、
1.守りを確認する。
2.何が難しくなっているかを言葉で整理する。
3.固定で考えてよいものと、固定で考えられないものを分ける。
4.全体を見て「どんな難しさの組み合わせか」を理解する。
という流れです。
[fuki-l]簡単にたとえるなら、これは「いきなり正解を当てにいくのではなく、問題文の条件を丁寧に読む」のと同じです。[/fuki-l]
保護機構を読む力は、まさにその「条件整理の力」なのです。
保護機構をやさしく理解するシリーズ。checksecの見方:最初に見るべき防御情報とは何かのまとめ
今回学んだ大事なことは、保護機構から逆算するとは、まず「このバイナリは何を難しくしているのか」を先に整理することだという点です。
NX、Canary、ASLR、PIE、RELRO は、それぞれ別の壁として働いており、1つの項目だけで全体を判断してはいけません。大切なのは、checksec などで守りを確認し、そのあとに「その場で実行しにくいのか」「場所を固定で考えにくいのか」「大事な表が守られているのか」といった難しさを言葉で整理することです。
つまり、保護機構を見るとは、解き方を決める前に条件を読むことに近いです。名前を覚えるだけでなく、「何ができなくされているのか」を順番に考えられるようになることが、現代のバイナリを理解するための大切な力になります。
これで、「保護機構をやさしく理解するシリーズ」全10回が、終了しました。
ありかとうございました。