San Antonio API Security Summit 2025 に参加しよう!
San Antonio API Security Summit 2025 に参加しよう!
San Antonio API Security Summit 2025 に参加しよう!
San Antonio API Security Summit 2025 に参加しよう!
San Antonio API Security Summit 2025 に参加しよう!
San Antonio API Security Summit 2025 に参加しよう!
閉じる
プライバシー設定
ウェブサイト運営に必要なCookieや類似技術を使用しています。追加のCookieは貴社の同意がある場合のみ利用されます。同意は「Agree」をクリックすることでいただけます。どのデータが収集され、どのようにパートナーと共有されているかの詳細は、Cookieポリシープライバシーポリシーをご確認ください。
Cookieは、貴社デバイスの特性や、IPアドレス、閲覧履歴、位置情報、固有識別子などの特定の個人情報を取得、解析、保存するために使用されます。これらのデータは様々な目的で利用されます。分析Cookieによりパフォーマンスを評価し、オンライン体験やキャンペーンの効果向上に役立てます。パーソナライズCookieは、利用状況に応じた情報やサポートを通じ、貴社専用の体験を提供します。広告Cookieは、第三者が貴社のデータをもとにオーディエンスリストを作成し、ソーシャルメディアやネット上でのターゲット広告に使用します。貴社は各ページ下部のリンクから、いつでも同意の許可、拒否、または撤回が可能です。
ご送信ありがとうございます。内容を受け付けました。
申し訳ありません。フォーム送信時にエラーが発生しました。
/
/
Vulnerabilities

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

コード内で変数を使った文字列の置換を定期的に行っている場合もあるでしょう。文字列挿入の機能を理解するだけでなく、その脆弱性の事例や可能性も把握することが大切です。

例えば、Cプログラムやその他多くの言語では、フォーマット文字列攻撃によってプログラムが応答しなくなることがあります。本記事では、フォーマット文字列脆弱性の仕組みや対策方法について解説します。

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

フォーマット文字列脆弱性とは? 

主にC言語のプログラムで見られる、この脆弱性はprintf()関数に存在するバグを指します。printf()は、ASCIIテキストなどのデータを標準出力へ送るためによく用いられます。正しく使えば効果的な自動変換が可能ですが、設定ミスがあると問題が発生します。

printf()に与えられた入力データがソフトウェア上でコマンドとして解釈または実行されると、フォーマット文字列攻撃が発生します。その結果、攻撃者は入力文字列に悪意あるコードを挿入したり、スタック領域に不正アクセスするなどして、一時的または恒久的な実行障害を引き起こす恐れがあります。

攻撃の深刻度により、システムの異常な動作や停止が起こる可能性があります。特に、print()関数で%dや%sを誤って使用すると、攻撃が成功しやすくなります。

この脅威の影響を受けやすいprintf系の関数には、fprintf、vsprintf、vsnprintf、sprint、vfprintfなどがあります。

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

以下にサンプルコードを示します。

#include <stdio.h>
int main(int arg1, char **arg2){
printf(arg2[1]);
}

このコードでは攻撃者が任意のフォーマット指定子を挿入する仕組みがありません。この問題を回避するため、安全な方法としてprintf文を次のように書き換えるとよいでしょう。

printf("%s", arg2[1]);

ここではフォーマット指定子 %s が使用されているため、攻撃の余地がありません。

歴史的背景

Tymm Twillman氏は1999年9月、入力文字列のフォーマットに潜む可能性に初めて気付いた人物です。当時、C言語で作られたサーバであるProFTPDのセキュリティ監査に従事していた際、正確な文字列が指定されていないprintf()関数を発見し、ユーザー生成のデータがサーバへ送信される事象に気付いたのです。

事例をより正確に把握するため、利用可能な全てのprint系関数を徹底的にテストし、その結果、文字列に関する抜け穴が複数の脅威につながると結論付けました。これにより、攻撃者は特権やroot権限を得たり、システムの不具合を引き起こす恐れがあります。

被害の内容

