OSコマンドインジェクションとは、ユーザ入力値が適切に検証されていないことにより、Webアプリケーション上でOSコマンドを実行できてしまう脆弱性です。Webアプリケーション開発に使用する言語にはシェル(shell)経由でOSコマンドを呼び出す機能を提供しているものが複数あります。
この、シェルを呼び出す機能を悪用されることで情報漏洩やデータの改ざん、別サーバへの攻撃などさまざまなリスクが考えられます。
大好物の貝に麻痺させる毒を注入し、動きをにぶらせ捕食する。からだが変色しているのは自分の毒にあてられているせいらしい。
ゼイジャッキーとは?
シェルとは、ユーザとカーネルの間に入り、代わりにやり取りを行うプログラムです。
ユーザが入力したコマンドを解釈してカーネルに処理を依頼し、その結果やメッセージなどを渡す機能を持っています。カーネルを包む殻(shell)のように見えることからシェルと呼ばれています。
プログラミング言語にはシェルを経由してOSコマンドを実行できる機能を提供しているものがあります。 一部を表にまとめました。
言語 | 関数・メソッド・記法 |
---|---|
C | system() |
Java | Runtime.getRuntime().exec() |
Python | os.system() , commands.getoutput() , subprocess.call() ※ |
Visual Basic | Shell() |
Node.js | child_process.exec() , child_process.execSync() , ※ |
PHP | shell_exec() , exec() , system() |
Ruby | system() , exec() |
Perl | system() , exec() , open() |
Go | exec.Command().Run() |
※デフォルトの利用ではシェルを経由しませんが、オプションや引数によってシェルを経由します。
上記の関数やメソッドなどにユーザ入力値を渡して処理を実行する際に対策がされていないことで、意図しないコマンド実行が行われる可能性があります。|
、;
やコメントアウト(#や//など)
を使用して本来のコマンドとは別のコマンドを実行させる文字列を入力値として渡し、攻撃を行います。
|
:前のコマンドの出力を、次のコマンドの入力として渡す;
:文の終端や区切りを意味する#,//,--
など:コメントアウト
PHPで作成された応募を受け付ける機能を例に攻撃を実行してみます。
この機能は応募を受け付けたことをユーザに知らせるために、受付完了メールを下記のプログラムで送信します。
//応募したユーザが入力したメールアドレス $mail = $_POST["mail"]; //応募を受け付けたことを知らせるメールのテンプレート $reception_mail = "./reception_mail.txt"; system('sendmail -r gift@present.ubsecure.jp < '.$reception_mail.' '.$mail);
サイトのメールアドレスの入力フォームに、/etc/passwd
を表示するcatコマンドを合わせて入力し、応募ボタンをクリックします。
user@example.com; cat /etc/passwd
入力値を受け取るとsystem関数は下記の値を実行します。
sendmail -r gift@present.ubsecure.jp < ./reception_mail.txt user@example.com; cat /etc/passwd
受付完了メールが送られると同時に、ブラウザに/etc/passwd
の内容が表示されており、システムの内部情報、アカウント管理の情報などが取得できました。
このことから、sendmail
とcat
、2つのコマンドが実行されたことがわかります。
sendmail -r gift@present.ubsecure.jp < ./reception_mail.txt user@example.com
の結果
cat /etc/passwd
の結果
OSコマンドインジェクション攻撃が成立する仕組みとその対策を解説しましたが、この章ではOSコマンドインジェクションの脆弱性に起因して発生した現実世界の事例をいくつかご紹介します。
直近10年間で実際にJVNでOSコマンドインジェクションの脆弱性が存在する可能性があるとして報告された件数です。
年代 | 件数 |
---|---|
2015 | 16件 |
2016 | 40件 |
2017 | 106件 |
2018 | 184件 |
2019 | 335件 |
2020 | 386件 |
2021 | 369件 |
2022 | 467件 |
2023 | 538件 |
2024 | 404件 |
※上記の表はMyJVN APIを利用してCWE識別子を基に統計した件数になります。
JVNDBRSS - JVN iPediaにて公開している脆弱性対策情報の概要
アプリケーションからOSコマンドを直接実行するような実装は避けてください。
多くの場合プログラミング言語標準の関数等を用いることで、シェルを経由してコマンドを実行せずとも同等のことが実現できます。
どうしてもOSコマンドを実行する必要がある場合は、Webアプリケーションの実行権限レベルを最小限に留めるよう設定し、次の対策も実施してください。
ユーザ入力値を検証してください。検証方法には、「ホワイトリスト方式」を推奨します。「ホワイトリスト方式」とは、引数に対して使用しても良いと判断した文字の組み合わせのみを定義したリストを使用する方式です。リストに当てはまらないものが確認された場合は、処理を中止します。
OSコマンドインジェクションの脆弱性が存在していると、シェルを呼び出す機能を悪用されることで情報漏洩やデータの改ざん、別サーバへの攻撃などが可能になります。
こういった被害を防ぐために、設計段階からシェルを起動する機能を避け、脆弱性診断を行い、安全な状態になっているかを確認することを推奨します。