SV.CODE_INJECTION.SHELL_EXEC
コマンド インジェクションの脆弱性
system() 関数または popen() 関数を外部の影響を受ける入力とともに使用する場合、攻撃プロセスの特権を使用して、悪意のあるユーザーは文字列を挿入して任意のコマンドとコードを実行することができます。たとえば、攻撃者はセミコロンを挿入して 1 つのコマンドを終了し、新しい関連のない実行コマンドを挿入することもできます。
脆弱性とリスク
コマンドインジェクションの影響を受けやすい system() 呼び出しまたは popen() 呼び出しは、次のようになることがあります。
- 悪意のあるコードの実行
- 危険にさらされたシステムにアクセスするための新しいユーザーアカウントの作成
- 通常のユーザーより高度な特権レベルの任意のコマンドの実行
最悪の場合は、攻撃者は、ルートパーティションの内容の削除など、システムを制御する文字列を挿入することもできます。
軽減と防止
この指摘を回避するには、次のことを実行するのがベストです。
- システム呼び出しで定数文字列のみを使用
- コマンド実行前に検証コードを追加する
- 外部プロセスではなくライブラリ呼び出しを使用
- ブラックリスト入力検証ではなくホワイトリスト入力検証を使用
- 外部実行プログラムを実行するために関数の exec ファミリーを使用
- ユーザーが外部実行プログラムに書き込むことはできないことを確認
- 既存ライブラリへの呼び出しで機能をプログラムに直接実装
脆弱コード例
コピー
char *constbuf = "bash";
int main()
{
char buf[100];
scanf("%s",buf);
system("echo \"constant string: no warning\"");
system(constbuf);
system(buf);
popen("echo OK","r");
popen(constbuf, "r");
popen(buf, "r");
return 0;
}
この例では、Klocwork は 9 行目で、system() 関数がユーザーによる影響を受ける可能性のあるコマンドラインを受け入れ、これが任意コードの実行を生じることになることを示す指摘レポートを生成します。類似した警告が 12 行目で関数 popen() について報告されています。いずれの場合も、攻撃者がコマンドを挿入して悪意のあるコードを実行し、システムを制御したり、ルートパーティションを削除することもできます。6 行目と 8 行目のシステムの関数呼び出しで、定数文字列およびライブラリ呼び出しを引数として使用するため、それらはコード挿入の可能性に対してオープンではなく、フラグは立てません。
関連チェッカー
外部参考資料
- CERT ENV33-C: system() を呼び出さない
- CWE-20: 不適切な入力検証
- CWE-77: コマンドで使用される特殊要素の不適切な中立化 ('コマンド インジェクション')
- CWE-78: OS コマンド中で使用される特殊要素の不適切な中立化 ('OS コマンドインジェクション')。
- CWE-88: コマンド内の引数区切り文字の不適切な無効化 ('引数インジェクション')
- CWE-94: コード生成の不適切な制御 ('コードインジェクション')
- CWE-99: リソース識別子の不適切な制御 ('リソースインジェクション')
- CWE-400: 制御されていないリソース消費
- OWASP A3:2021 インジェクション
- STIG-ID:APP3570 コマンドインジェクションに影響を受けやすいアプリケーション