【活用ガイド】

CWE-78

Weakness ID:78(Weakness Base)

Status: Draft

OSコマンドインジェクション

解説

解説要約

上位コンポーネントによる外部からの影響がある入力を使用したOS コマンドの全部、もしくは一部を構築するソフトウェアにおいて、意図する OS コマンドの改ざん可能な要素を適切に無効化せずに下位コンポーネントに送信する際に発生する脆弱性です。

詳細な解説

本脆弱性は、Web アプリケーションの様な、攻撃者がOSに直接アクセス権を持たない環境で発生し、攻撃者により直接OS に対して予期しない危険なコマンドを実行される可能性があります。本脆弱性が特権を持つプログラム上で発生した場合、攻撃者が通常はアクセスできないコマンドを指定する、または攻撃者が持たない権限を持つ別のコマンドを呼び出す可能性があります。このコマンドは、被害の深刻化を招くシステム特権で実行されるため、攻撃を受けたプロセスが最小特権の原則を遵守しない場合、本脆弱性は更に深刻なものとなります。

OS コマンドインジェクションには少なくとも二種類が存在します。

1) アプリケーションが特定の自己制御プログラムを実行し、引数として外部入力を使用する場合。例えば、プログラムはシステム関数 ("nslookup [HOSTNAME]") を使用して nslookup を実行し、引数として使用されるHOSTNAME に対してユーザからの入力を許可しています。攻撃者は nslookup の実行を妨害することはできませんが、プログラムがコマンドセパレータを HOSTNAME から削除しなかった場合、 HOSTNAME 引数に任意のプログラムを実行させるセパレータを入力し、nslookup の終了後に実行することが可能です。

2) 外部入力により実行するプログラムやコマンドを選択し、OS に全コマンドをリダイレクトするアプリケーションの場合。
例えば、ユーザから入力された [COMMAND] を "exec 関数 ([COMMAND])" を用いて実行するプログラムにおいて、COMMAND が攻撃者の制御下にある場合、攻撃者は任意のコマンドやプログラムを実行することが可能です。コマンドが exec() や CreateProcess() のような関数で実行されている場合には、同じ行に複数のコマンドを記述できない可能性があります。

上記二種類の OS コマンドインジェクションには、脆弱性の観点において明確なプログラム上のエラーが存在します。
一種類目において、実行されるコマンドの引数として信頼できない第三者からの入力を受け入れています。
二種類目において、信頼できない第三者からのコマンドへのアクセスは拒否していますが、恐らく、攻撃者が入力できる代替方法を説明されていません。

別名

シェルインジェクション
シェルメタキャラクタ

理論的な補足

「OS コマンドインジェクション」という用語の指し示す意味の範囲は、人により異なります。
一つは、攻撃者が任意の OS コマンドを実行可能である全ての攻撃を指す場合。この場合では、攻撃者の制御下にあるプログラムを検索、実行するアプリケーションにより引き起こされる untrusted path weaknesses(CWE-426) を含みます。
もう一つは、アプリケーションが制御するプログラムにおいて、引数に攻撃者がコマンドセパレータを挿入するパターンのみを指す場合。

しかし、argument injection (CWE-88) において、続く引数をコマンドとして実行する 「-exec」 スイッチ(UNIX の「find」 コマンドなど)のようなコマンドラインスイッチや、コマンドラインに挿入されるオプションを切り替える場合などもあるため、OS コマンドインジェクションの定義は複雑な問題となっています。
二つ目に挙げた定義の場合には、 CWE-88 は CWE-78 の原因となる脆弱性(primary weakness)であると見なされています。

脆弱性の発生時期

アーキテクチャ及び設計
実装

該当するプラットフォーム

言語

全て

一般的な影響

 

影響を受ける範囲 影響
機密性
完全性
可用性
否認防止
技術的インパクト:許可されていないコードやコマンドの実行、DoS、crash / exit / restart、ファイルやディレクトリの読み込み、改ざん、アプリケーションデータの読み込み、改ざん

