Skip to content
KitploitKITPLOIT
ツールブログ
Log in
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095 — Struts2の脆弱性S2-045, S2-055 および Jackson の脆弱性 CVE-2017-7525, CVE-2017-15095 の調査報告 | Kitploit
ツール/GitHubGitHub/secureskytechnology/study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095
脆弱性分析コード分析ウェブアプリケーション悪用論文と研究学習と教育Archived
GitHubsecureskytechnology/study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095

study-struts2-s2-054_055-jackson-cve-2017-7525_cve-2017-15095

Struts2の脆弱性S2-045, S2-055 および Jackson の脆弱性 CVE-2017-7525, CVE-2017-15095 の調査報告

リポジトリを見る
10621148年前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

Struts2の脆弱性S2-054, S2-055 および Jackson の脆弱性 CVE-2017-7525, CVE-2017-15095 の調査報告

要点だけまとめ、読みやすくしたサマリ記事を公開しました。まず概要を知りたい方、あるいはお時間に余裕の無い方におすすめです。

  • SSTtechlog 08 S2-054, S2-055 および jackson-databindの脆弱性 CVE-2017-7525, CVE-2017-15095 について | SST 株式会社セキュアスカイ・テクノロジー
    • https://www.securesky-tech.com/column/techlog/08.html

2017年12月1日にStruts2のセキュリティアップデートが公開されました。 公開前からJackson(Javaで人気のあるJSONライブラリ)の脆弱性が関連している、という話がメーリングリストに流れており、社内システムやツールでJacksonを利用している筆者も具体的にどのような内容か気にしていました。

  • https://lists.apache.org/thread.html/ed74083f2d7187e71ee5ed644c5e45ba58d0792b515d1d1cc28bfadf@%3Cdev.struts.apache.org%3E

