Spring4Shell:Spring FrameworkのゼロデイRCEを解説
2022年4月1日
0 分で読めます2022年3月30日、Spring Frameworkで重大なリモートコード実行(RCE)の脆弱性が見つかりました。より具体的には、spring-beansパッケージの脆弱性で、spring-webmvcとspring-webfluxの両方に推移的依存関係として含まれています。この脆弱性も、オープンソースにおいてソフトウェアサプライチェーンを保護することが重要である理由を示す例です。
Lunasec、Rapid7、Praetorianなどのセキュリティリソースが、この脆弱性の実在を確認しました。その間にSpringは、この問題を緩和する新しいバージョンをすでにリリースしているため、アップデートを推奨します。Spring4Shellは、最近のLog4Shell脆弱性と同じほどの影響はないようですが、Spring Frameworkを利用するすべての組織が評価し、優先的に対処すべきです。この記事では、RCEの仕組みを解説します。
Spring4Shellを解説
リクエストマッピングがメモリに読み込まれたコントローラーがある場合、すでにこの問題の影響を受ける可能性があります。以下は、GreetingControllerに/greetingへのPostMappingを設定した例です。たとえばTomcat上のアプリケーションをhttp://mydomain/myapp/greetingで呼び出すと、入力をPOJO(Plain Old Java Object)に変換しようとします。この場合、変換先はGreetingオブジェクトです。
しかし、Springは内部でシリアライズを使ってこれらの値をJavaオブジェクトにマッピングするため、ほかの値も設定できてしまいます。調査を進めたところ、クラスのプロパティを設定できることが分かりました。Tomcatを実行している場合、これは重大な問題になります。
この動作を実証するため、クラスのログ関連プロパティを利用してrce.jspファイルを作成する、次のcurlコマンドを使います。
パターンに設定した内容はすべて、ファイルのコンテンツになります。エスケープ処理を工夫し、ヘッダーを利用することで、私たちのチームはTomcatサーバー上に、単純な本文<% out.println(“HACKED”); %>を含むJSPファイルを作成できました。このファイルは/myapp/rce.jspからアクセスできる状態になりました。

Snyk Security ResearchチームのKirill EfimovとAviad Hahamiが作成したPOCの全容は、GitHubで公開されています。
単純なout.printlnを実行できるのであれば、Runtime.exec()を使ってターミナルコマンドを実行し、リバースシェルでアクセスできるJSPファイルも作成できます。また、JSPの機能を使ってWebシェルのインターフェースを作成することも可能です。
ほかの多くのブログで紹介されている同様のエクスプロイトでは、コマンドを実行できるJSPを作成します。このPythonスクリプトは、必要なヘッダーを含む適切なリクエストを生成します。デモアプリケーションでこのスクリプトを実行すると、次のようにwhoamiコマンドを実行できます。[http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami](http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami)。

影響を受けるのは?
状況は現在も急速に変化しているため、現時点で分かっていることをお伝えします。
影響を受けるspring-beansのバージョンでは、JDK 9以降を使用している場合にのみ、この脆弱性が有効になるようです。JDK 9の導入によって、以前から存在する問題CVE-2010-1622が事実上回避されました。
多くのJava開発者がすでにJava 8より後のバージョンに移行していること、そしてSpring Frameworkが広く使われていることから、多くのJavaアプリケーションがこの問題の影響を受ける可能性があると考えられます。
この問題を解決する方法はいくつかあります。Springのメンテナーは、フレームワークの新しいバージョンをリリースしました。最善の対策は、Spring Frameworkを5.3.18または5.2.20にアップデートすることです。当社のセキュリティチームによると、`spring-bean`パッケージだけを最新バージョンに更新すればよいとのことですが、フレームワーク全体を更新するほうが望ましいでしょう。Spring Bootを使用している場合は、リリース2.6.6または2.5.12に、更新済みのSpring Frameworkが組み込まれています。
Springを新しいバージョンにアップデートできない場合は、JavaのバージョンをJava 8にダウングレードする方法もあります。
別の方法として、以下のようにコントローラー内、または独立したControllerAdviceとしてInitBinderを作成できます。
ただし、これは最終的な解決策ではないことに注意してください。このようなブロックリストを作成するのは、望ましいセキュリティ対策とは言えませんが、時間を稼ぐことはできるかもしれません。Spring Frameworkのメンテナーは、ブログ記事で、ほかのすべての初期化が完了した後にRequestMappingHandlerAdapterを作成し、WebDataBinderを更新する方法を推奨しています。
フレームワークやライブラリへの依存
Spring4Shellは、オープンソースのフレームワークやライブラリに大きく依存していることを改めて示しています。しかし、今回や最近のLog4ShellのようなRCE脆弱性が見つかった場合、すぐに緩和策を講じられるよう、状況を把握しておく必要があります。
Snykは、アプリケーションを定期的にスキャンして、こうした脆弱性の把握を支援します。新たな脆弱性が検出されると、Snykがお客様とチームに通知し、アプリケーションを安全に保つための推奨される次のステップを提示します。
最後に、このようなゼロデイ脆弱性は、ライブラリを最新バージョンに保つことの重要性を改めて思い出させてくれます。常に最新の状態であれば、アップデートを適用し、再ビルドして、迅速に再リリースできます。
CTFを始めよう
オンデマンドのバーチャル入門ワークショップを視聴して、CTFの課題の解き方を学びましょう。