攻撃者は使用権限のないコマンドによりソフトウェアを無効化したり、アクセス権のないデータを読み込み、改ざんする可能性があります。攻撃対象のアプリケーションは攻撃者に代わりコマンドを実行するため、全ての悪意ある行動はアプリケーションや、アプリケーションの所有者のものであると見なされる可能性があります。

 

攻撃を受ける可能性

高い

検出手段

自動静的分析
本脆弱性は自動静的分析によって検出が可能です。最近のツールの多くは、フォールスポジティブを最小化するために、データフロー分析や制約ベースの技術を使用しています。
自動静的分析は、入力の妥当性チェックが適切に行われている場合、例えば、セキュリティ上影響のない警告や、コードの変更を要求する警告といったフォールスポジティブを識別できない場合があります。
自動静的分析は、直接 OS コマンドを呼び出すようなカスタム API ファンクションや、サードパーティのライブラリの使用を検出できない場合、特に API やライブラリのコードが分析に使用できない場合において、フォールスネガティブを引き起こす可能性があります。
この手段において100%の精度やカバーは不可能なため、完璧な解決策ではありません。

自動動的分析
本脆弱性は、ファズテスト(ファジング)、ロバストネステスト(頑健性のテスト)や、フォールトインジェクション(エラーをわざと起こすテスト)等、多種多様な入力を持つ膨大なテストケースを使用してソフトウェアを分析する、動的なツールや技術を用いて検出することが可能です。
ソフトウェアの処理速度は低下しますが、処理が不安定になったり、クラッシュする、不正確な結果を出すといったことはありません。

有効性:中

手動静的分析
本脆弱性は通常、一つのソフトウェアパッケージ内では高頻度では発生しないため、時間的制約の中で、脆弱な可能性がある処理の全てを評価することが可能な場合、手動によるホワイトボックス手法は十分なコードの範囲を網羅し、フォールスポジティブを減少させることが可能です。

有効性:高

脆弱なコード例

例 1:

 

以下の例は、ユーザが入力するドメイン名に対し DNS lookup の役割を担う Web アプリケーションです。OS コマンドインジェクションの一つ目の種類に分類されます。

サンプル言語:Perl (悪い例)
use CGI qw(:standard);
$name = param('name');
$nslookup = "/path/to/nslookup";
print header;
if (open($fh, "$nslookup $name|")) {
while (<$fh>) {
print escapeHTML($_);
print "<br>¥n";
}
close($fh);
}

攻撃者が以下のようなドメイン名を入力したと想定します。

(攻撃)
     cwe.mitre.org%20%3B%20/bin/ls%20-l

デコードすると、"%3B" は ";" に、"%20” はスペースとなり、Open() 関数は以下の様に文字列を処理することになります。
/path/to/nslookup cwe.mitre.org ; /bin/ls -l

結果、攻撃者は "/bin/ls -l" というコマンドを実行し、プログラムのワーキングディレクトリにある全ファイルのリストを入手します。この入力は、悪意あるプログラムをサーバにインストールするなど、さらに危険なコマンドに置き換えられる可能性があります。

 

例 2:

 

以下の例は、システムプロパティから実行するシェルスクリプトの名前を読み込みます。 OS コマンドインジェクションの二つ目の種類に分類されます。

サンプル言語:Java (悪い例)
String script = System.getProperty("SCRIPTNAME");
if (script != null)
System.exec(script);

攻撃者がこのプロパティを制御できる場合、危険なプログラムを指し示すようにプロパティを改ざんする可能性があります。

 

発見された事例

 

参照 詳細
CVE-1999-0067 Canonical example. CGI program does not neutralize "|" metacharacter when invoking a phonebook program.
CVE-2001-1246 Language interpreter's mail function accepts another argument that is concatenated to a string used in a dangerous popen() call. Since there is no neutralization of this argument, both OS Command Injection (CWE-78) and Argument Injection (CWE-88) are possible.
CVE-2002-0061 Web server allows command execution using "|" (pipe) character.
CVE-2003-0041 FTP client does not filter "|" from filenames returned by the server, allowing for OS command injection.
CVE-2008-2575 Shell metacharacters in a filename in a ZIP archive
CVE-2002-1898 Shell metacharacters in a telnet:// link are not properly handled when the launching application processes the link.
CVE-2008-4304 OS command injection through environment variable.
CVE-2008-4796 OS command injection through https:// URLs
CVE-2007-3572 Chain: incomplete blacklist for OS command injection

 

