3

Windows システムの「フォーマット文字列の脆弱性」とは正確には何ですか?どのように機能し、どのように防御できますか?

4

2 に答える 2

4

最も単純なフォーマット文字列攻撃は次のとおりです。

char buffer[128];
gets(buffer);
printf(buffer);

そこにもバッファオーバーフローの脆弱性がありますが、要点は次のとおりです。信頼できないデータ(ユーザーから)をprintf、その引数をフォーマット文字列として使用する(またはそのいとこの1つに)渡すことになります。

つまり、ユーザーが「%s」と入力すると、情報開示の脆弱性が発生します。これはprintf、ユーザー入力をフォーマット文字列として扱い、スタック上の次のものを文字列として出力しようとするためです。それはあなたのコードが言ったかのようですprintf("%s");。に他の引数を渡さなかったためprintf、任意の値が表示されます。

ユーザーが「%n」と入力すると、特権の昇格攻撃(少なくともサービス拒否攻撃)が発生する可能性があります。これは、%n形式の文字列によりprintf、これまでに印刷された文字数が次の場所に書き込まれるためです。スタック上。この値を入れる場所を指定しなかったので、任意の場所に書き込みます。

printfこれはすべて悪いことであり、いとこを使用するときに非常に注意する必要がある理由の1つです。

あなたがすべきことはこれです:

printf("%s", buffer);

これは、ユーザーの入力がフォーマット文字列として扱われることは決してないため、その特定の攻撃ベクトルから安全であることを意味します。

Visual C ++では、注釈を使用して、__Format_stringへの引数を検証するように指示できますprintf%nデフォルトでは許可されていません。GCCでは__attribute__(__printf__)、同じことを使用できます。

于 2008-12-30T16:23:12.247 に答える
2

この擬似コードでは、ユーザーは「hello」のように、印刷する文字をいくつか入力します。

string s=getUserInput();
write(s)

それは意図したとおりに機能します。しかし、書き込みは文字列をフォーマットできるため、たとえば

int i=getUnits();
write("%02d units",i);

出力:「03ユニット」。そもそもユーザーが「%02d」と書いた場合はどうでしょうか...スタックにパラメーターがないため、他の何かがフェッチされます。それが何であるか、そしてそれが問題であるかどうかはプログラムに依存します。

簡単な修正は、文字列を出力するようにプログラムに指示することです。

write("%s",s);

または、文字列をフォーマットしようとしない別の方法を使用します。

output(s);

詳細情報が記載されたウィキペディアへのリンク。

于 2008-12-30T16:21:36.260 に答える