界: Input Validation and Representation

入力の検証や表現の問題は、メタキャラクター、代替エンコーディング、数値表現などによって引き起こされます。セキュリティの問題は、入力を信頼することに起因します。この問題に含まれるのは、「Buffer Overflow」、「Cross-Site Scripting」攻撃、「SQL Injection」などです。

Command Injection

Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。

2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: システムユーティリティの次のコードでは、レジストリキー APPHOME を使用してインストール先ディレクトリが決定され、指定されたディレクトリからの相対パスに基づいて初期化スクリプトが実行されます。


...
CALL FUNCTION 'REGISTRY_GET'
EXPORTING
KEY = 'APPHOME'
IMPORTING
VALUE = home.

CONCATENATE home INITCMD INTO cmd.
CALL 'SYSTEM' ID 'COMMAND' FIELD cmd ID 'TAB' FIELD TABL[].
...
Example 1 のコードでは、悪意ある INITCMD を含んだ別のパスを参照するようにレジストリエントリ APPHOME を変更することにより、攻撃者はアプリケーションの任意のコマンドを高い権限で実行できます。このプログラムはレジストリから読み取った値の検証を行わないので、レジストリキー APPHOME の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。

例 2: 次のコードは、ユーザーが rman ユーティリティに対するバッチファイルラッパーを使用して Oracle データベースのバックアップを開始し、その後 cleanup.bat スクリプトを実行して一部のテンポラリ ファイルを削除できるインターフェイスを持つ Web アプリケーションのものです。スクリプト rmanDB.bat は、実行するバックアップのタイプを指定するコマンドライン パラメーターを 1 つ受け取ります。データベースへのアクセスが制限されているため、アプリケーションは権限を持つユーザーとしてバックアップを実行します。


...
btype = request->get_form_field( 'backuptype' )
CONCATENATE `/K 'c:\\util\\rmanDB.bat ` btype `&&c:\\util\\cleanup.bat'` INTO cmd.

CALL FUNCTION 'SXPG_COMMAND_EXECUTE_LONG'
EXPORTING
commandname = cmd_exe
long_params = cmd_string
EXCEPTIONS
no_permission = 1
command_not_found = 2
parameters_too_long = 3
security_risk = 4
OTHERS = 5.
...


ここでの問題はプログラムがユーザーから読み取る backuptypeパラメーターを検証しないことです。通常、関数モジュール SXPG_COMMAND_EXECUTE_LONG は複数のコマンドを実行しませんが、この例のプログラムは最初に cmd.exe シェルを実行して、CALL 'SYSTEM' を 1 回コールするだけで複数のコマンドを実行しています。呼び出されたシェルは、2 つのアンパサンドで区切られた複数のコマンドを実行できます。攻撃者が "&& del c:\\dbms\\*.*" という形式の文字列を渡すと、アプリケーションは、プログラムにより指定された他のコマンドとともにこのコマンドを実行します。アプリケーションはその性質上、データベースとのやり取りに必要な権限で実行されています。このため、攻撃者が挿入したコマンドも、その権限で実行されます。

例 3: 次のコードは、ユーザーがシステムのパスワードを更新できるインターフェイスを提供する Web アプリケーションのものです。特定のネットワーク環境でパスワードを更新する処理には、/var/yp ディレクトリでの make コマンドの実行が含まれます。


...
MOVE 'make' to cmd.
CALL 'SYSTEM' ID 'COMMAND' FIELD cmd ID 'TAB' FIELD TABL[].
...


ここでの問題は、プログラムが make のための絶対パスを指定しておらず、CALL 'SYSTEM' のコールを実行する前に環境をクリーンにできていないことです。攻撃者が $PATH 変数を変更して、make という名前の悪意あるバイナリを参照させ、攻撃者の環境でプログラムが実行されるようにすると、本来のバイナリでなく悪意あるバイナリがロードされます。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の make もその権限で実行されるため、攻撃者がシステムを完全に制御してしまう可能性があります。
References
[1] SAP OSS notes 677435, 686765, 866732, 854060, 1336776, 1520462, 1530983 and related notes.
desc.dataflow.abap.command_injection
Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。

2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: 次のコードでは、設定ファイルの入力を使用してインストール先のディレクトリが決定され、指定されたディレクトリからの相対パスに基づいて初期化スクリプトが実行されます。


...
var fs:FileStream = new FileStream();
fs.open(new File(String(configStream.readObject())+".txt"), FileMode.READ);
home = String(fs.readObject(home));
var cmd:String = home + INITCMD;
fscommand("exec", cmd);
...
Example 1 のコードでは、悪意ある INITCMD を含んだ別のパスを参照するように設定ファイル configStream の内容を変更することにより、攻撃者はアプリケーションの任意のコマンドを高い権限で実行できます。このプログラムではファイルから読み取った値の検証が実行されないため、攻撃者がこの値を制御できる場合、アプリケーションを操って悪意のあるコードを実行し、システムを制御できます。