被害の緩和策

フェーズ:アーキテクチャおよび設計

望まれる機能を再作成する際には、可能な限り外部処理ではなくライブラリコールを使用して下さい。

フェーズ:アーキテクチャおよび設計、オペレーション

戦略: サンドボックス、Jail
プロセスとオペレーティングシステムの間で厳重な境界を強制する "jail" や、類似するサンドボックス環境の中でコードを実行してください。これにより、個々のディレクトリにおいてどのファイルに対しアクセス可能か、あるいは、そのソフトウェアによってどのコマンドが実行可能かを効果的に制限できます。
OSレベルの例として、Unix chroot jail、AppArmor 及び SELinux が挙げられます。一般的に、マネージドコードはいくつかの防御機能を提供します。例えば、Java SecurityManager の持つ java.io.FilePermission は、ファイル処理における制限を指定することが可能です。
これは、実現可能な解決策ではない可能性があります。また、オペレーティングシステムへの被害を限定するだけであり、残りのアプリケーションは侵害の対象のままです。
CWE-243 及びその他の jail に関連する脆弱性の回避には注意してください。

フェーズ:アーキテクチャおよび設計

戦略:攻撃面の特定と縮小
実行するコマンドの生成に使用するデータは、最大限、外部からの制御を排除して下さい。Web アプリケーションの場合には、  セッション状態を hidden form フィールドでクライアントに送信する代わりに、データをローカルに保存することが要求されます。

フェーズ:アーキテクチャおよび設計

CWE-602 を防ぐために、クライアント側で行われる全てのセキュリティチェックにおいて、それらのチェックがサーバ側でも同様に行われていることを確認してください。攻撃者はチェックが行われたあとに値を改ざんする、あるいはチェックを完全に消去することで、クライアント側のチェックを回避することが可能です。その場合、改ざんされた値がサーバに送信されます。

フェーズ:アーキテクチャおよび設計

戦略: ライブラリ、フレームワーク
本脆弱性の発生を防ぐ、あるいは本脆弱性を回避しやすい構造を提供する、十分に検査されたライブラリやフレームワークを使用してください。
例として、ESAPI Encoding control や類似するツール、ライブラリ、フレームワークが挙げられます。使用することによって、エラーになりにくい方法で出力をエンコードすることが可能です。

フェーズ:実装

戦略:出力エンコーディング
リスクを受容し、動的に生成されるクエリやコマンドを使用する必要がある場合には、適切に引数をクォートし、引数に含まれる特殊文字をエスケープして下さい。最も慎重な手法として、非常に厳重なホワイトリストを通過しない全ての文字について、エスケープ又はフィルタリングを行う(英数字以外の全ての文字や空白等)ことが挙げられます。空白等の特殊文字の使用が必要な場合は、エスケープ又はフィルタリングの処理後、それぞれの引数をクォートで囲ってください。argument injection(CWE-88)の脆弱性が発生しないよう注意してください。

フェーズ:実装

実行するプログラムが、入力ファイルまたは標準入力による引数指定を許可している場合、コマンドラインの代わりに引数を渡すモードの利用を検討して下さい。

フェーズ:アーキテクチャおよび設計

