sprintfを用いたフォーマット文字列攻撃に関する質問です。
main文の中で
---------------------
int main(void){
char str[50];
sprintf(str,"%s");
puts(str);
}
---------------------
を実行すると(null)で帰ってきます。
しかし関数呼び出しを行うと結果が変わってきます。
---------------------
void f(){
char str[50];
sprintf(str,"%s");
puts(str);
}
int main(void){
f();
}
---------------------
これを実行すると" ・L "のような文字化けしたものに変わりました。
sprintf(str,"%s%s");と記述することによって" ・L (null) "と、本来呼び出される箇所のものが格納されています。
なぜ関数呼び出しにすると変なところを参照してしまうのか(第3引数があると勘違いしてしまうのか)教えてください。
また、これによりどのような悪影響があるのか教えてください。
自分はプログラマが意図しない箇所を参照するため攻撃者のプログラムアドレスを格納してしまう恐れがあると考えています。
No.1ベストアンサー
- 回答日時:
>なぜ関数呼び出しにすると変なところを参照してしまうのか(第3引数があると勘違いしてしまうのか)教えてください。
勘違いなどしていません。
sprintfのフォーマット指定"%s"で第3引数があり、それは文字列へのポインタと書いてあります。
同様にsprintfのフォーマット指定"%s%s"は第3引数,第4引数があり、それは文字列へのポインタということになります。
C,C++で可変長引数はどのようにして実装するのか調べてみてください。
>自分はプログラマが意図しない箇所を参照するため攻撃者のプログラムアドレスを格納してしまう恐れがあると考えています。
フォーマットをユーザーに入力させたりするなら、その可能性はあります。
ですが通常そのようなケースはないのではないでしょうか。
この回答への補足
回答ありがとうございます。
char str[50];
sprintf(str,"%s");
puts(str);
上記のプログラムをmain文内で実行したところ、第3引数の%sは(null)になったのに、関数に記述すると第3引数に文字化けしたものが入るのか理由がわかりません。
同じ処理の流れだと思うのですが、なぜ%sに格納される内容が変わるのか教えていただけないでしょうか。
>フォーマットをユーザーに入力させたりするなら、その可能性はあります。
>ですが通常そのようなケースはないのではないでしょうか。
確かにそうですね。
これは現実的ではないですよね。
ありがとうございます。
No.6
- 回答日時:
関数呼出しだから内容が変わったわけではありません。
strには何も書き込まれていないので、
コンパイルされた時点でchar str[50]で確保されたメモリに存在したデータが見えているだけしょう。
sprintf( str, "%s" );では、strに何も書き込まれていません。
sprintf( str, "%s", "ABC" ); とか
sprintf( str, "%s%s", "ABC", "XYZ");
とすることでstrにABCやABCXYZの文字列が書き込まれます。
No.5
- 回答日時:
>同じ処理の流れだと思うのですが、なぜ%sに格納される内容が変わるのか教えていただけないでしょうか。
未定義動作だしたまたまそうなっただけです。
前にも書きましたけど可変長引数の関数をどうやってつくるのか調べてみてください。
No.4
- 回答日時:
この質問は、残念ながら”コンパイラの実装依存”であるため、誰も回答できません。
まず、int sprintf(char *str, const char *format, ...) は、
format に渡されたフォーマット文字列から、可変個の引数を読みに行こうとします。
ですので、
sprintf(str, "%s"); と書けば引数を2つしか渡さなくても3番目の引数の値を読みに行き、
sprintf(str, "%s%s"); なら3番目と4番目の引数を読みに行くわけです。
(質問に”第3引数があると勘違いしてしまうのか”とありますが、そうではなく、
sprintf(str, "%s") は、必ず第3引数を読みにいくと考えてください。)
この渡されなかった”3番目の引数がどのように読みだされるのか?”
について、一般的なことは、誰にも回答できません。
大抵は、コンパイラや sprintf(str, "%s"); の前にあるコード群と
そのコードの実行結果によって、様々に変わってしまうと思います。
ですので、質問にあるどちらの結果も”たまたまそうなった”に過ぎず、
・少しコードを変えたら結果も変わった。
・コンパイルオプションを変更したら結果が変わった。
・他のコンパイラでコンパイルしたら結果が変わった。
だとしても、全く不思議ではないです。
もし、あなたがアセンブラを読めるなら、どのように引数が渡され、sprintf 側で
どのように読みこまれたか調査することは可能でしょう。
でも、それもあなたが使用したコンパイラがたまたまそのように実装していたという
話に過ぎません。
No.2
- 回答日時:
#1にもありますが「可変長引数 C言語 実装」で検索するとか、上級者向けの参考書を読むとかして、どんなカラクリになっているか、調べてください。
結果が違うのは「たまたま」です。
例えば、次のものは、また違った結果になるのではないでしょうか。
#include <stdio.h>
int main(void){
char *a= "A";
char str[50];
char *b= "B";
sprintf(str,"%s");
puts(str);
return 0;
}
また、どのコンパイラを使っているかわかりませんが、Release/Debugビルド、最適化オプション等でも変わる可能性があります
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コンパイルできない
-
0除算して、落ちるプログラムと...
-
io.hをincludeするとそのような...
-
C++ で、「)」が必要 というエ...
-
コンパイルの意味
-
ccコマンドの使い方
-
Delphiの逆コンパイル
-
コンパイラの制限 : ヒープの領...
-
【エラー】Cpadで初めてコンパイル
-
volatile修飾について
-
対応Cコンパイラについて [C/OC...
-
Windows環境でgnu系コンパイラ...
-
C言語が学べるフリーソフト
-
fortranでのNaNについて
-
COBOLのEVALUATE文について
-
Visual C++とVisual C++.NETの違い
-
ブラウザ上でクライアント側で...
-
コンパイラフラグ(compiler fla...
-
cobolの文法チェックソフト
-
LL(n)構文解析機での高速化手法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
0除算して、落ちるプログラムと...
-
C++ で、「)」が必要 というエ...
-
コンパイルできない
-
C++でアボート(Abort)で処理が...
-
io.hをincludeするとそのような...
-
__extension__
-
初心者はIDE使わないほうが良く...
-
ABAQUS ユーザーサブルーチン...
-
Delphiの逆コンパイル
-
コンパイラの制限 : ヒープの領...
-
Eclipseの環境設定について
-
fortranでのNaNについて
-
cobolの文法チェックソフト
-
変数(関数)名の頭に_
-
graph.hがincludeできない
-
PICマイコンによる乱数の表示に...
-
どのプログラミング言語ででき...
-
Visual C++とVisual C++.NETの違い
-
コンパイラフラグ(compiler fla...
-
ccコマンドの使い方
おすすめ情報