例 2: 次のコードは、ユーザーが rman ユーティリティに対するバッチファイルラッパーを使用して Oracle データベースのバックアップを開始し、その後 cleanup.bat スクリプトを実行して一部のテンポラリ ファイルを削除できるインターフェイスを持つ Web アプリケーションのものです。スクリプト rmanDB.bat は、実行するバックアップのタイプを指定するコマンドライン パラメーターを 1 つ受け取ります。データベースへのアクセスが制限されているため、アプリケーションは権限を持つユーザーとしてバックアップを実行します。


...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var btype:String = String(params["backuptype"]);
var cmd:String = "cmd.exe /K \"c:\\util\\rmanDB.bat " + btype + "&&c:\\util\\cleanup.bat\"";
fscommand("exec", cmd);
...


ここでの問題はプログラムがユーザーから読み取る backuptypeパラメーターを検証しないことです。通常、関数 fscommand() は複数のコマンドを実行しませんが、この例のプログラムは最初に cmd.exe シェルを実行して、fscommnd() を 1 回コールするだけで複数のコマンドを実行しています。呼び出されたシェルは、2 つのアンパサンドで区切られた複数のコマンドを実行できます。攻撃者が "&& del c:\\dbms\\*.*" という形式の文字列を渡すと、アプリケーションは、プログラムにより指定された他のコマンドとともにこのコマンドを実行します。アプリケーションはその性質上、データベースとのやり取りに必要な権限で実行されています。このため、攻撃者が挿入したコマンドも、その権限で実行されます。

例 3: 次のコードは、ユーザーがシステムのパスワードを更新できるインターフェイスを提供する Web アプリケーションのものです。特定のネットワーク環境でパスワードを更新する処理には、/var/yp ディレクトリでの make コマンドの実行が含まれます。


...
fscommand("exec", "make");
...


ここでの問題は、プログラムが make のための絶対パスを指定しておらず、fscommand() のコールを実行する前に環境をクリーンにできていないことです。攻撃者が $PATH 変数を変更して、make という名前の悪意あるバイナリを参照させ、攻撃者の環境でプログラムが実行されるようにすると、本来のバイナリでなく悪意あるバイナリがロードされます。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の make もその権限で実行されるため、攻撃者がシステムを完全に制御してしまう可能性があります。
desc.dataflow.actionscript.command_injection
Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。

2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: システムユーティリティの次のコードでは、システムプロパティ APPHOME を使用してインストール先ディレクトリが決定され、指定されたディレクトリからの相対パスに基づいて初期化スクリプトが実行されます。


...
string val = Environment.GetEnvironmentVariable("APPHOME");
string cmd = val + INITCMD;
ProcessStartInfo startInfo = new ProcessStartInfo(cmd);
Process.Start(startInfo);
...
Example 1 のコードでは、悪意ある INITCMD を含んだ別のパスを参照するようにシステムプロパティ APPHOME を変更することにより、攻撃者はアプリケーションの任意のコマンドを昇格した権限で実行できます。このプログラムは環境から読み取った値の検証を行わないので、システムプロパティ APPHOME の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。

例 2: 次のコードは、ユーザーが rman ユーティリティに対するバッチファイルラッパーを使用して Oracle データベースのバックアップを開始し、その後 cleanup.bat スクリプトを実行して一部のテンポラリ ファイルを削除できるインターフェイスを持つ Web アプリケーションのものです。スクリプト rmanDB.bat は、実行するバックアップのタイプを指定するコマンドライン パラメーターを 1 つ受け取ります。データベースへのアクセスが制限されているため、アプリケーションは権限を持つユーザーとしてバックアップを実行します。


...
string btype = BackupTypeField.Text;
string cmd = "cmd.exe /K \"c:\\util\\rmanDB.bat"
+ btype + "&&c:\\util\\cleanup.bat\""));
Process.Start(cmd);
...


ここでの問題は、このプログラムが BackupTypeFieldをいっさい検証しないことです。通常、Process.Start() 関数は複数のコマンドを実行しませんが、この例のプログラムは最初に cmd.exe シェルを実行して、Process.Start() を 1 回コールするだけで複数のコマンドを実行しています。呼び出されたシェルは、2 つのアンパサンドで区切られた複数のコマンドを実行できます。攻撃者が "&& del c:\\dbms\\*.*" という形式の文字列を渡すと、アプリケーションは、プログラムにより指定された他のコマンドとともにこのコマンドを実行します。アプリケーションはその性質上、データベースとのやり取りに必要な権限で実行されています。このため、攻撃者が挿入したコマンドも、その権限で実行されます。

例 3: 次のコードは、ユーザーがアクセスしてシステムのパスワードを更新できるインターフェイスを持つ Web アプリケーションのものです。このネットワーク環境でパスワードを更新する処理には、次に示すように update.exe コマンドの実行が含まれます。


...
Process.Start("update.exe");
...