戦略:パラメータ化
可能であれば、自動的にデータとコード間の分離を強制するような、構造化された仕組みを使用してください。
このような仕組みにより、開発者が手動で行う代わりに、出力が生成される全ての箇所に、関連する引用、エンコード、入力の妥当性チェックの機能を自動的に提供することが可能です。
言語によってはコマンドを呼び出す関数が複数提供されています。可能であれば、一行の文字列を使用するコマンドシェルを呼び出す関数を特定し、この関数を個別の引数を必要とする関数に置き換えて下さい。一般的にこれらの関数は、引数に適切なクォートを適用し、適切なフィルタリングを実施します。
例えば、C言語では、system() 関数は実行される全てのコマンドを含む文字列を受け付けます。一方で、execl()、execve()等の関数は、各引数に文字列の配列が必要です。Windows では、CreateProcess() は一度に一つのコマンドしか受け付けません。Perl では、 system() に対して、引数の配列が提供される場合、各引数にクォートを適用します。

フェーズ:実装

戦略: 入力の妥当性チェック
全ての入力は悪意のあるものと想定してください。仕様に厳密に従い許可する入力のホワイトリストを使用する等、既知の受け入れられている入力の妥当性チェック手法を用いてください。仕様に反する入力を拒否する、あるいは入力を仕様に適応する形に変化させてください。ブラックリストに依存してしまう等、悪意のある、あるいは不正な入力を探すことのみに頼らないでください。しかし、ブラックリストは予測される攻撃の検知や、無条件に拒否するべき不正な入力を決定する際に役立ちます。

入力値の妥当性をチェックする際、関連しそうな全ての要素(長さ、入力タイプ、許容する値の範囲、入力の過不足、構文、関連するフィールド間の一貫性、及びビジネスルールの一致、等)について考慮してください。ビジネスルールの例として、"boat" は英数字しか含まないため構文的に有効ですが、もし開発者が "red" や "blue" のような色の名前を想定する場合には有効ではない、というロジックが挙げられます。

OS コマンドを構築する際、リクエストのパラメータとして想定する値に基づき文字セットを制限するような、厳しいホワイトリストを使用してください。これにより、間接的に攻撃の範囲を限定することが可能ですが、適切な出力エンコード及びエスケープと比較すると緩和策としての重要度は下がります。

適切な出力のエンコード、エスケープ、クォートは、OS コマンドインジェクションを防ぐために最も効果的な解決策であるのに対し、入力の妥当性チェックは多層防御を提供するものであることに注意してください。これは、実際に出力される内容を効果的に制限するからです。入力の妥当性のチェックだけでOSコマンドインジェクションを防げるわけではありません。特に、任意の内容を自由に入力可能なテキストフィールドのサポートを必要とする場合は困難になります。例えばOSコマンドとしてメールプログラムを呼び出す際には、";" や ">" のように、他のプログラムでは危険性のある入力を含む件名フィールドを許可する必要があるため、エスケープやその他の方法で処理しなければなりません。この場合、危険な文字の削除により、OS コマンドインジェクションのリスクを下げることが可能ですが、メールの件名がユーザの意図した通りではないため、不正確なふるまいをする可能性があります。些細な問題に見えますが、この問題は、他のコンポーネントへメッセージを引き渡すために、プログラムが構造化されたメールの件名に依存している場合に重大な問題へと発展します。

入力の妥当性チェックにミスがある場合にも(例えば 100 の入力フィールドのうち 1 つだけチェックを忘れてしまう等)、適切なエンコードがインジェクション攻撃からの保護となるでしょう。入力の妥当性のチェックは使いやすい手法であり、攻撃される可能性を大きく減らし、攻撃を検出し、適切なエンコーディングが行えない場合にも効果がある等の利点がありますが、それ単体で独立して使える手法でありません。

フェーズ:アーキテクチャおよび設計

戦略: 変換による強制
ファイル名やURLのような条件に適合するオブジェクトが制限されている場合、あるいは既知である場合、固定した入力値(数字のID等)から実際のファイル名やURLのマッピングを作成し、それ以外の入力を拒否してください。

フェーズ:オペレーション

戦略: コンパイル、ビルドの強化
Perl の 「-T」 スイッチ等、汚染検出機能を自動実行し、汚染された変数を含むコマンドの実行を防ぐ環境でコードを実行して下さい。誤って危険性がある入力に対して、汚染されていないという印がつかないように正確に入力の妥当性を確認するように注意しなければなりませんが、汚染された変数を取り除くための妥当性を確認するステップを強制的に実行して下さい。(CWE-183、CWE-184をご参照下さい)

