点击查找:
CVE-2022-42889 可能对广泛的基于 Java 的应用程序构成严重威胁。开发人员在此时可能会提出的重要问题包括:
commons-text?是哪些版本?发布的代码是否包含 commons-text?其中包含哪个版本的库?由于两个因素,回答这些问题可能并不直接:
传递性依赖:虽然 commons-text 可能不在项目的直接依赖列表中,但它可能被其他依赖间接使用。
该库的代码可能不会以独立文件的形式直接出现,而是被打包到其他代码 jar 文件中。
JFrog 发布了一个工具来帮助解决此问题:scan_commons_text_versions。该工具会查找 StringLookupFactory 的类代码(无论包含的 .jar 文件名和 pom.xml 文件的内容如何),并尝试对对象的版本进行指纹识别,以报告包含的 commons-text 版本是否存在漏洞。
commons-text 函数?这个问题适用于开发人员希望验证代码库中对 commons-text 的调用是否可能传递攻击者可控数据的情况。尽管如公告中所讨论的那样,修复漏洞最安全的方式是应用相应的补丁,但在假设 commons-text 未打补丁的情况下,控制并验证潜在影响在许多场景中可能很有价值。
scan_commons_text_calls_jar.py 可以定位 已编译的 .jar 中对漏洞函数的调用,并以每次调用所在的类名和方法名的形式报告发现结果。
commons-text jar 文件,如何快速禁用危险行为?升级仍然是最好的解决方案——此解决方案旨在快速热修补
在 CVE-2022-42889 漏洞的背景下,commons-text 中的 org/apache/commons/text/lookup/ScriptStringLookup 类允许执行可能通过 ${script} 嵌入到从攻击者可控来源接收的字符串中的脚本。因此,调用 ScriptStringLookup.lookup 函数表明该功能已被激活。
我们提供了一个工具 Text4ShellPatch,可以对这一特定调用进行修补,使脚本执行功能无法被利用。应用补丁后,该库将始终执行一个返回警告消息的脚本(而不是可能由攻击者控制的代码)。
类似地,如果 DNS 和 URL 查找被攻击者通过 ${dns} 和 ${url} 控制,它们可以加载不受信任的内容;因此,可以通过修补分别禁用相应的 DnsStringLookup 和 UrlStringLookup 查找,使其返回警告消息。
该补丁可以应用于特定的 jar 文件,可以仅针对 script 查找,也可以针对 script、dns 和 url 以便在应用程序中不使用这些功能时提供更好的保护。
commons-text jar 吗?我们的两个工具共同提供了扫描和修补有漏洞的 commons-text jar 文件的能力。
此 Github 仓库中提供了一个示例 bash 脚本,名为 scan_and_patch.sh。基本上,它使用 scan_commons_text_versions.py 脚本在特定的 root-folder 下查找存在漏洞版本的 commons-text jar 文件,并对其运行 Text4ShellPatch 工具,如下所示。

scan_commons_text_versions.pypython scan_commons_text_versions.py root-folder [-quiet] [-exclude folder1 folder2 ..]
该工具将递归扫描 root_folder 中的 .jar 和 .war 文件;在每个定位到的文件中,工具会查找 StringLookupFactory.class(在每个 .jar 文件中递归查找)。如果至少找到一个该类,工具将尝试对其版本进行指纹识别(包括在补丁和后向移植补丁中发现的一些变体),以报告代码是否存在漏洞。
使用 -quiet 标志时,仅打印版本结论,其他消息(未找到文件/归档文件打开失败/受密码保护的归档文件)将被静默。
-exclude(可选)后出现的文件夹将被跳过。
scan_commons_text_calls_jar.py该工具需要 Python 3 和以下第三方库:jawa、tqdm、easyargs、colorama
pip install -r requirements.txt
默认使用场景:
python scan_commons_text_calls_jar.py root-folder
将递归扫描 root-folder 中的所有 .jar 文件,并针对每个文件打印对 StringSubstitutor/StringLookup 的 lookup/replace/replaceIn 方法的调用位置(类名和方法名)。
该工具可通过以下命令行标志配置为其他使用场景。
text_4_shell_patchjava -jar Text4ShellPatch.jar TARGET_JAR [PATCHING_MODE]
Where TARGET_JAR is the application to patch and PATCHING_MODE is
0 (default): Patch Script lookup
1: Patch Script + DNS + URL lookups
[Note: The original Jar will be kept in the same folder with the .orig.jar extension]
该工具将查找给定的 commons-text jar 中的 org/apache/commons/text/lookup/ScriptStringLookup 类,并将 lookup() 函数的内容替换为一条警告消息并返回函数。因此,新的 ScriptStringLookup 类中将不存在 eval。
它还可以修补 DnsStringLookup 和 URLStringLookup 类,并在将 PATCHING_MODE 选项设置为 1 时禁用 lookup() 函数。
在修补过程中,会生成一个备份文件,路径相同,扩展名为 .orig.jar。
Text4ShellPatch 可以通过 Maven 使用简单的命令进行编辑和编译:
mvn clean assembly:single。它将在 target/ 文件夹中创建一个 Text4ShellPatch.jar 文件。
在替换为补丁后的文件之前,会在原始 jar 的相同位置生成一个备份。备份文件名遵循以下模式:<原始jar名称>_YYYY.MM.DD_HH.mm.ss.orig.jar,其中 YYYY、MM、DD 分别为年、月、日,HH、mm、ss 分别为时、分、秒。
也可以定位 commons-text 的易受攻击版本并自动修补它们,正如下一个问题所回答的那样。
| 标志 | 默认值 | 用途 |
|---|
--class_regex | (.*StringSubstitutor|.*StringLookup) | 所需类名的正则表达式 |
--method_regex | (lookup|replace|replaceIn) | 所需方法名的正则表达式 |
--quickmatch_string | (StringLookup|StringSubstitutor) | 文件分析的预条件:不包含指定正则表达式的 .jar 文件将被忽略 |
--class_existence | 未设置 | 未设置时,查找按正则表达式指定的 类::方法 的调用。设置时,--method_regex 被忽略,工具将查找 jar 中由 --class_regex 指定的类是否存在。 |
--no_quickmatch | 未设置 | 设置时,--quickmatch_string 的值将被忽略,所有 jar 文件都会被分析 |
--caller_block | .*org/apache/commons/text | 如果调用者类匹配此正则表达式,则不会被显示 |