コンテンツにスキップ

Format String Vulnerability

フォーマット文字列の脆弱性

概要

フォーマット文字列の脆弱性(Format string vulnerability)は、フォーマットされた出力関数でフォーマット指定子として使用されるユーザー入力を、プログラムが適切に検証またはサニタイズしない場合に発生します。これにより、攻撃者がフォーマット文字列の引数を操作し、任意のコードを実行したり機密情報を漏洩させたりする可能性があります。

フォーマット文字列の脆弱性の影響は甚大であり、以下の事態を招く可能性があります。 1. 情報漏洩: フォーマット文字列の脆弱性を悪用することで、攻撃者はメモリから機密情報を抽出できます。これには、パスワード、暗号化キー、またはその他の重要な情報などの機密データが含まれる場合があります。

  1. リモートコード実行 (RCE): フォーマット文字列の脆弱性を悪用して、システム上で任意のコードをリモートで実行することができます。これにより、攻撃者はシステムの制御を取得し、不正アクセスや機密データの窃取につながる可能性があります。

  2. サービス拒否 (DoS): フォーマット文字列の脆弱性は、攻撃者によって操作され、プログラムをクラッシュさせたり無限ループに陥らせたりする可能性があります。このタイプの攻撃はサービス拒否 (DoS) を引き起こし、正規のユーザーがシステムやアプリケーションにアクセスできなくなります。

// gcc vulnerable.c

#include <stdio.h>
#include <unistd.h>

int main() {
    int secret_num = 0x8badf00d;

    char name[64] = {0};
    read(0, name, 64);
    printf("Hello ");
    printf(name);
    printf("! You'll never get my secret!\n");
    return 0;
}

推奨事項

フォーマット文字列攻撃に関連する脆弱性を軽減するには、以下のプラクティスに従うことが重要です。

  • ユーザー入力を直接受け入れるフォーマット文字列関数の使用を避け、代わりに、ユーザーが制御するフォーマット文字列に依存しない文字列連結やフォーマットされた出力関数などの、より安全な代替手段を使用します。
  • ユーザーから提供されたデータが予期されたフォーマットと一致することを保証するための、堅牢化(ハードニング)対策としての入力検証およびサニタイズ。

コード例:

#include <stdio.h>

int main() {
    int secret_num = 0x8badf00d;

    char name[64] = {0};

    printf("Enter your name: ");
    if (fgets(name, sizeof(name), stdin) != NULL) {
        // Remove the newline character from the input
        size_t len = strlen(name);
        if (len > 0 && name[len - 1] == '\n') {93317
            name[len - 1] = '\0';
        }

        printf("Hello %s! You'll never get my secret!\n", name);
    } else {
        // Handle error reading input
        printf("Error reading input.\n");
        return 1;
    }

    return 0;
}

リンク

標準

  • OWASP_MASVS_L1:
    • MSTG_PLATFORM_2
  • OWASP_MASVS_L2:
    • MSTG_PLATFORM_2
  • OWASP_MASVS_v2_1:
    • MASVS_CODE_4
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_3_4
    • CC_4_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5