フェーズ:実装

エラーメッセージが対象となる読者にとってのみ有益な、最小限の詳細情報しか含まないことを確認してください。メッセージは適度に曖昧になるようバランスを取る必要があります。エラー内容を判別する方法を公開する必要は必ずしもありません。そのような詳細情報は攻撃が成功する機会を増やすための攻撃手法の改良に利用される可能性があります。

もし、エラーが詳細を追跡する必要がある場合、ログメッセージに記録するようにしてください。しかし、攻撃者がログメッセージを閲覧可能である場合に何が起こるかも考慮してください。どんな形式であってもパスワードのような極秘情報が記録されることは避けるべきです。また、ユーザ名が有効か否かといった、攻撃者に内部の構文をほのめかしてしまうような、一貫性のないメッセージにならないよう避けてください。

OS コマンドインジェクションの背景において、ユーザに戻されるエラー情報によって、OS コマンドが実行されているか否か、場合によってはどのコマンドが使用されているかが公開されてしまう可能性があります。

フェーズ:オペレーション

戦略: サンドボックス、Jail
許可するコマンドのホワイトリストを作るためにランタイムポリシーを使用し、ホワイトリストに掲載されていないコマンドの使用を防いで下さい。AppArmor 等の技術が有効です。

フェーズ:オペレーション

戦略: ファイアウォール
本脆弱性に対する攻撃を検知するアプリケーションファイアウォールを使用してください。第三者が制作したソフトウェアであるためコードが修正できない場合などに、より総合的なソフトウェアの保証手段となるため、緊急回避策として、または多層防御の目的として効果的です。

有効性:中
アプリケーションファイアウォールは全ての入力ベクターを網羅することができない可能性があります。加えて、入力を検証する処理に対して不正な形式の入力により、防御メカニズムを迂回するような行為が可能です。アプリケーションファイアウォールの機能によっては、不用意に正当なリクエストを拒否、または修正してしまう可能性があります。最終的に、手動によるカスタマイズが必要です。

フェーズ:アーキテクチャおよび設計、オペレーション

戦略: 環境の強化
必要なタスクを実行するために求められる最小限の権限を使用してコードを実行してください。可能であれば、一つのタスクのみに使用される、権限を限定した単独のアカウントを作成してください。それにより、攻撃が成功した場合でも、即座に他のソフトウェアやその環境へアクセスされることは防ぐことができます。例えば、特に日常的なオペレーションにおいて、めったにデータベースの管理者権限を必要としないデータベースアプリケーションが挙げられます。

フェーズ:オペレーションおよび実装

戦略: 環境の強化
PHP を使用している場合は、register_globals を使用しないようにアプリケーションを設定してください。実装においては、この機能に頼らないようアプリケーションを開発してください。register_globals の類似機能の実装においては CWE-95、CWE-261 及び類似する脆弱性の対象とならないよう警戒してください。

関係性

 

Nature Type ID Name View(s) this relationship pertains to
ChildOf Weakness Class 77 Improper Neutralization of Special Elements used in a Command ('Command Injection') Development Concepts (primary)699
Research Concepts (primary)1000
ChildOf Category 634 Weaknesses that Affect System Processes Resource-specific Weaknesses (primary)631
ChildOf Category 714 OWASP Top Ten 2007 Category A3 - Malicious File Execution Weaknesses in OWASP Top Ten (2007) (primary)629
ChildOf Category 727 OWASP Top Ten 2004 Category A6 - Injection Flaws Weaknesses in OWASP Top Ten (2004) (primary)711
ChildOf Category 741 CERT C Secure Coding Section 07 - Characters and Strings (STR) Weaknesses Addressed by the CERT C Secure Coding Standard (primary)734
ChildOf Category 744 CERT C Secure Coding Section 10 - Environment (ENV) Weaknesses Addressed by the CERT C Secure Coding Standard734
ChildOf Category 751 2009 Top 25 - Insecure Interaction Between Components Weaknesses in the 2009 CWE/SANS Top 25 Most Dangerous Programming Errors (primary)750
ChildOf Category 801 2010 Top 25 - Insecure Interaction Between Components Weaknesses in the 2010 CWE/SANS Top 25 Most Dangerous Programming Errors(primary)800
ChildOf Category 810 OWASP Top Ten 2010 Category A1 - Injection Weaknesses in OWASP Top Ten (2010)(primary)809
CanAlsoBe Weakness Base 88 Argument Injection or Modification Research Concepts1000
MemberOf View 630 Weaknesses Examined by SAMATE Weaknesses Examined by SAMATE (primary)630
MemberOf View 635 Weaknesses Used by NVD Weaknesses Used by NVD (primary)635
CanFollow Weakness Base 184 Incomplete Blacklist Research Concepts1000

 