ここでの問題は、プログラムが絶対パスを指定しておらず、Process.start() のコールを実行する前に環境をクリーンにできていないことです。攻撃者が $PATH 変数を変更して、update.exe という名前の悪意あるバイナリを参照させ、攻撃者の環境でプログラムが実行されるようにすると、本来のバイナリでなく悪意あるバイナリがロードされます。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の update.exe もその権限で実行されるため、攻撃者がシステムを完全に制御してしまう可能性があります。
desc.dataflow.dotnet.command_injection
Abstract
未検証のユーザー入力を含むコマンドを実行すると、アプリケーションが攻撃者に利用される原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この例では、1 つ目のシナリオが最も懸念されます。この場合、攻撃者は実行されるコマンドを直接的に制御します。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。


2. データが、アプリケーションがコマンドとして実行する文字列の一部の場合。


3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: 次の単純なプログラムはファイル名をコマンド ライン引数として受け取り、ユーザーに対してファイルの内容を表示します。このプログラムは setuid root にインストールされている、システム管理者用の学習ツールです。権限が設定されているシステム ファイルを変更したりシステムに損傷を与えたりすることができない状態で、それらのファイルをチェックすることができます。


int main(char* argc, char** argv) {
char cmd[CMD_MAX] = "/usr/bin/cat ";
strcat(cmd, argv[1]);
system(cmd);
}


このプログラムは root 権限で実行されるため、system() のコールも root 権限で実行されます。ユーザーが標準的なファイル名を指定した場合、コールは想定どおりに動作します。しかし、攻撃者が ";rm -rf /" という形の文字列を渡すと、system() へのコールでは引数がないため cat を実行できず、root パーティションの内容を回帰的に削除してしまいます。

例 2: 権限が設定されているプログラムの次のコードは、環境変数 $APPHOME を使用してアプリケーションのインストール先ディレクトリを判断し、そのディレクトリの初期化スクリプトを実行します。


...
char* home=getenv("APPHOME");
char* cmd=(char*)malloc(strlen(home)+strlen(INITCMD));
if (cmd) {
strcpy(cmd,home);
strcat(cmd,INITCMD);
execl(cmd, NULL);
}
...
Example 1 に例示するコードを利用すれば、攻撃者はアプリケーションの権限を高めて任意のコマンドを実行できます。この例では、攻撃者は環境変数 $APPHOME を変更して、INITCMD の悪意ある改変版が置かれた別のパスを指定することができます。プログラムでは環境から読み取った値を検証しないため、攻撃者は環境変数を制御することでアプリケーションを操って悪意あるコードを実行させることができます。

攻撃者は環境変数を使用して、プログラムが呼び出すコマンドを制御します。この例には環境の影響が明らかに示されています。次に、コマンドの解釈を攻撃者が変更できる場合にどうなるか見てみましょう。

例 3: 次のコードは、ユーザーが自分のパスワードを変更するための Web ベースの CGI ユーティリティのものです。NIS によるパスワード更新処理には、/var/yp ディレクトリでの make の実行も含まれます。プログラムはパスワードレコードも更新するので setuid root にインストールされている、ということに注意してください。

プログラムは次のようにして make を呼び出します。


system("cd /var/yp && make &> /dev/null");


前述した例とは異なり、この例ではコマンドはハードコーディングされているため、攻撃者は system() に渡される引数を制御できません。ただし、プログラムでは make の絶対パスが指定されておらず、コマンドを呼び出す前にすべての環境変数がチェックされません。このため、攻撃者は $PATH 変数を変更して、make という名前の悪意あるバイナリを参照させ、シェル プロンプトから CGI スクリプトを実行させることができます。また、プログラムが setuid root にインストールされているため、攻撃者の makeroot 権限で実行されます。

Windows では、この他のリスクも存在します。

例 4:CreateProcess() を直接または _spawn() ファミリの関数のいずれかへのコールを介して呼び出す場合、実行可能ファイルまたはパスにスペースがあるときは注意が必要です。


...
LPTSTR cmdLine = _tcsdup(TEXT("C:\\Program Files\\MyApplication -L -S"));
CreateProcess(NULL, cmdLine, ...);
...
CreateProcess() がスペースを解析する方法では、オペレーティングシステムが最初に実行を試みる実行可能ファイルは、MyApplication.exe ではなく Program.exe です。このため、攻撃者がシステムに Program.exe という名前の悪意あるアプリケーションをインストールできる場合、Program Files ディレクトリを使用して CreateProcess() を不正にコールするプログラムは、目的のアプリケーションの代わりにこのアプリケーションを実行します。

環境は、プログラム内のシステムコマンドの実行に大きな役割を果たします。system()exec()、および CreateProcess() といった関数は、自身をコールするプログラムの環境を使用するため、攻撃者はそれらのコールの動作を変更できる可能性があります。
desc.dataflow.cpp.command_injection
Abstract
絶対パスを指定せずにコマンドを実行すると、プログラムの実行環境の $PATH やその他の要素を変えることで、攻撃者がプログラムを利用して悪意のあるバイナリを実行することが可能になる場合があります。
Explanation
Command Injection 脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドを明示的に制御します。

- プログラムに対するパラメーターを攻撃者が変更可能である。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を暗黙的に制御します。

この場合は第 2 のシナリオが最も懸念されます。環境変数を変更したり、悪意のある実行可能ファイルを検索パスの最初の方に置くことにより、攻撃者はコマンドの意味を変更することができます。このタイプの Command Injection 脆弱性が発生するのは、次の場合です。

