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
漏洞分析代码分析Web应用程序漏洞利用论文与研究学习与教育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 股份有限公司 SecureSky Technology
    • 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

实际发布的内容修复了以下两个安全问题。只有 S2-055 受到 Jackson 组件 jackson-databind 漏洞的影响。

  • S2-055 : https://cwiki.apache.org/confluence/display/WW/S2-055
    • 这是针对 jackson-databind 的 CVE-2017-7525 的修复。
    • Struts 端的依赖项已将 jackson-databind 升级到 2.9.2。这样也对应了后述的 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 插件曾使用名为 JSON-lib ( http://json-lib.sourceforge.net/ ) 的旧版 JSON 库,但由于被指出存在 DoS 问题,因此将其更改为 Jackson 的修复。

REST 插件此前已内置了使用 JSON-lib 的 handler 和使用 Jackson 的 handler,似乎用户可以自行选择。 S2-054 将默认 handler 切换为 Jackson,S2-055 进一步将旧版 Jackson 更新至最新版,这似乎是本次修复的全貌。

那么,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 先生的博客中公开了 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 反序列化的基本使用方法。(本文中的 Jackson 示例代码使用了 Groovy。使用 @Grab 可以方便地切换 jackson-databind 的版本。)

  • objectmapper-demo.groovy

在上述示例代码中,直接可以将 "animal" 键映射到 Animal 类。 那么,在以下情况下又会如何呢?```java 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类两种情况。因此,需要额外的信息来确定具体使用哪个类进行映射。

为了解决这个问题,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,但从方法名来看,可以推测出可能发生了某种含有副作用的过程。  

要构造出能够成功执行代码的JSON,看来还需要进一步调查。  
本文在这里暂且只介绍到这,但如果其他网站发布了进一步调查的文章,我们也会在此处进行补充。  

那么,关键的黑名单是在哪里实现的呢?就是以下这个类。  
* 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版本时,这个黑名单似乎存在遗漏。该问题就是CVE-2017-15095。  

### 改善黑名单的CVE-2017-15095应对  

关于黑名单遗漏的改善,首先在 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 中添加了以下黑名单检查。```java
// [databind#1737]; JDK provided
s.add("java.util.logging.FileHandler");
s.add("java.rmi.server.UnicastRemoteObject");
// [databind#1737]; 3rd party
s.add("org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor");
s.add("org.springframework.beans.factory.config.PropertyPathFactoryBean");
s.add("com.mchange.v2.c3p0.JndiRefForwardingDataSource");
s.add("com.mchange.v2.c3p0.WrapperConnectionPoolDataSource");

こうして 2.8.10 / 2.9.1 がリリースされ、CVE-2017-15095 への対応完了となっています。

2.8.10 でのblack list動作をチェックするテストコード:

  • https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.8.10/src/test/java/com/fasterxml/jackson/databind/interop/IllegalTypesCheckTest.java#L57
下载工具