1. ホーム
  2. c

[解決済み] sprintf関数のバッファオーバーフロー?

2022-02-18 07:26:59

質問

{     
    char buf[8];
    sprintf(buf,"AAAA%3s","XXXXXXXX");
    printf("%s\n",buf);
}

どうなるんだろう?

バッファには8文字の空き領域があり、残り3文字しかありませんが、"XXXXXXXX"は8文字です。

Windows7にVisual Studion 2008をインストールしてテストしています。その結果、AAAXXXXXXXと表示され、ランタイムエラーが発生しました。

解決方法を教えてください。

あなたの、そしてもっと重要なことに、似たようなケースで何が起こるかを考えることは、とても意味のあることです。他の投稿者が指摘しているように、それはUBを呼び起こすものです。それはおそらく事実でしょう。しかし、誰かが次に起こるべきことを正確に定義しなかったからといって、世界が止まることはないのです。そして、何が 物理的に が起こるかもしれません。 メジャーセキュリティホール .

もしあなたの文字列が XXX... が制御不能なソースから来る場合、バッファオーバーフローの脆弱性が発生する可能性が非常に高くなります。

(1) スタックは通常、quot;grows" 逆方向、つまりアドレスが小さいほどスタックは埋まっていきます。

(2) 文字列は、その文字列に属する文字が格納されることを想定しているので、文字n+1が格納されるように 文字n

(3) 関数を呼び出すと、リターンアドレス、つまり関数が戻った後に実行される命令のアドレスがスタックにプッシュされる(とりわけ、典型的な)。

ここで、関数のスタックフレームを考えてみましょう。

|----------------|
| buf [size 8]   |
|----------------|
| (func args)    |
|----------------|
| (other stuff)  |
|----------------|
| return address |
|----------------|

との間のオフセットを正確に把握することで buf とスタック上のリターンアドレスが一致するように、悪意のあるユーザがアプリケーションへの入力を操作する可能性があります。 XXX... 文字列には、攻撃者が選んだアドレスが含まれており、ちょうど制御されていない sprintf 関数はスタック上のリターンアドレスを上書きします。(注意: より良いのは snprintf があれば、それを使用します)。これによって、攻撃者は バッファオーバーフロー の攻撃を受けます。彼は、以下のようなものを使うかもしれません。 NOPソリテクニック を起動させることができます。 シェル を使用します。特権ユーザアカウントで実行されるアプリケーションを書いていたなら、攻撃者に、顧客のシステムへの第一級の侵入手段である エース の穴とでも言うべきでしょうか。

更新情報

あなたが経験したランタイムエラーは、リターンアドレスが上書きされたことが原因である可能性が高いです。このアドレスは基本的に文字列で埋められているため、CPUがジャンプした先には、プログラムテキストとして解釈すると不正なメモリアクセスを引き起こすバイト列が含まれていた可能性があります(あるいは、アドレス自体が既に不正だった可能性もあります)。

この種のエラーに対して、いくつかのコンパイラは有効であることに留意すべきです。たとえば、GCCは -fstack-protector . それらの機能がどの程度優れているかはよく知らないが。