1.攻撃者がアプリケーションの環境を変更する。

2.絶対パスを指定せずに、または実行するバイナリを検証せずに、アプリケーションがコマンドを実行する。



3.アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: この例は、コマンドを解釈する方法を攻撃者が変えられる場合に何が起きるかを示しています。コードは、ユーザーが自分のパスワードを変更するための Web ベースの CGI ユーティリティのものです。NIS によるパスワード更新処理には、/var/yp ディレクトリでの make の実行も含まれます。プログラムはパスワード レコードを更新するため、setuid root にインストールされていることに注意してください。

プログラムは、make を次のように呼び出します。


MOVE "cd /var/yp && make &> /dev/null" to command-line
CALL "CBL_EXEC_RUN_UNIT" USING command-line
length of command-line
run-unit-id
stack-size
flags


この例のコマンドはハードコードされているため、攻撃者は CBL_EXEC_RUN_UNIT に渡す引数を制御できません。しかしプログラムは make の絶対パスを指定せず、コマンド呼出しの前に環境変数をスクラブしないため、攻撃者は $PATH 変数が make という名前の悪意のあるバイナリをポイントするように変更して、シェル プロンプトから CGI スクリプトを実行できます。さらに、プログラムは setuid root にインストールされているため、攻撃者バージョンの makeroot 権限で実行されるようになります。

例 2: 以下のコードは環境変数を使用して、pdfprint コマンドを使用して印刷するファイルを含む一時ディレクトリを決定します。


DISPLAY "TEMP" UPON ENVIRONMENT-NAME
ACCEPT ws-temp-dir FROM ENVIRONMENT-VARIABLE
STRING "pdfprint " DELIMITED SIZE
ws-temp-dir DELIMITED SPACE
"/" DELIMITED SIZE
ws-pdf-filename DELIMITED SPACE
x"00" DELIMITED SIZE
INTO cmd-buffer
CALL "SYSTEM" USING cmd-buffer


前の例と同様に、コマンドはハードコードされています。しかし、プログラムは pdfprint の絶対パスを指定しないため、攻撃者は $PATH 変数が悪意のあるバイナリをポイントするように変更できます。さらに、DELIMITED SPACE フレーズが ws-temp-dir および ws-pdf-filename における埋め込みスペースを防止する一方で、シェル メタ文字 (&& など) が埋め込まれている可能性もあります。
desc.semantic.cobol.command_injection
Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。

2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: 次のコードがあると、攻撃者は、cmd リクエストパラメーターを介して任意のコマンドを指定できてしまいます。


...
<cfset var="#url.cmd#">
<cfexecute name = "C:\windows\System32\cmd.exe"
arguments = "/c #var#"
timeout = "1"
variable="mycmd">
</cfexecute>
...
desc.dataflow.cfml.command_injection
Abstract
信頼されていないソースから、または信頼されていない環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection 脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドを明示的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を暗黙的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection 脆弱性が発生するのは、次の場合です。

1.信頼できないソースからアプリケーションにデータが入力された場合。

2.アプリケーションによって実行されるコマンドを表す文字列として、またはその一部であるデータが使用された場合。

3.アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: システム ユーティリティの次のコードは、システム プロパティ APPHOME を使用してインストール先ディレクトリを特定し、指定されたディレクトリからの相対パスに基づいて初期化スクリプトを実行します。


...
final cmd = String.fromEnvironment('APPHOME');
await Process.run(cmd);
...
Example 1 のコードでは、悪意ある INITCMD を含んだ別のパスを参照するようにシステムプロパティ APPHOME を変更することにより、攻撃者はアプリケーションの任意のコマンドを昇格した権限で実行できます。このプログラムは環境から読み取った値の検証を行わないので、システムプロパティ APPHOME の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。
desc.dataflow.dart.command_injection
Abstract
信頼されていないソースから、または信頼されていない環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection 脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドを明示的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を暗黙的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection 脆弱性が発生するのは、次の場合です。

1.信頼できないソースからアプリケーションにデータが入力された場合。


2.アプリケーションで実行されるコマンドを表す文字列 (またはその一部) としてデータが使用された場合。

3.アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例: 次のコードでは、ユーザー制御のコマンドを実行します。


cmdName := request.FormValue("Command")
c := exec.Command(cmdName)
c.Run()
desc.dataflow.golang.command_injection
Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。

2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: システムユーティリティの次のコードでは、システムプロパティ APPHOME を使用してインストール先ディレクトリが決定され、指定されたディレクトリからの相対パスに基づいて初期化スクリプトが実行されます。


...
String home = System.getProperty("APPHOME");
String cmd = home + INITCMD;
java.lang.Runtime.getRuntime().exec(cmd);
...
Example 1 のコードでは、悪意ある INITCMD を含んだ別のパスを参照するようにシステムプロパティ APPHOME を変更することにより、攻撃者はアプリケーションの任意のコマンドを昇格した権限で実行できます。このプログラムは環境から読み取った値の検証を行わないので、システムプロパティ APPHOME の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。

