CVE-2025-31931:Android Intel ITT API任意共享库加载漏洞(影响OpenCV <= 4.10)
Intel® Instrumentation and Tracing Technology (ITT)是一个性能分析API,开发者使用它来分析应用程序性能。ITT库支持多个平台,被许多Android应用程序直接或间接使用(例如:通过从OpenCV官网下载的预编译OpenCV Android库)。
Intel安全公告位于:https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-01337.html
发现了一个允许ITT加载任意共享库的漏洞。该共享库可以执行任何操作(执行任意代码、窃取数据等)。幸运的是,利用这个漏洞并不容易(需要通过PC或Shizuku应用获得adb访问权限,因此远程利用应该不可能)。POC可在我的github上找到,但请继续阅读以了解此漏洞。
漏洞背景
OpenCV将所有ITT API文件原样复制到其3rdparty/ittnotify目录中。ITT始终为Android平台构建(无法通过CMake配置禁用):
|
|
任何使用OpenCV 4.10及更早版本的Android应用程序都会受到影响,4.11及更高版本是安全的。OpenCV中没有关于此CVE的警告,因为它们的发布早于此CVE的公布,并且他们意外地修复了这个漏洞(见[此链接]),因为有人想要支持OpenBSD(“3rdparty/ittnotify已经9年没有更新了。为了支持OpenBSD,我建议更新到最新版本v3.25.4”)。
漏洞发现过程
我不是通过源代码审查或模糊测试发现这个漏洞的,而是在对银行内部应用程序进行渗透测试时发现的。他们要求我特别检查他们用于活体检测的第三方库(我们称之为库X),因为他们计划在公共应用程序中使用它。在逆向工程该库时,我发现它使用了dlopen,并且可以加载在/data/local/tmp/com.intel.itt.collector_lib_64中指定的任意库。
易受攻击的旧代码可以在static const char* __itt_get_lib_name(void)函数中看到。首先,它通过连接/data/local/tmp和com.intel.itt.collector_lib_64(对于Android 64位)或com.intel.itt.collector_lib_32(对于Android 32位)来构造一个字符串。然后它将读取文件的内容。
从源代码来看,这段代码将加载任意库并不明显。
当代码编译后反汇编时,这一点更加明显:param1被赋值为__itt_get_lib_name的返回值。
然后它被赋值给pcVar2,接着使用dlopen加载。
您可以通过查看[此提交]来查看修复。他们完全移除了该功能,因此修复是彻底的。
起初我以为这是库X本身的错误,然后在github上搜索后,发现它来自Intel ITT。经过进一步调查,库X并不直接使用ITT库,而是来自他们使用的OpenCV。默认静态链接的OpenCV库是易受攻击的。
去年在向Intel报告此漏洞时遇到了一些小问题后,他们最终接受了它并给了我1500美元。为了节省大家的时间:如果您在他们的开源组件中发现错误,请通过intigriti报告。后来我发现同一家银行的许多其他应用程序也使用了存在相同漏洞的OpenCV。
漏洞利用
为了测试我们是否真的可以加载任意的.so,我尝试从/data/local/tmp加载一个库,但由于SELinux,它不起作用。在阅读了The Mystique exploit (2002)之后,我意识到:如果我们知道路径,android允许从任何应用程序加载共享库。
因此,要进行测试,我们需要:
- 一个易受攻击的应用程序(最早的OpenCV 4.10版本:Camera Preview示例就足够了)
- 包含要加载的动态库的应用程序(利用应用程序,我们需要编写代码),其中
extractNativeLibs设置为true(如果需要了解原因,请参阅我的其他文章)。
安装两个应用程序后,我们需要知道我们的利用应用程序的位置:
|
|
这将打印base.apk的路径,我们只需要将base.apk替换为lib/arm64/lib_cve_2025_3191.so。然后我们使用adb shell创建/data/local/tmp/com.intel.itt.collector_lib_64
|
|
请注意:
- 使用
-n防止文件中有换行符 - 确保路径正确
- 确保文件名完全如上所述(com.intel.itt.collector_lib_64)
简单概念验证(POC)
为了在库加载时执行操作,我们可以编写一个简单的代码:
|
|
如果库被加载,那么我们将使用adb logcat看到"JOE-INJECT Library Loaded"。
更好的POC
我扩展了POC以执行以下操作:
- 获取Android应用程序的当前包名,这是通过读取
/proc/self/cmdline完成的,这样我们就可以确定哪个应用程序是易受攻击的 - 我们希望为任何易受攻击的应用程序报告此情况:我使用了两种方法:通过telegram机器人,和通过Android toast
如果应用程序没有互联网访问权限(例如opencv示例),telegram方法将不起作用,这就是为什么我添加了Toast方法。
POC实现
为了能够显示toast,我们需要使用JNI API。为了能够使用JNI,我们需要访问JNIEnv,而要获取它,我们需要从JavaVM获取。对于API Level 31,我们可以直接使用JNI_GetCreatedJavaVMs(参见[此Stack Overflow问题])。为了在以前的android版本上工作,我们可以使用:
|
|
POC可在此处获取: https://github.com/yohanes/POC-CVE-2025-31931
为了方便任何人测试,您可以在发布选项卡上使用预编译的版本。预编译的版本没有设置telegram API密钥,因此它只会显示一个toast。您可以重新编译库(或十六进制修补.so)以使用您的telegram密钥。
指令:
- 安装应用程序
- 启动应用程序,使用复制按钮复制nativelib文件路径
- 使用adb创建
/data/local/tmp/com.intel.itt.collector_lib_64,将内容填充为我们获得的路径 - 启动测试易受攻击的应用程序,它应该显示一个toast
漏洞影响
此漏洞的影响通常有限,因为利用并不容易,我们需要:
- 通过PC获得adb访问权限,或者获得对Shizuku的访问权限(如果用户安装了此应用,并且我们获得了用户的允许)
- 让库被加载。在我的案例中:直到我们进行面部验证时,库才被加载
但是一旦您可以放置此库,并创建了/data/local/tmp/com.intel.itt.collector_lib_64,那么您突然可以从所有受影响的已安装应用程序中窃取任何数据或运行任意代码(不仅仅是针对单个应用程序)。
在我的案例中,银行认为我的利用具有高严重性,原因如下:
- 我能够注入可以相对轻松绕过其生物识别的任意代码(不需要root手机)
- 我可以绕过其检查各种注入工具/库(如Frida、LSPosed、Zygisk等)的RASP(运行时应用程序自我保护)
- 它可以绕过Play完整性检查
- 它具有持久性(即使在重新安装易受攻击的应用程序后仍然有效,在完整的Android重启后仍然有效)
- 它在任何Android版本中都有效
给漏洞猎人的建议
对于漏洞猎人:有相当多的Android应用程序使用OpenCV。通过安装POC并设置/data/local/tmp/com.intel.itt.collector_lib_64,您只需要等待您使用的某个应用程序加载该库。您可能会为重要的应用程序获得漏洞赏金。如果您确实获得了一些赏金,请考虑帮助我的朋友为她的癌症治疗发起的gofundme。
给开发者的建议
对于开发者:如果您在Android上使用OpenCV,请尽快更新您的OpenCV版本。