Genieは、Netflixによって開発されオープンソース化された、ビッグデータ処理用のジョブオーケストレーションエンジンだ。
Hadoop、Pig、Hive、Spark、Presto、Sqoopなどの様々なビッグデータジョブを実行するためのREST-ful API(アプリケーションプログラミングインタフェース)を提供している。また、多くの分散処理クラスタのメタデータや、それらで実行されるコマンドやアプリケーションを管理するためのAPIも提供している。
エンドユーザの視点から見ると、Genieが様々な計算資源(YARN、Presto、Mesosクラスタなど)を一時的な可能性のある資源も含めて物理的な詳細を抽象化してくれるのだ。そして、これらのクラスタでジョブを送信したり監視するためのAPIが提供されるので、ユーザは自分でクライアントをインストールしたり、各クラスタの構成やコマンドの詳細を知る必要がない。
Contrast Assessは、脆弱性を絶えず検出して優先順位付けをし、開発担当がリスクを取り除くことができるよう導く、IAST(インタラクティブアプリケーションセキュリティテスト)ソリューションだ。弊社はContrast Assessを使用して行った調査の一環として、先日Genieの脆弱性を発見した。
Contrastが2023夏 G2 Grid® ReportのIAST部門でNo.1リーダーと評価され、満足度スコアは100点満点中93点を獲得、レポートのダウンロードはこちら
具体的には、オープンソース版のGenieにパストラバーサルの脆弱性(ディレクトリトラバーサルとも呼ばれる)があり、攻撃者がこれを利用してリモートコード実行(RCE)を行う可能性があった。 このような攻撃が成功すると、Webアプリケーションが操作されて、アプリケーションやWebサーバのドキュメントルートディレクトリ以外のファイルの内容を読み取られる。その結果、バックエンドシステムの認証情報、 アプリケーションコードやデータ、機密性の高いオペレーティングシステムファイルなどが公開される可能性がある。
この脆弱性は「CVE-2024-4701」として指定され、CVSSの深刻度評価基準は10点中9.9点で「緊急(Critical)」に分類されている。重要なのは、この問題はNetflixのいかなる製品やサービス、またNetflix自体の社内のGenieサービスには影響しなかったことだ。しかし、他のGenieユーザは影響を受けた可能性がある。Netflixが自社で使用していたのと同じような対策を講じておらず、影響を受けるファイルアップロードを保存するためにローカルファイルシステムを使用しているインスタンスがある場合は、影響があったかもしれない。Genieのインスタンスが、これらのファイルのアップロードを保存するためにローカルファイルシステムを使用していない(例えば、ストレージにAWS S3を使用している)場合、脆弱性は発生しない。
Genieのパストラバーサルの脆弱性
Contrast Assessで検出
この問題は、別の研究者のjmoritzc53が独自にContrast Assessを使用してGenieアプリケーションを検査することで発見され、これもNetflixに非公開で報告されている。
Contrast Protectでブロック
Contrast Protectを有効にすると、攻撃は正常にブロックされて、ユーザに通知される。ContrastのGenieインスタンスでは、Contrast Protectを有効にしており、パストラバーサル攻撃はブロックされた。なお、NetflixはContrast Protectのユーザではなく、提携もしていない。
Contrast Protectは、ContrastのRASP(Runtime Application Self Protection)テクノロジである。これは、防御の最前線となる他ツールを迂回するようなロジックの欠陥やゼロデイを悪用した攻撃を阻止することで、実行中のアプリケーションとAPIを保護するソリューションだ。
Contrast Protectは、多くの脆弱性が知られる前から攻撃を事前にブロックしていることに注目してほしい。それは、例えばLog4Shellや以下のゼロディリストに見られるものだ:
CVE-2023-22527 Atlassian Confluence – テンプレートインジェクション
CVE-2023-34040 Spring/Kafka – 安全でないデシリアライズ
CVE-2023-22965 Spring4Shell – 悪意のあるデータバインド
CVE-2021-44228 Log4Shell – JNDIインジェクションによるリモートコード実行
CVE-2021-26084 Atlassian ConfluenceのELインジェクション
CVE-2020-17530 Apache Struts2 – ELインジェクション
CVE-2020-11651 Python Salt – 認証回避
CVE-2020-11652 Python Salt – ディレクトリトラバーサル
CVE-2020-9484 Apache Tomcat – 安全でないデシリアライズ
CVE-2019-2725 WebLogic – 安全でないデシリアライズ
CVE-2019-0230 Apache Struts2 – ELインジェクション
CVE-2018-11776 Apache Struts2 – ELインジェクション
CVE-2016-0792 Jenkins XStream – 安全でないデシリアライズ
Contrast Protectは、信頼できない入力(ファイルやファイルのJSON マニフェストなど)が、適切なサニタイズ無しに危険な関数(ホストファイルシステムへのファイルの格納など)に渡されるような実行動作を探すことで、これを実現する。
Contrast Protectは、バージョン6.5.0以降、CVE-2024-4701のパストラバーサル攻撃をブロックできる。
日常的に使用するアプリケーションやライブラリに潜む数多くの脆弱性
今回のケースでは、この脆弱性が攻撃されたという形跡はなかったが、多くの場合、脆弱性が最初に知られるのは、ゼロデイ攻撃で悪用されたときだ。最も堅牢な検知と最も迅速な対策を組み合わせても、ハッキングされる可能性は残されており、ほとんどの企業は「最も堅牢」で 「最も迅速」なものコストをかける余裕がない。Contrast Protectを使用すれば、このようなのアプリケーションやライブラリの使用は事前に保護され、攻撃にさらされる期間は存在しなくなる。
脆弱性の説明
Genieアプリケーション内にはREST APIがあり様々な機能が提供されているが、特にSpark SQLを使用してSQLクエリを送信できることに注目する。この処理の一環として、実行するSQLが含まれるSQLファイルをアップロードすることができる。
このアップロードは、以下のHTTPリクエストに示されるように、マルチパート形式のファイルアップロードを使用して行われる:
上記のHTTPリクエストでは、query.sqlとquery2.sqlという名前の2つのファイルがアップロードされ、リクエストの先頭にあるJSONで指定されたジョブとして実行される。
しかし、このfilenameパラメータが、以下でのパストラバーサル攻撃に対して脆弱だった:
genie/genie-web/src/main/java/com/netflix/genie/web/services/impl/LocalFileSystemAttachmentServiceImpl.java at 99cd72286b6fc813d87afc379dd8a83450391368 · Netflix/genie
アップロードされたファイルがディスクに書き込まれる際のコードを見てみよう:
ここで、attachmentPathはアップロードされたファイルの送信先のパスで、 /tmp/genie/attachments/{uuid}/である。
このuuidはリクエストごとに生成され、一意なディレクトリパスとなる。
上記のリクエストの場合、パスは以下となる:
/tmp/genie/attachments/{uuid}/query.sql
しかし、HTTPリクエストのfilenameパラメータを
../../../../../root/query.sqlに変更すると、
ファイルは、次に示すように/root/query.sqlにアップロードされることになる:
つまり、本来想定していたアップロード先から抜け出すことができ、その結果、パストラバーサルを悪用してRCEを実行できる可能性があるということだ。
パストラバーサルを悪用してRCE
そこで、Genieアプリのファイルシステムにファイルをアップロードすることができるのだが、それで何ができるのか?
その答えとして、ファイルアップロードには次のような制限がある:
- アップロードできるのは、Webサーバがアクセスできる場所のみである。幸いなことに、ここではgenieドキュメントのdocker-composeを使用している。この場合、Genieアプリケーションはrootとして実行されるため、問題はない。
- 新しいファイルのみを作成できる。既存のファイルを上書きすることはできない。
これらの条件を使って、共有オブジェクトファイル/tmp/pe.soをアップロードすることができる。
この共有オブジェクトには以下のコードが含まれている:
これは …
- ld.so.preload のリンクを解除して(詳細は後述)、
- 標準出力に「HACK HACK HACK」と出力し、
- コードが実行されたことを証明するために、bash コマンドを実行して、新しいファイルを作成する。
これを試したい場合は、以下の方法でコンパイルできる:
gcc -fPIC -shared -o pe.so pe.c -nostartfiles
完了すると、pe.soファイルが作成される。このファイルは、実行時に複数のコンピュータプログラムや他のライブラリによって使用されるように設計された実行可能コードを含む共有オブジェクト(つまり、コンピュータファイル)だ。
pe.soファイルは、上記の脆弱性を利用して、ファイルシステム上の任意の場所にアップロードする。
共有オブジェクトを実行
共有オブジェクトをアップロードしたら、それを実行する必要がある。
そのために、別のファイルを/etc/ld.so.preloadにアップロードする。
このファイルには、“/tmp/pe.so”を含めるだけだ。
ld.so.preloadファイルは(存在する場合)、ld.soの実行中に読み込まれる。ld.soは、動的リンクで他のどのプログラムよりも前に実行される。この動的リンクは、他のプログラムが実行される前に、そのプログラムが必要とする共有ライブラリもロードする。つまり、ld.soは、ld.so.preload内の全てプログラムと同様に、他のどのプログラムよりも先に実行される。
これを利用すれば、悪意のある共有オブジェクトとファイルの両方をアップロードして、次にプログラムが起動したときに実行されるようになる。
そして、GenieアプリOSでは …
… ペイロードが、Genieに送信される前は、/tmp/ にはpe.soファイルもcommand.outファイルも含まれていないことが分かる。
アップロード後、ホストで次に実行されたコマンドはlsだ。これにより、ld.so が起動されて、pe.soライブラリ内のコードも実行され、「HACK HACK HACK」というテキストがターミナルに出力され、ファイルがディスクに書き込まれる。
デモ
Netflixがこの問題を解決する前、この攻撃は以下の手順で再現できた:
- genieのdockerファイルを以下よりダウンロード:
https://netflix.github.io/genie/docs/4.3.0/demo/docker-compose.yml
- 以下を実行:
docker-compose up
- 攻撃ペイロードのサンプルを以下よりダウンロード:
loadlib
- 以下のコマンドを実行:
nc -w 5 localhost 8080 < loadlib
これにより、dockerで実行されているgenieアプリにペイロードが送信され、pe.soファイルとld.so.uploadファイルがアップロードされる。
- 次に、genie-appのdockerコンテナにログイン:
docker exec -it genie_demo_app_4.3.0 /bin/bash
- ログインすると、悪意のあるライブラリが実行されることになる。
- 以下を実行:
ls /tmp/
command.outというファイルがディスクに書き込まれているかを確認する。
現在の状況
Bugcrowdを通じて、この脆弱性をNetflixに届け出た。Netflixは、このパストラバーサルを修正し、セキュリティアドバイザリをリリースした。パストラバーサルの問題は、Genie OSS v4.3.18で修正されている。この問題は、#1216と#1217で修正され、修正を含む新しいリリースが作成された。Netflixは、Genie OSSインスタンスを新しいバージョンにアップグレードするようユーザに呼びかけている。
Netflixは、私の報告がパストラーバサルに関する以前の報告と重複していたにもかかわらず、私に250ドルを与えるという異例の措置をとった。
Contrastユーザは心配の必要がなかった
Contrast Assessによって、弊社独自の検査中にこのパストラバーサルの脆弱性が検出されたが、Contrast Protect(バージョン6.5.0以降)によって、弊社のGenieインスタンスへの攻撃はブロックされた。
Contrast Assessでカスタムコードやサードパーティライブラリの脆弱性を検出する方法や、実行中のアプリケーションを保護する方法については、是非デモをリクエストして欲しい。Contrast Securityのアプリケーションセキュリティ(AppSec)へのアプローチは、脆弱性のクラス全体を排除するように設計されているので、その方法をお見せしよう。
パストラバーサル脆弱性についての詳細は、用語集を参照のこと:
関連記事/サイト: