2012-03-03 2 views
3

は、私はシンプルなCプログラムがあります。それは、これはセキュリティ上の脆弱性を表して私の理解であるフォーマット文字列の脆弱性

char user_input[100]; 
scanf("%s", user_input); 
printf(user_input); 

を。例えば%xの束を入力するとスタックの内容が表示されます。

しかし、どのように選択したメモリの場所を印刷できますか?

私がいることを読ん

\x10\x01\x48\x08_%08x.%08x.%08x.%08x.%08x|%s| 

this paperから場所0x08480110のメモリの内容をダンプするべきです。しかし代わりに、次の4バイトをスタック上のフォーマット文字列に出力しています。私はなぜそれを理解しようとしています。

+6

これは木の森であり、バッファオーバーフローを呼び出すために99文字以上を入力します。リトル・ボビー・テーブルの話は、サニタイズ入力ではない。 –

答えて

1

フォーマット文字列自体は、(ローカル変数としてuser_inputを宣言したように)スタック上にあります。だから十分にスタックを歩いている場合(これは force printf)、最終的に書式文字列の先頭に到着します。 %sprintfにスタックからアドレスを読み取り、その場所で見つかった文字列を出力するように指示します。したがって、フォーマット文字列の最初の4/8バイトを読み取り、それらをアドレスとして使用します。

もちろん、これが機能するためには、書式文字列をヒットするためにスタックをどのくらい読みとるべきかを正確に知る必要があります。したがって、%08xの数を調整する必要があります。これはあなたの場合はExploiting Format String Vulnerabilities.

に非常に詳細に説明されて

+0

フォーマット文字列は、user_inputよりもメモリ内で低くなっていませんか?また、%xは "スタックを歩く"ことを理解しています。スタックの内容全体を表示しない方法があります。つまり、最初の4バイトをフォーマット文字列に移動する方法ですアドレスはスタックから読み込む必要がありますが、その間にすべてを印刷することはありませんか? –

+0

@Pi_:それは異なります。 x86では、スタックは通常下向きに成長します( 'printf'のスタックフレームは呼び出し元のスタックフレームよりも低いアドレスになります)。 –

+0

注:nが整数である入力 "%n $ x"は、結果を出力せずに最初のn-1回の繰り返しを行っていることがわかりました(つまり、n-1回の繰り返しをポップしていて、 ) –

0

また

、実行時に\x10を入力するユーザーが\x10が含まれているソースコードに文字列リテラルと同じではありません...画像が必要な場合は、lecture notesのセクション4.4を参照してください。