例 2: 次のコードは、ユーザーが rman ユーティリティに対するバッチファイルラッパーを使用して Oracle データベースのバックアップを開始し、その後 cleanup.bat スクリプトを実行して一部のテンポラリ ファイルを削除できるインターフェイスを持つ Web アプリケーションのものです。スクリプト rmanDB.bat は、実行するバックアップのタイプを指定するコマンドライン パラメーターを 1 つ受け取ります。データベースへのアクセスが制限されているため、アプリケーションは権限を持つユーザーとしてバックアップを実行します。


...
String btype = request.getParameter("backuptype");
String cmd = new String("cmd.exe /K
\"c:\\util\\rmanDB.bat "+btype+"&&c:\\util\\cleanup.bat\"")
System.Runtime.getRuntime().exec(cmd);
...


ここでの問題はプログラムがユーザーから読み取る backuptypeパラメーターを検証しないことです。通常、関数 Runtime.exec() は複数のコマンドを実行しませんが、この例のプログラムは最初に cmd.exe シェルを実行して、Runtime.exec() を 1 回コールするだけで複数のコマンドを実行しています。呼び出されたシェルは、2 つのアンパサンドで区切られた複数のコマンドを実行できます。攻撃者が "&& del c:\\dbms\\*.*" という形式の文字列を渡すと、アプリケーションは、プログラムにより指定された他のコマンドとともにこのコマンドを実行します。アプリケーションはその性質上、データベースとのやり取りに必要な権限で実行されています。このため、攻撃者が挿入したコマンドも、その権限で実行されます。

例 3: 次のコードは、ユーザーがシステムのパスワードを更新できるインターフェイスを提供する Web アプリケーションのものです。特定のネットワーク環境でパスワードを更新する処理には、/var/yp ディレクトリでの make コマンドの実行が含まれます。


...
System.Runtime.getRuntime().exec("make");
...


ここでの問題は、プログラムが make のための絶対パスを指定しておらず、Runtime.exec() のコールを実行する前に環境をクリーンにできていないことです。攻撃者が $PATH 変数を変更して、make という名前の悪意あるバイナリを参照させ、攻撃者の環境でプログラムが実行されるようにすると、本来のバイナリでなく悪意あるバイナリがロードされます。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の make もその権限で実行されるため、攻撃者がシステムを完全に制御してしまう可能性があります。

一部には、モバイルの世界では Command Injection のような古典的な脆弱性は意味がなく、自分に降りかかる攻撃をするはずがない、という見方があります。しかし忘れてはならないモバイルプラットフォームの基本は、さまざまなソースからアプリケーションをダウンロードして同じデバイス上で一緒に実行することです。このため、たとえばバンキングアプリケーションのすぐ隣でマルウェアの一部を実行する可能性が高くなり、モバイルアプリケーションの攻撃面を拡張し、プロセス間通信なども含める必要があります。

例 4: 次のコードは、Android のインテントから実行されるコマンドを読み取ります。


...
String[] cmds = this.getIntent().getStringArrayExtra("commands");
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String cmd : cmds) {
os.writeBytes(cmd+"\n");
}
os.writeBytes("exit\n");
os.flush();
...


ルート化されたデバイス上では、悪意のあるアプリケーションが標的となるアプリケーションにスーパー ユーザーの権限で任意のコマンドを強制的に実行させることができます。
References
[1] IDS07-J. Sanitize untrusted data passed to the Runtime.exec() method CERT
desc.dataflow.java.command_injection
Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。


2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: システム ユーティリティの次のコードでは、環境変数 APPHOME を使用してインストール先ディレクトリが決定され、指定されたディレクトリからの相対パスに基づいて初期化スクリプトが実行されます。


var cp = require('child_process');
...
var home = process.env('APPHOME');
var cmd = home + INITCMD;
child = cp.exec(cmd, function(error, stdout, stderr){
...
});
...
Example 1 のコードでは、悪意ある INITCMD を含んだ別のパスを参照するようにシステムプロパティ APPHOME を変更することにより、攻撃者はアプリケーションの任意のコマンドを昇格した権限で実行できます。このプログラムは環境から読み取った値の検証を行わないので、システム プロパティ APPHOME の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。

例 2: 次のコードは、ユーザーが rman ユーティリティに対するバッチファイル ラッパーを使用して Oracle データベースのバックアップを開始できるようにする管理用 Web アプリケーションのものです。スクリプト rmanDB.bat は、実行するバックアップのタイプを指定するコマンドライン パラメーターを 1 つ受け取ります。データベースへのアクセスが制限されているため、アプリケーションは権限を持つユーザーとしてバックアップを実行します。


var cp = require('child_process');
var http = require('http');
var url = require('url');

function listener(request, response){
var btype = url.parse(request.url, true)['query']['backuptype'];
if (btype !== undefined){
cmd = "c:\\util\\rmanDB.bat" + btype;
cp.exec(cmd, function(error, stdout, stderr){
...
});
}
...
}
...
http.createServer(listener).listen(8080);


