【しょしきもじれつこうげき】

書式文字列攻撃 とは?

最終更新:
💡 表示するはずの入力が、書式の指示として解釈される

信頼できない入力をprintfなどの書式文字列として解釈させ、メモリの情報漏えい・書き換えやクラッシュなどを起こす攻撃。起きる結果は実装と実行環境にも依存する。

📌 このページのポイント
入力を「書式」にするか「データ」にするか入力が書式になるprintf(input)入力中の書式を指示として解釈書式を固定するprintf("%s", input)入力中の%xなども文字列として出力外部入力の例:%x左側の結果は、実装や環境によって異なる
同じ外部入力を、左では書式、右では文字列データとして扱う比較です。右は書式文字列の脆弱性への修正例で、入力ポインターの妥当性など他の安全条件を保証するものではありません。
ひよこ ひよこ
書式文字列攻撃って、何が問題なの?
ペンギン先生 ペンギン先生
例えば printf(input) のinputを外部から指定できると、入力に含まれる書式指定が解釈されるよ。本来は表示したいデータなのに、関数への指示として扱われるのが問題。条件によって、情報漏えいやメモリの書き換え、クラッシュなどにつながるんだ
ひよこ ひよこ
%xや%sは何をするの?
ペンギン先生 ペンギン先生
通常のprintfでは、%xは対応する整数を16進数で、%sは対応するポインターが指す文字列を表示するよ。必要な引数を渡さずに入力を書式として解釈させるのは正常な使い方ではない。「%xを並べれば、必ず全ての秘密が読み出せる」という決まった結果ではないんだ
ひよこ ひよこ
%nは何が違うの?
ペンギン先生 ペンギン先生
%nは表示するための指定ではなく、それまでに出力した文字数を、対応するポインターが指す整数へ書き込む指定だよ。信頼できない書式を解釈すると、書き込みにつながる場合がある。ただ入力に%nを含めれば、どの環境でも好きな場所へ好きな値を書けるという意味ではないんだ
ひよこ ひよこ
どう修正するの?
ペンギン先生 ペンギン先生
文字列を表示するなら、例えば printf("%s", input) として書式を固定し、inputをデータの引数にするよ。この場合、入力の中にある%xなどは文字列として出力される。これは書式文字列の問題への修正で、inputが有効な文字列であることなど、他の条件まで自動的に満たすわけではないんだ
ひよこ ひよこ
printfだけを探せばいいの?
ペンギン先生 ペンギン先生
fprintfや、POSIXのsyslogなど、書式を解釈する他の関数も確認しよう。入力から組み立てたメッセージを、後で再び書式として渡す経路にも注意が必要だよ。コンパイラーの警告や静的解析も役立つけれど、見つかる範囲は設定や道具に左右されるんだ
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「書式文字列攻撃」って出てきたら「入力が書式の指示として解釈される脆弱性を狙う攻撃」と思えばだいたいOK!
📖 おまけ:英語の意味
「Format String Attack」 = 書式文字列攻撃
💬 C言語のprintf()などが「書式文字列(format string)」を解釈する仕組みを悪用するため、この名前がついているんだよ。

参考資料

← 用語集にもどる