1

このコードが保護されていないのはなぜですか?

#include <stdio.h>
int main( int argc, char *argv[] )
    {
       printf(argv[1]);
       printf("\n");
       return 0;
    }
4

5 に答える 5

5

printf%dとのようなものを探して、最初のパラメータを処理します%s

それらの値に基づいて、スタックからより多くのデータを取得し、それを出力します。

したがって、誰かがあなたのプログラムを呼び出した場合:

a.out "%d %d %d %d %d %d %d %d %d %d %d %d"

彼らはあなたのコンピュータのコールスタックのセクションを見ることができました。

フォーマット指定子を使用してさらにクリエイティブになれば、クレジットカード番号やパスワードなどの重要なものをダンプできる可能性があります。

于 2012-04-09T21:15:33.270 に答える
4

コントロールの最初の引数が何であるかを検討してくださいprintf(ヒント:printf入力引数を読み取るだけではありません)。

于 2012-04-09T21:13:04.323 に答える
4

フォーマット文字列の脆弱性とは何かを見てください。

http://en.wikipedia.org/wiki/Unmanaged_format_string

于 2012-04-09T21:14:07.330 に答える
1

ここで説明を見つけることができます。 https://www.owasp.org/index.php/Testing_for_Format_String

于 2012-04-09T21:16:13.263 に答える
1

ポスターが例を求めたので、何をしますか%n

printfフォーマット文字列がメモリを変更する方法は、%nオプションを使用することです。書き込まれる特定の値は、フォーマット幅指定子を「賢く」使用することによって取得できます。テストとして:

#include <stdio.h>

int main(int argc, char **argv)
{
    int *q = (int *)argv[0];
    printf("%1$300000d%5$n",
        123,         // %1 - 1st param (formatted as '300000d')
        0,           // %2 - 2nd param (unused)
        0,           // %3 - 3rd param (unused)
        0,           // %4 - 4th param (unused)
        argv[0]);    // %5 - 5th param (written to via 'n')

    printf("\nNow *q == %d\n", *q);

    return 0;
}

これを実行して出力の最後の行を見ると、印刷されますNow *q == 300000(Linuxでテスト済み)。

ここでは、「興味のない」ものを使用せずに、引数をスキップして変更する引数を選択する方法を示すために、あまり知られていない位置形式の構文%<pos> $<fmt>)を使用しています。printf()

printf()のような呼び出しの「引数」として何が扱われるかを理解するために、読者の実験に任せますprintf(argv[1])。その答えは、呼び出し規約(または関連するシステムのABI)によって異なり、32/64ビットのWindows / Linux/MacOSXなどでは異なります。

于 2012-04-12T10:43:29.987 に答える