ここでの問題は、プログラムがユーザーから読み取る backuptypeパラメーターを、その存在を除いて検証しないことです。シェルが呼び出されると、複数のコマンドの実行が許可され、アプリケーションの特性により、データベースとの対話に必要な権限を使用して実行されるので、攻撃者が挿入する任意のコマンドもそれらの権限を使用して実行されることになります。

例 3: 次のコードは、ユーザーがシステムのパスワードを更新できるインターフェイスを提供する Web アプリケーションのものです。特定のネットワーク環境でパスワードを更新する処理には、/var/yp ディレクトリでの make コマンドの実行が含まれます。


...
require('child_process').exec("make", function(error, stdout, stderr){
...
});
...


ここでの問題は、プログラムが make の絶対パスを指定しておらず、child_process.exec() の呼び出しを実行する前に環境をクリーニングできないことです。攻撃者が $PATH 変数を変更して、make という名前の悪意あるバイナリを参照させ、攻撃者の環境でプログラムが実行されるようにすると、本来のバイナリでなく悪意あるバイナリがロードされます。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の make もその権限で実行されるため、攻撃者がシステムを完全に制御してしまう可能性があります。
desc.dataflow.javascript.command_injection
Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。

2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: システムユーティリティの次のコードでは、システムプロパティ APPHOME を使用してインストール先ディレクトリが決定され、指定されたディレクトリからの相対パスに基づいて初期化スクリプトが実行されます。


...
$home = $_ENV['APPHOME'];
$cmd = $home . $INITCMD;
system(cmd);
...
Example 1 のコードでは、悪意ある INITCMD を含んだ別のパスを参照するようにシステムプロパティ APPHOME を変更することにより、攻撃者はアプリケーションの任意のコマンドを昇格した権限で実行できます。このプログラムは環境から読み取った値の検証を行わないので、システムプロパティ APPHOME の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。

例 2: 次のコードは、ユーザーが rman ユーティリティに対するバッチファイルラッパーを使用して Oracle データベースのバックアップを開始し、その後 cleanup.bat スクリプトを実行して一部のテンポラリ ファイルを削除できるインターフェイスを持つ Web アプリケーションのものです。スクリプト rmanDB.bat は、実行するバックアップのタイプを指定するコマンドライン パラメーターを 1 つ受け取ります。データベースへのアクセスが制限されているため、アプリケーションは権限を持つユーザーとしてバックアップを実行します。


...
$btype = $_GET['backuptype'];
$cmd = "cmd.exe /K \"c:\\util\\rmanDB.bat " . $btype . "&&c:\\util\\cleanup.bat\"";
system(cmd);
...


ここでの問題はプログラムがユーザーから読み取る backuptypeパラメーターを検証しないことです。通常、関数 Runtime.exec() は複数のコマンドを実行しませんが、この例のプログラムは最初に cmd.exe シェルを実行して、Runtime.exec() を 1 回コールするだけで複数のコマンドを実行しています。呼び出されたシェルは、2 つのアンパサンドで区切られた複数のコマンドを実行できます。攻撃者が "&& del c:\\dbms\\*.*" という形式の文字列を渡すと、アプリケーションは、プログラムにより指定された他のコマンドとともにこのコマンドを実行します。アプリケーションはその性質上、データベースとのやり取りに必要な権限で実行されています。このため、攻撃者が挿入したコマンドも、その権限で実行されます。

例 3: 次のコードは、ユーザーがシステムのパスワードを更新できるインターフェイスを提供する Web アプリケーションのものです。特定のネットワーク環境でパスワードを更新する処理には、/var/yp ディレクトリでの make コマンドの実行が含まれます。


...
$result = shell_exec("make");
...


ここでの問題は、プログラムが make のための絶対パスを指定しておらず、Runtime.exec() のコールを実行する前に環境をクリーンにできていないことです。攻撃者が $PATH 変数を変更して、make という名前の悪意あるバイナリを参照させ、攻撃者の環境でプログラムが実行されるようにすると、本来のバイナリでなく悪意あるバイナリがロードされます。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の make もその権限で実行されるため、攻撃者がシステムを完全に制御してしまう可能性があります。
desc.dataflow.php.command_injection
Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。

2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例: 次のコードは、信頼できないデータでコールされた場合、攻撃者によって制御されたシステム コマンドを実行する T-SQL ストアド プロシージャを定義します。


...
CREATE PROCEDURE dbo.listFiles (@path NVARCHAR(200))
AS

DECLARE @cmd NVARCHAR(500)
SET @cmd = 'dir ' + @path

exec xp_cmdshell @cmd

GO
...
References
[1] xp_cmdshell
desc.dataflow.sql.command_injection
Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。

2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: システムユーティリティの次のコードでは、システムプロパティ APPHOME を使用してインストール先ディレクトリが決定され、指定されたディレクトリからの相対パスに基づいて初期化スクリプトが実行されます。


