インジェクション攻撃 (インジェクションこうげき、英 : Injection attack、または Code injection )とは、コンピュータ プログラム が無効なデータを処理した場合に出現するバグ を、攻撃者が悪用し不正な命令を実行する攻撃手法である。攻撃者は脆弱性 のあるプログラム にソースコード を注入(インジェクト)し、実行過程に変更を加える[1] [2] [3] 。インジェクション攻撃が成功した場合、例えばワーム の増殖のような、深刻な被害を受けることがある。
概要
コードインジェクション脆弱性(インジェクションフロー)は、アプリケーションがインタプリタ へ信頼できないデータを送信する場合に生じる。SQL 、 LDAP 、XPath 、NoSQL の問い合わせ、 オペレーティングシステム (OS) のコマンド 、XML の構文解析 、SMTP ヘッダ、プログラム 引数 などで最も頻繁に見られる。インジェクションフローはソフトウェアテスト よりもソースコード診断 [訳語疑問点 ] の工程で見つけやすい傾向にある[4] 。脆弱性検査ツール やファジング が脆弱性発見に役立つこともある[5] 。
インジェクション攻撃により、データの損失や改変、責任追跡性 の欠如、DoS攻撃 などが生じる。時にホストの完全な乗っ取りが起こることもある。
特定の種類のインジェクション攻撃では、単なるユーザ入力に特別な意味を付与してしまい、入力データの解釈に失敗する。このような解釈ミスはWho's on First? (英語版 ) のコメディーのように情報科学の世界以外でも見られる。Who's on First? では、固有名詞と一般名詞を区別することに失敗する。同様に、ある種のインジェクション攻撃では、ユーザ入力とシステム命令の区別に失敗する。
インジェクション攻撃の技術は、情報取得のためのハッキング (クラッキング )や特権昇格攻撃 (英語版 ) 、システムへの不正アクセスにおいて広く用いられている。
インジェクション攻撃は悪意を伴う多くの目的に用いられ、次のような例が挙げられる。
2008年に報告された全ての脆弱性のうち5.66%がインジェクション攻撃に分類されており、記録上最も大きい割合であった。2015年にはこの割合は0.77%へと減少した[6] 。
有益または非意図的な利用
コードインジェクションは健全な目的にも用いられる。例えば、コードインジェクションによりプログラムやシステムの動作を変更したり微調整したりすることで、悪意のない特定の動作をするようにシステムを「だます」ことができる[7] [8] 。
具体例として
検索結果ページにおいて本来の設計には出てこない有用な新規カラムを導入する。
本来の設計の標準機能において公開されていないデータフィールドを用いて、データのフィルタリング・並べ替え・分類の新しい方法を提供する。
Dropbox などのプログラムのように、オフラインプログラムにおいてネットワーク上のリソースにアクセスできる特別な機能を追加する。
Linux の動的リンカを用いて、特定のlibc 関数と同名の関数を定義し、ライブラリとして関数をリンクし、既存のlibc関数を上書きする。
といったことが挙げられる[要出典 ] 。
プログラムへの入力がシステム開発者の想定外であるために、ユーザが疑いなくコードインジェクションを行ってしまうことがある。
次のような具体例が挙げられる。
ユーザが有効だとみなした入力に、特別な意味を持つトークン文字や予約語 が含まれるかもしれない (「Shannon & Jason」の「&」や「Bub 'Slugger' McCracken」の引用符があるいはこれに該当するかもしれない)
あるアプリケーションではうまく処理されるが、送信先のシステムには有害であるような、誤った形式の入力ファイルを送信するかもしれない。
別の有益な利用法としては、脆弱性を修正する目的でのコードインジェクション脆弱性の発見が挙げられるだろう。
このような手法はホワイトハット ペネトレーションテスト として知られる。
問題の予防
インジェクション攻撃を防ぐために、以下に挙げるような安全な入出力処理をする必要がある。
適切に利用すれば任意の文字入力に対してセキュアであるようなAPIを用いる。パラメータ化クエリ(コンパイル済みクエリ、プリペアドステートメント、バインド変数などとも)を用いてユーザデータが解釈実行されることを防ぐことができる。加えてクライテリアAPI[9] や類似のAPIを用いることでコマンド文字列を生成・解釈実行するという考え方から解放される。
型システム により言語間の分離を強制する[要出典 ] 。
既知の適切な値のみをホワイトリスト 化するなどの入力バリデーションを行う。
危険な文字をエスケープするなど、入力のエンコーディングを行う。例えば、PHPでは、htmlspecialchars()
関数によりHTMLにおけるテキスト中の特別な文字を安全な出力にエスケープしたり、mysqli::real_escape_string()
関数によりSQLリクエストに含まれるであろうデータを分離しSQLインジェクションを防いだりする。
出力をエンコーディングし、ウェブサイトの訪問者へのクロスサイトスクリプティング (XSS)攻撃を防ぐ。
HttpOnly
フラグを立てるとクライアントサイドのスクリプトはHTTP cookie の情報にアクセスできなくなり、ある種のXSS攻撃を防ぐことができる[10] 。
シェルのモジュールをカーネル から分離する。
SQLインジェクションについては、パラメータ化クエリ、ストアドプロシージャ、ホワイトリスト入力バリデーションなどにより、コードインジェクションの問題を緩和することができる[11] 。
上述の解決策は主にウェブのHTMLやスクリプトからサーバサイドアプリケーションへのコードインジェクションについてのものである。
しかし、権限昇格攻撃を引き起こすような、計算機上におけるユーザのコードによるインジェクション攻撃を取り扱うには、別のアプローチが必要である。
管理されたあるいは管理されていない [訳語疑問点 ] インジェクション攻撃を検知・隔離するためのアプローチには次のようなものがある。
ランタイムイメージのハッシュ検査 - メモリに読み込まれた実行可能イメージの全部または一部のハッシュを生成し、予め記憶済みの期待されるハッシュ値と比較する。
NXビット - 全てのユーザデータを実行ができないようにした特別な記憶領域に保存する。プロセッサにその領域には一切のコードが存在しないことを伝達し、その領域内のあらゆるデータの実行を拒否させる。
カナリア (英語版 ) - スタックにランダムに値を配置する。実行時、関数が値を返す際にカナリアの値が確認される。カナリアに変更が加えられれば、そのプログラムは実行を停止・終了する。これはスタックオーバーフロー 時などに生じる。
(C言語 における) Code Pointer Masking (CPM) - (変更が加えられる可能性のある)コードへのポインタをレジスタに読み込んだ後に、ポインタにマスク をすることで、ポインタが指し示すアドレスを効果的に隠すことが出来る[12] 。
出典
関連項目
外部リンク