OS コマンドインジェクション その危険性と対策
OS コマンドインジェクション(OS Command Injection) は、オペレーティングシステムのコマンドを不正に実行できてしまう脆弱性および攻撃手法です。
コマンド注入攻撃、コマンドインジェクションとも呼ばれます。
Web アプリケーションのコードに OS コマンドの呼び出し処理があり、ユーザーが入力したデータがコマンドの一部分を構成している場合に発生します。
本記事では、OS コマンドインジェクション(以下、コマンドインジェクション)の概要と攻撃による影響、対策について解説していきます。
コマンドインジェクションとはなにか
コマンドインジェクションは、攻撃者が Web アプリケーションを通して、Web サーバが動作する OS でコマンドを実行できてしまう脆弱性です。
コマンドインジェクションが起きるまでの流れ
攻撃者は、Cookie やフォームのデータ、URL のクエリパラメーターといった、ユーザーから提供されたデータの一部を使ってオペレーティングシステムコマンドを生成し実行します。
これらの攻撃は、Web アプリケーション内の OS コマンドを生成する部分において、ユーザーから提供されたデータのバリデーション(検証処理)が不十分であることが原因となり、意図しないコマンドが実行できてしまうと成立します。
OS 上で動作している Web サーバは、注入されたコマンドを Web サーバーの権限で実行します。
そのため、Web サーバの実行権限が弱い権限で適切に運用されていれば、コマンドインジェクションの脆弱性自体がシステムの完全な乗っ取りになることはありません。
ただし、攻撃者は Web サーバ内の別な脆弱性を利用して、権限昇格を取得できる可能性があります。
この試みが成功し、サーバーの root 権限が奪取されると、攻撃者はサーバをフルにコントロールすることができてしまいます。
また、Web アプリのサーバーから同一ネットワークで繋がっている別のサーバーにアクセスできる状態になっていると、組織内の他のシステムへの攻撃を仕掛けることも可能になります。
コマンドインジェクションの脆弱性は、特定のプログラミング言語に限定された話ではありません。
OS コマンドを呼び出すことができるすべての言語(Java, PHP, Ruby, Python, Node.js, Go, Scala など)において、コマンドインジェクションが発生する可能性があります。
コマンドインジェクション攻撃を受けると、どのような影響が出るのか
コマンドインジェクションによる攻撃を受けると、サーバ内に保存されているファイルを読み出したり、システムに関係する操作、プログラムを不正に実行することが可能になります。
発生する影響は、軽微なものから破壊的なものまでさまざまです。
以下は攻撃によって起こりえる影響の一例です。
- 情報の漏えい(顧客のデータの読み取り)
- サーバー内にあるファイルへのアクセス・改ざん・削除
- データベースの変更・破壊
- ウィルスなどのマルウェア感染
- サーバー自体の乗っ取り
- DDoS 攻撃の踏み台サーバー化
上記の結果として生じる影響範囲は、組織が実施しているユーザー認証とセキュリティ保護のレベルによります。
コマンドインジェクションの脆弱性を修正したとしても、攻撃者は引き続きシステムへのアクセスができる可能性もあります。
もし攻撃を受けてしまったら
コマンドインジェクション攻撃の影響を受けていることを発見した場合は、一般的には証拠保全のためにサーバを外部と切り離すことが望まれます。
コマンドインジェクションが成功した場合、攻撃者は侵入経路を永続化するためにバックドアを配置している可能性が高く、攻撃者が何をやっていたのか被害状況を明らかにすることは容易ではありません。
そのため、保全したサーバを調査専門家(フォレンジックエンジニア)などの協力を得つつ、被害状況や影響範囲を調査することが望まれます。
被害状況や影響範囲が調査が完了したら、その結果報告に従って適切に対策・復旧する必要があります。
コマンドインジェクションの脆弱性には、どのような対策を行えば良いのか
コマンドインジェクションの脆弱性を防ぐための最も効果的な方法は、Web アプリケーション上のコードから OS コマンドを呼び出さないようにすることです。
ほぼすべてのケースにおいて、より安全なプラットフォーム API やクライアントライブラリを利用することで必要な機能を実装できる方法があります。
また保険的な対策として、侵入を検知する仕組みの構築、問題発生時の影響ができる限り小さくなるような対策を行うことをお勧めします。
OS コマンドを呼び出している実装箇所を洗い出し、現状を把握する
コマンドインジェクションが起きる原因は、ユーザーが入力したデータが、そのまま OS コマンドの一部を構成してしまうことに問題があります。
まずは、Web ブラウザーを通してアクセス可能なすべてのエンドポイントにおいて、OS システムコマンドのユーザー制御可能なデータを含めないようにすることが重要です。
開発チームとセキュリティチームは、意図しないコマンドによるサーバーレベルの処理を実装していないか、確認する必要があるでしょう。
以下で各言語別に実行できるコードの一部をご紹介します。
Web アプリケーションの開発者として、OS コマンドを呼び出す関数やメソッドを使っている箇所については、特に注意が必要です。
言語 |
OSコマンドを呼び出すことができる代表的な関数・メソッド |
---|---|
Java |
Runtime.getRuntime(...).exec(), ProcessBuilder() |
PHP |
exec(), system(), passthru(), shell_exec(), pcntl_exec(), backtick演算子 |
Ruby |
exec(), system(), IO.popen(), backtick演算子 |
Python |
subprocess.call(), os.system() |
Node.js |
child_process.exec(), child_process.spawn() |
Go |
exec.Command().Run() |
Scala |
Process() |
OS コマンドを使わずに実装できる方法を検討する
直接 OS コマンドを実行しなくとも、同等の処理を実現できる API やライブラリがベンダーや OSS で提供されている場合がありますので、利用することを検討してみましょう。
なお、ライブラリー自体にも脆弱性が存在している場合があります。
日々新しく発見される脆弱性に気付ける仕組み作りや、Web アプリで利用しているライブラリを最新版にアップデートし続けていける体制作りも必要です。
yamory のようなオープンソースのライブラリの脆弱性を検出・管理できるツールを導入も検討してみてください。
ユーザーが入力したデータのバリデーションを厳格に行う
OS コマンドの実行を回避する方法が見つからない場合は、ユーザーが入力したデータすべてに対してバリデーションを厳格に行うことが重要です。
繰り返しになりますが、コマンドインジェクションが起きる原因は、ユーザーが入力したデータがそのまま OS コマンドの一部を構成してしまうことにあります。
ホワイトリスト方式で受け付けるデータを限定する(たとえば英数字のみしか受け付けない)バリデーションを必ず実施するようにしてください。
シェルのメタ文字をエスケープして入力をサニタイジングすることは避けるべきでしょう。
完全なサニタイジングは難しく、豊富な経験を持つ攻撃者であれば迂回する方法を見つけてしまう可能性があるためです。
保険的な対策
Web アプリケーションのコードを修正する方針とは別に、保険的な方法として以下のような対策も考えられます。
- 侵入検知システムの導入
- 権限昇格の可能性がある設定の見直し(問題発生時の影響範囲を狭める)
これらを導入することで、万が一問題が発生した際も影響をできる限り小さくでき、異常に気が付ける体制が構築できます。
侵入検知・異常検知としては、Wazuhと呼ばれるOSSツールなどがあります。
これらのツールはシステムに対してスキャンを行うことで、異常なデータ(攻撃に使われるファイルなど)を検知し、サーバに侵入されたことを通知してくれます。
そのため、侵入などが発生した際にすぐさま対処を行うことができ、攻撃の影響を最小化できます。
他にも、権限昇格の可能性がある設定を見つけ、安全な設定へ変更するなどは、コマンドインジェクションの影響を小さくすることに繋がるでしょう。
たとえば LinEnum や、 BeRoot といったツールは、サーバ内の権限昇格に繋がる可能性がある設定を確認してくれます。
さいごに
コマンドインジェクションの脆弱性は、Web アプリケーションの内部に存在するもので、原因と対策も確立されているといえます。
一方で攻撃を受けた場合の対処は、開発チームの範囲にとどまらず、セキュリティチーム、インフラチームにも求められます。
また、情報の漏えいが発生した場合は、ビジネス面においても影響が及ぶため、ビジネスサイド(顧客サポート部門、リスク管理部門、経営層、広報部門など)にも判断や対応が求められることもあり得ます。
さまざまな脆弱性・攻撃手法の中でも影響範囲が大きく、最も注意を払うべき怖い脆弱性のひとつと言えるでしょう。
攻撃はいつ発生するかわかりません。
不測の事態に備えるためにも、普段から各チーム・各部門とコミュニケーションをとり、連携をとれるようにしておくことをお勧めします。
yamory でできること
コマンドインジェクションが OSS ライブラリ内で発生した場合、ライブラリの脆弱性を定期的に集め、精査する必要が出てきます。
パッチ管理は非常に煩雑ですが、セキュアなアプリ開発においては避けては通れない道です。
yamory では、こういった煩雑なライブラリの脆弱性管理を楽にし、セキュアな開発を支援しております。
ぜひ一度お試しいただければ幸いです。