...
home = os.getenv('APPHOME')
cmd = home.join(INITCMD)
os.system(cmd);
...
Example 1 のコードでは、悪意ある INITCMD を含んだ別のパスを参照するようにシステムプロパティ APPHOME を変更することにより、攻撃者はアプリケーションの任意のコマンドを昇格した権限で実行できます。このプログラムは環境から読み取った値の検証を行わないので、システムプロパティ APPHOME の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。

例 2: 次のコードは、ユーザーが rman ユーティリティに対するバッチファイルラッパーを使用して Oracle データベースのバックアップを開始し、その後 cleanup.bat スクリプトを実行して一部のテンポラリ ファイルを削除できるインターフェイスを持つ Web アプリケーションのものです。スクリプト rmanDB.bat は、実行するバックアップのタイプを指定するコマンドライン パラメーターを 1 つ受け取ります。データベースへのアクセスが制限されているため、アプリケーションは権限を持つユーザーとしてバックアップを実行します。


...
btype = req.field('backuptype')
cmd = "cmd.exe /K \"c:\\util\\rmanDB.bat " + btype + "&&c:\\util\\cleanup.bat\""
os.system(cmd);
...


ここでの問題はプログラムがユーザーから読み取る backuptypeパラメーターを検証しないことです。通常、関数 Runtime.exec() は複数のコマンドを実行しませんが、この例のプログラムは最初に cmd.exe シェルを実行して、Runtime.exec() を 1 回コールするだけで複数のコマンドを実行しています。呼び出されたシェルは、2 つのアンパサンドで区切られた複数のコマンドを実行できます。攻撃者が "&& del c:\\dbms\\*.*" という形式の文字列を渡すと、アプリケーションは、プログラムにより指定された他のコマンドとともにこのコマンドを実行します。アプリケーションはその性質上、データベースとのやり取りに必要な権限で実行されています。このため、攻撃者が挿入したコマンドも、その権限で実行されます。

例 3: 次のコードは、ユーザーがシステムのパスワードを更新できるインターフェイスを提供する Web アプリケーションのものです。特定のネットワーク環境でパスワードを更新する処理には、/var/yp ディレクトリでの make コマンドの実行が含まれます。


...
result = os.system("make");
...


ここでの問題は、プログラムが make のための絶対パスを指定しておらず、os.system() のコールを実行する前に環境をクリーンにできていないことです。攻撃者が $PATH 変数を変更して、make という名前の悪意あるバイナリを参照させ、攻撃者の環境でプログラムが実行されるようにすると、本来のバイナリでなく悪意あるバイナリがロードされます。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の make もその権限で実行されるため、攻撃者がシステムを完全に制御してしまう可能性があります。
desc.dataflow.python.command_injection
Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。


2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: システムユーティリティの次のコードでは、システムプロパティ APPHOME を使用してインストール先ディレクトリが決定され、指定されたディレクトリからの相対パスに基づいて初期化スクリプトが実行されます。


...
home = ENV['APPHOME']
cmd = home + INITCMD
Process.spawn(cmd)
...
Example 1 のコードでは、悪意ある INITCMD を含んだ別のパスを参照するようにシステムプロパティ APPHOME を変更することにより、攻撃者はアプリケーションの任意のコマンドを昇格した権限で実行できます。このプログラムは環境から読み取った値の検証を行わないので、システムプロパティ APPHOME の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。

例 2: 次のコードは、ユーザーが rman ユーティリティに対するバッチファイルラッパーを使用して Oracle データベースのバックアップを開始し、その後 cleanup.bat スクリプトを実行して一部のテンポラリ ファイルを削除できるインターフェイスを持つ Web アプリケーションのものです。スクリプト rmanDB.bat は、実行するバックアップのタイプを指定するコマンドライン パラメーターを 1 つ受け取ります。データベースへのアクセスが制限されているため、アプリケーションは権限を持つユーザーとしてバックアップを実行します。


...
btype = req['backuptype']
cmd = "C:\\util\\rmanDB.bat #{btype} &&C:\\util\\cleanup.bat"
spawn(cmd)
...


ここでの問題はプログラムがユーザーから読み取る backuptypeパラメーターを検証しないことです。Kernel.spawn 経由で呼び出されたシェルは、2 つのアンパサンドで区切られた複数のコマンドの実行を許可します。攻撃者が "&& del c:\\dbms\\*.*" という形式の文字列を渡すと、アプリケーションは、プログラムにより指定された他のコマンドとともにこのコマンドを実行します。アプリケーションはその性質上、データベースとのやり取りに必要な権限で実行されています。このため、攻撃者が挿入したコマンドも、その権限で実行されます。

例 3: 次のコードは、ユーザーがシステムのパスワードを更新できるインターフェイスを提供する Web アプリケーションのものです。特定のネットワーク環境でパスワードを更新する処理には、/var/yp ディレクトリでの make コマンドの実行が含まれます。


...
system("make")
...