要調査事項 (CWE の見解)

argument injection (CWE-88) の機能を含め、OS コマンドインジェクションの変種を区別するために、一層の調査が必要です。同様の区別は、SQL インジェクション等、その他のインジェクション関連の問題にも存在する可能性があります。

影響を受けるシステムリソース

システムプロセス

機能分野

プログラムの呼び出し

他組織での分類

 

組織名または組織での分類 ノード ID CWEの分類との適合度 分類名
PLOVER OS Command Injection
OWASP Top Ten 2007 A3 CWEより詳細 Malicious File Execution
OWASP Top Ten 2004 A6 CWEより詳細 Injection Flaws
CERT C Secure Coding ENV03-C Sanitize the environment when invoking external programs
CERT C Secure Coding ENV04-C Do not call system() if you do not need a command processor
CERT C Secure Coding STR02-C Sanitize data passed to complex subsystems
WASC 31 OS Commanding

 

関連する攻撃パターン

 

CAPEC-ID 攻撃パターン名 (CAPEC Version 1.5)
15 Command Delimiters
43 Exploiting Multiple Input Interpretation Layers
88 OS Command Injection
6 Argument Injection
108 Command Line Execution through SQL Injection

 

ホワイトボックスの定義

コードパスが以下の条件を満たす脆弱性
  1. 開始ステートメントで入力を受け付ける場合
  2. 以下の条件を満たす終了ステートメントで OS コマンドを実行する場合
        ・入力が OS コマンドの一部であり、望ましくないOSコマンドである場合
※上記の「望ましくない」とは、以下の状態を指します。
  1. 検証されていない
  2. 誤った方法で検証されている

参照

G. Hoglund and G. McGraw. "Exploiting Software: How to Break Code". Addison-Wesley. 2004-02. 
Pascal Meunier. "Meta-Character Vulnerabilities". 2008-02-20. <http://www.cs.purdue.edu/homes/cs390s/slides/week09.pdf>.
Robert Auger. "OS Commanding". 2009-06. <http://projects.webappsec.org/OS-Commanding>.
Lincoln Stein and John Stewart. "The World Wide Web Security FAQ". chapter: "CGI Scripts". 2002-02-04. <http://www.w3.org/Security/Faq/wwwsf4.html>.
Jordan Dimov, Cigital. "Security Issues in Perl Scripts". <http://www.cgisecurity.com/lib/sips.html>.
[REF-17] Michael Howard, David LeBlanc and John Viega. "24 Deadly Sins of Software Security". "Sin 10: Command Injection." Page 171. McGraw-Hill. 2010. 
Frank Kim. "Top 25 Series - Rank 9 - OS Command Injection". SANS Software Security Institute. 2010-02-24. <http://blogs.sans.org/appsecstreetfighter/2010/02/24/top-25-series-rank-9-os-command-injection/>.

更新履歴

[2011年04月21日]
  2010年10月12日時点のデータを元に更新
[2009年06月29日]
  2009年02月02日時点の下記 URL を元に作成
    http://cwe.mitre.org/data/definitions/78.html


登録日 2011/04/21

最終更新日 2023/04/04