長時間放置されると、既存の文字列フォーマットに関するセキュリティ抜け穴が多くの脅威を生む可能性があります。例えば、

  • 予期しないコードのクラッシュ
  • スタックデータへの不正アクセス
  • アプリに対する任意のコード実行
  • DoS(サービス拒否攻撃)の成功

各種プログラムにおけるフォーマット文字列脆弱性

Cで書かれたコード

C言語では出力時に様々な種類の引数を受け入れますが、ユーザ制御のプログラムが意図的または偶発的な入力を受けると脆弱性が発生することがあります。

C言語のフォーマット文字列は非常に一般的で、フォーマット指定子が欠如すると、ハッカーがその特性を利用して出力を操る危険性があります。

例えば、次のコードを考えてみてください。

printf("%x%x%x%x");

この場合、テキストはなく、複数のフォーマット指定子のみが存在します。

関数が実行されると、最初のスタックとそれに対応する変数のみが考慮され、残りの%x指定子は順次処理されます。

Webアプリ

C言語のモジュールを含むWebアプリは、本攻撃に対して脆弱です。大部分のWebサーバがCまたはC++で構築されているため、脆弱なコードがWebアプリに流入しやすい状況です。

Javascriptコードにおけるフォーマット文字列も、問題となる場合があります。

さらに、sprintfを利用するPHPアプリでは、熟練したハッカーによりsprintfのフォーマット文字列脆弱性が悪用される可能性があります。この抜け穴は、過去にSQLインジェクション攻撃にも利用されました。

Pythonアプリ

この攻撃はCやC++だけに限らず、Pythonにおけるフォーマット文字列も非常に一般的です。実際、調査記事ではPythonがCやC++よりも脆弱であることが示されています。特に、すべてのPython文字列がformat()メソッドを持つ点は注目に値します。

例えば、次のようなコードを考えてみてください: print("Directory {} contains {} files".format("Office", 32))

この例では、各{}がformat()メソッドの隣接する引数で置き換えられます。しかし、format()はオブジェクトを受け取り、その属性を利用して文字列整形を行う可能性もあります。ここではDirDataクラスを用い、同一モジュール内に秘密の値を保持するグローバル変数が存在すると仮定します。

SECRET_VALUE = "getintosystem"
class DirData:
    def __init__(self):
        self.name = "Office"
        self.noOfFiles = 32
print("Directory {dirInfo.name} contains {dirInfo.noOfFiles} files".
format(dirInfo=DirData()))

この場合、Pythonオブジェクトは内部属性にアクセス可能となります。これらの属性を連結すると、次のような出力が得られる可能性があります。

秘密は: getintosystem

フォーマット文字列攻撃への対策

安全で安心なソフトウェア開発のためには、いかなる脆弱性も見逃してはなりません。早期に対策を講じるため、次のポイントに留意してください。

  • 文字列を入力として定義せず、常にプログラムの一部として組み込むようにする。
  • 定数文字列を用い、変数部分は早めに抽出する。
  • Format_Guard.Rareは、glibcの全パッチを修正し各種フォーマットバグから守る優れた対策ツールです。設計段階での導入を推奨します。
  • printfを正しく使用することで、脆弱性が問題を引き起こすことはありません。
  • 有名なバイナリ書き換えソリューションであるKimchiを利用する。これは実行時の文字列フォーマットの抜け穴を防止し、printfの呼び出しを安全なsafe_printfに置換します。
  • 関数、ライブラリ、変数などの重要要素に対しては、ASLR(アドレス空間配置のランダム化)を用いて動的アドレスを生成する。動的アドレスは改ざんが難しく、攻撃の可能性を低減します。
  • コンパイラの警告を決して無視せず、脆弱な関数が検出された場合は速やかに安全なバージョンに置き換えることが重要です。

締めの言葉

関数文字列はCやその他主要なプログラミング言語に欠かせない要素であり、そのエラーや脆弱性は大きな運用障害を引き起こす恐れがあります。このため、脆弱性の可能性や対策方法についての知識を深め、被害の最小化に努めるべきです。

FAQ

参考資料

最新情報を購読

更新日:
February 25, 2025
学習目標
最新情報を購読
購読
関連トピック