ここでの問題は、プログラムが make のための絶対パスを指定しておらず、Kernel.system() のコールを実行する前に環境をクリーンにできていないことです。攻撃者が $PATH 変数を変更して、make という名前の悪意あるバイナリを参照させ、攻撃者の環境でプログラムが実行されるようにすると、本来のバイナリでなく悪意あるバイナリがロードされます。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の make もその権限で実行されるため、攻撃者がシステムを完全に制御してしまう可能性があります。
desc.dataflow.ruby.command_injection
Abstract
未検証のユーザー入力を含むコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は主に第 2 のシナリオが懸念されます。攻撃者は環境変数を変更したり、悪意のある実行可能ファイルを検索パスの最初の方に置くことにより、コマンドの意味を変更できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1.攻撃者がアプリケーションの環境を変更する場合。

2.アプリケーションが、絶対パスを指定しないか、実行されるバイナリを検証しないでコマンドを実行する場合。

3.アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例: 次のコードは、ユーザーがシステムのパスワードを更新できるインターフェイスを提供する Web アプリケーションのものです。


def changePassword(username: String, password: String) = Action { request =>
...
s'echo "${password}" | passwd ${username} --stdin'.!
...
}
References
[1] IDS07-J. Sanitize untrusted data passed to the Runtime.exec() method CERT
desc.dataflow.scala.command_injection
Abstract
信頼されていないソースから、またはそのような環境下でコマンドを実行すると、アプリケーションが攻撃者に利用されて悪意のあるコマンドを実行する原因になることがあります。
Explanation
Command Injection の脆弱性には、次の 2 つの形態があります。

- プログラムが実行するコマンドを攻撃者が変更可能である。この場合、攻撃者はコマンドの内容を直接的に制御します。

- コマンドが実行される環境を攻撃者が変更可能である。この場合、攻撃者はコマンドの動作を間接的に制御します。

この場合は 1 つ目の状況が最も懸念されます。攻撃者は実行されるコマンドを制御できる可能性があります。このタイプの Command Injection の脆弱性が発生するのは、次の場合です。

1. 信頼できないソースからアプリケーションにデータが入り込んだ場合。

2. データが、アプリケーションが実行するコマンドを表す文字列 (またはその一部) として使用された場合。

3. アプリケーションがコマンドを実行することにより、本来付与されないはずの権限や機能が攻撃者に与えられた場合。

例 1: システムユーティリティの次のコードでは、システムプロパティ APPHOME を使用してインストール先ディレクトリが決定され、指定されたディレクトリからの相対パスに基づいて初期化スクリプトが実行されます。


...
Dim cmd
Dim home

home = Environ$("AppHome")
cmd = home & initCmd
Shell cmd, vbNormalFocus
...
Example 1 のコードでは、悪意ある INITCMD を含んだ別のパスを参照するようにシステムプロパティ APPHOME を変更することにより、攻撃者はアプリケーションの任意のコマンドを昇格した権限で実行できます。このプログラムは環境から読み取った値の検証を行わないので、システムプロパティ APPHOME の値を制御できれば、攻撃者はアプリケーションを操作して悪意のあるコードを実行させ、システムを支配下に置くことができます。

例 2: 次のコードは、ユーザーが rman ユーティリティに対するバッチファイルラッパーを使用して Oracle データベースのバックアップを開始し、その後 cleanup.bat スクリプトを実行して一部のテンポラリ ファイルを削除できるインターフェイスを持つ Web アプリケーションのものです。スクリプト rmanDB.bat は、実行するバックアップのタイプを指定するコマンドライン パラメーターを 1 つ受け取ります。データベースへのアクセスが制限されているため、アプリケーションは権限を持つユーザーとしてバックアップを実行します。


...
btype = Request.Form("backuptype")
cmd = "cmd.exe /K " & Chr(34) & "c:\util\rmanDB.bat " & btype & "&&c:\util\cleanup.bat" & Chr(34) & ";
Shell cmd, vbNormalFocus
...


ここでの問題はプログラムがユーザーから読み取る backuptypeパラメーターを検証しないことです。呼び出されたシェルは、2 つのアンパサンドで区切られた複数のコマンドを実行できます。攻撃者が "&& del c:\\dbms\\*.*" という形式の文字列を渡すと、アプリケーションは、プログラムにより指定された他のコマンドとともにこのコマンドを実行します。アプリケーションはその性質上、データベースとのやり取りに必要な権限で実行されています。このため、攻撃者が挿入したコマンドも、その権限で実行されます。

例 3: 次のコードは、ユーザーがシステムのパスワードを更新できるインターフェイスを提供する Web アプリケーションのものです。特定のネットワーク環境でパスワードを更新する処理には、/var/yp ディレクトリでの make コマンドの実行が含まれます。


...
$result = shell_exec("make");
...


ここでの問題は、プログラムが make のための絶対パスを指定しておらず、Runtime.exec() のコールを実行する前に環境をクリーンにできていないことです。攻撃者が $PATH 変数を変更して、make という名前の悪意あるバイナリを参照させ、攻撃者の環境でプログラムが実行されるようにすると、本来のバイナリでなく悪意あるバイナリがロードされます。アプリケーションの性質上、このバイナリはシステム操作の実行に必要な権限で実行されます。つまり、攻撃者の make もその権限で実行されるため、攻撃者がシステムを完全に制御してしまう可能性があります。
desc.dataflow.vb.command_injection