実際に公開された内容としては、以下2点のセキュリティ問題が修正されていました。Jacksonのコンポーネントであるjackson-databindの脆弱性が影響しているのはS2-055のみです。

  • S2-055 : https://cwiki.apache.org/confluence/display/WW/S2-055
    • こちらが jackson-databind のCVE-2017-7525に対応した修正になります。
    • Struts側の依存関係でjackson-databindを 2.9.2 にUPしています。これなら、後述のCVE-2017-15095 にも対応しています。
    • https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.5.14.1
  • S2-054 : https://cwiki.apache.org/confluence/display/WW/S2-054
    • こちらはREST pluginでJSON-lib( http://json-lib.sourceforge.net/ )という古いJSONライブラリを使っていたが、DoSの問題が指摘されていたため、Jacksonに変更した修正になります。

REST plugin では、以前からJSON-libを使ったhandlerとJacksonを使ったhandlerが組み込まれていて、利用者側で選べるようになっていたようです。 S2-054ではデフォルトhandlerをJacksonに切り替え、さらにJacksonのバージョンが古かったのを S2-055 で最新にした、というのが今回の修正の全容と思われます。

では一体、CVE-2017-7525はどんな脆弱性なのか?筆者自身が、普段JavaでJSON処理をするときにJacksonを使っていることもあり、12月2, 3の土日を使ってこの問題を調べてみたのが本記事になります。


サンプルコード検証に用いた筆者の環境:

  • OS : Windows 10 Pro 64bit
  • Java : Oracle JDK 1.8.0_92 64bit
  • Groovy : 2.3.1

jackson-databindの脆弱性 CVE-2017-7525 について

Adam Caudill氏のblogで、CVE-2017-7525 の解説が公開されています。

  • https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/

筆者自身の言葉でざっくりまとめると、jackson-databindではJSONをJavaのオブジェクトにマッピングする機能(ObjectMapper クラス)を提供しています。 ここで ObjectMapper.enableDefaultTyping() を呼ぶことにより、JSON中に独自に埋め込んだクラス名でマッピングすることが可能となります。 「入力JSON中からクラス名を指定可能」という時点で嫌な予感を抱いた方もいると思いますが、まさにその悪い予感が的中したのが CVE-2017-7525 となります。

脆弱性の説明に入る前に、そもそもなぜそのような機能が実装されたのか説明します。

ObjectMapper.enableDefaultTyping() 機能について

jackson-databind によるdeserializeの基本的な使い方は次のサンプルコードをご確認ください。(本記事ではJacksonのサンプルコードでGroovyを使っています。@Grab で jackson-databind のバージョンを簡単に切り替えられるのが便利です。)

  • objectmapper-demo.groovy

上記サンプルコードでは単純に"animal" キーがそのまま Animal クラスにマッピング可能です。 では、以下のようなケースではどうでしょうか?

class Zoo {
    Animal animal;
}

abstract class Animal {
    String name;
    protected Animal() { }
}

class Dog extends Animal {
    double barkVolume;
    Dog() { }
}

class Cat extends Animal {
    boolean likesCream;
    int lives;
    Cat() { }
}

この構成では、"animal"のキーの中身がDogクラスを指す場合と、Catクラスを指す場合の2種類が出てきてしまいます。したがって、どちらのクラスでマッピングするのか追加の情報が必要となります。

これを解決するため、jackson-databindではJSONにマッピングするクラス名を埋め込める独自処理を組み込みました。 例えば以下のように、"animal"キーの中身を配列にしてしまい、最初の要素にクラス名を指定します。

{"animal":["Dog",{"name":"dog1","barkVolume":1.2}]}

これにより ObjectMapper.readValue() は "animal" キーの中身が Dog クラスだと認識してマッピングを行います。 もちろん、そのままでは "animal" キーの中身がもともと配列だったのか、jackson-databind独自のクラス名情報が含まれたものなのか、判別できません。 これを切り替えるのが ObjectMapper.enableDefaultTyping() メソッドになります。 他にも @JsonTypeInfo アノテーションをクラスに定義する方法もあります。詳細は以下のJacksonドキュメントを参照してください。

  • JacksonPolymorphicDeserialization
    • https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization

実際に ObjectMapper.enableDefaultTyping() メソッドを使ったサンプルコードを次に示します。

  • enable-default-type-demo.groovy

クラス名のblack list検査による CVE-2017-7525 の対応

以上見てきたように、クラス名に続いてそのプロパティをJSONで与えることで、ある程度制限はあるものの、任意のクラスを任意のプロパティで生成することが可能となります。 これを悪用したのがCVE-2017-7525の脆弱性で、きっかけとなったのは恐らく次のレポートと思われます。

  • Java Unmarshaller Security - Turning your data into code execution
    • https://github.com/mbechler/marshalsec

JacksonなどJavaでよく使われているserialize/deserializeライブラリについて、クラス名などの操作で任意コード実行につながる危険性がレポートされており、実際にどのようなクラスが危険か具体的なクラス名がリストアップされています。

これを受けてのものか分かりませんが、日付的には上記リポジトリの1st commitの直後に、jackson-databind で以下のIssueが立てられ、対応が始まりました。

  • Jackson Deserializer security vulnerability
    • https://github.com/FasterXML/jackson-databind/issues/1599

実際にこの脆弱性を突くようなJSONデータとJavaコードはどのようなものでしょうか? このIssueで対応された jackson-databind 2.8.9 のテストコードにヒントがあります :

  • https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.8.9/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java

このテストコードを元に、動作確認できるよう調整したサンプルコードを次に示します。

  • cve-2017-7525-check.groovy

@Grab で 2.8.9 を指定して実行すると your jackson version IS SAFE to CVE-2017-7525 と表示されます。これは 2.8.9 の修正によりインスタンス化されるクラス名指定でblacklist検査が追加されたことによります。 ここで @Grab に 2.8.8 を指定して実行すると、以下のように出力されます。

your jackson version MAY NOT BE SAFE to CVE-2017-7525
com.fasterxml.jackson.databind.JsonMappingException: N/A
 at [Source:
{
  "id" : 124,
  "obj" : [
    "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
    {
      "transletBytecodes" : [ "AAIAZQ==" ],
      "transletName" : "a.b",
      "outputProperties" : { }
    }
  ]
}
; line: 9, column: 28] (through reference chain: Bean1599["obj"]->com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl["outputProperties"])
        at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:277)
(...)
        at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:128)
Caused by: java.lang.NullPointerException
        at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$1.run(TemplatesImpl.java:401)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.defineTransletClasses(TemplatesImpl.java:399)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:451)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:486)
        at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties(TemplatesImpl.java:507)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.fasterxml.jackson.databind.deser.impl.SetterlessProperty.deserializeAndSet(SetterlessProperty.java:116)
        ... 30 more
null

出力結果中に at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$1.run(TemplatesImpl.java:401) という行があります。 このサンプルコードではNullPointerExceptionがthrowされてしまっていますが、メソッド名的に、いかにも何か副作用を含む処理が発生していることが伺えます。

実際にコード実行を成功させるようなJSONを組み立てるには、さらなる調査が必要と思われます。 本記事では一旦ここまでの紹介に留めますが、さらなる調査記事が他のサイトで公開されれば、こちらにも追記していきたいと思います。

ところで肝心のblack listはどこで実装されているのか?ですが、以下のクラスになります。

  • https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.8.9/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java#L51

実は 2.8.9 の時点ではこのblack listに漏れがあったようです。その問題が、CVE-2017-15095 になります。

black list を改善した CVE-2017-15095 の対応

black list 漏れの改善ですが、まず https://github.com/FasterXML/jackson-databind/issues/1680 で s.add("com.sun.rowset.JdbcRowSetImpl"); が追加されました。 一旦それで 2.9.0 がリリースされた後、さらに https://github.com/FasterXML/jackson-databind/issues/1737 で以下のblack listチェックが追加されてます。

// [databind#1737]; JDK provided
s.add("java.util.logging.FileHandler");
s.add("java.rmi.server.UnicastRemoteObject");
ツールをダウンロード