CVE-2023-42942:xpcroleaccountd Root 权限升级

admin 2024年3月3日21:45:28评论18 views字数 4162阅读13分52秒阅读模式
大约两周前,苹果在安全通报中发布了CVE-2023-42942。这是系统服务xpcroleaccountd中存在的竞争条件问题,可利用该问题进行 root 权限提升。今天,我将分享详细信息。

CVE-2023-42942:xpcroleaccountd Root 权限升级

关于 xpcroleaccountd

系统服务/usr/libexec/xpcroleaccountd以 root 身份运行,并具有以下权限:

[Key] com.apple.private.xpc.launchd.ios-system-session  [Value]    [Bool] true  [Key] com.apple.rootless.storage.RoleAccountStaging  [Value]    [Bool] true  [Key] com.apple.security.exception.files.absolute-path.read-only  [Value]    [Array]      [String] /private/var/preferences/com.apple.security.xpc.plist  [Key] com.apple.security.exception.files.absolute-path.read-write  [Value]    [Array]      [String] /private/var/db/com.apple.xpc.roleaccountd.staging/      [String] /private/var/MobileSoftwareUpdate/com.apple.xpc.roleaccountd.staging/  [Key] platform-application  [Value]    [Bool] true  [Key] seatbelt-profiles  [Value]    [Array]      [String] temporary-sandbox

请注意,它能够访问SIP 保护的目录/private/var/db/com.apple.xpc.roleaccountd.staging

/private/var/db/com.apple.xpc.roleaccountd.stagin

有一些特殊的Apple 签名的XPC 服务,它们 在Info.plist文件中定义“_RoleAccount”=>“root”

/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/XPCServices/com.apple.dt.Xcode.XcodeSelectXPCService.xpc/Contents/Info.plist:
...  "XPCService" => {    "_AllowedClients" => [      0 => " identifier = com.apple.dt.Xcode and (anchor apple or (anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9]) or (anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9.1]))"    ]    "_RoleAccount" => "root"    "ServiceType" => "Application"  }...

当我们尝试与此类 XPC 服务进行通信时,xpcroleaccountd将帮助将XPC 服务包复制/暂存到受SIP 保护的位置,然后从受信任的位置以 root 权限安全地启动 XPC 服务包。

通过逆向,我发现xpcroleaccountd的逻辑很简单:

  1. 如果特殊的 XPC 服务捆绑来自系统本身,并且捆绑路径受 SIP 保护/可信,则它会成功回复。(直接用root权限启动)

  2. 如果不是第一次启动特殊XPC服务,则相应的XPC包已经复制到SIP保护位置/private/var/db/com.apple.xpc.roleaccountd.staging/exec/bundleID.size.blocks[-relaxed].xpc,则回复成功。(从受信任的缓存位置以 root 权限启动)

  3. 否则,就是第一次启动。它将首先将特殊的 XPC 包复制到受信任的临时位置/private/var/db/com.apple.xpc.roleaccountd.staging/tmp/uuid

CVE-2023-42942:xpcroleaccountd Root 权限升级

接下来,它将从受信任的临时位置检查特殊 XPC 包的签名:

CVE-2023-42942:xpcroleaccountd Root 权限升级

特殊的 XPC 服务包必须经过Apple 签名并具有权利com.apple.private.xpc.role-account

如果无法验证签名,则会回复错误,因此 XPC 捆绑包将不会启动。

一旦通过验证,它将 XPC 包从tmp位置移动/重命名到exec位置,并成功回复。因此,特殊的 XPC 服务将从受信任的执行位置以 root 权限启动。

CVE-2023-42942:xpcroleaccountd Root 权限升级

问题与利用

代码签名验证过程似乎很完美:它首先将 XPC 服务包复制到受信任的临时位置,然后检查那里的签名(使用权利com.apple.private.xpc.role-account)。只有通过签名验证后,XPC服务才会以root权限启动。

从一开始就阻止了我的TOCTOU攻击,因为我无法从 SIP 保护的位置修改 XPC 服务包。

然而,我发现我可以通过符号链接绕过它!

在第 372 行,在将特殊 XPC 捆绑包复制到受信任的临时位置之前,我可以用符号链接替换 XPC 捆绑包源路径。接下来,符号链接已成功复制到受信任位置。结果,它检查签名并通过解析我的符号链接来启动 XPC 包。

以下是我利用这个问题的方法:

  1. 将 Apple 签名的 XPC 服务包放在位置/tmp/com.apple.dt.Xcode.XcodeSelectXPCService.xpc
  2. 向服务包发送空 XPC 消息以触发该问题。
  3. 在xpcroleaccountd调用 API之前copyfile,替换/tmp/com.apple.dt.Xcode.XcodeSelectXPCService.xpc为符号链接,并让符号链接指向原始 Apple 签名的 XPC 包(可写位置)。
  4. 通过签名验证后,使用恶意负载修改XPC包。
  5. 我的恶意 XPC 包将以 root 权限启动。

顺便说一句,为了赢得竞争条件,日志字符串可能是执行某些操作的提示。例如,日志内容“stagingareaforbundle:”表明它将调用API copyfile,现在是替换为符号链接的正确时机。

漏洞代码上传至GitHub仅用于研究目的。

苹果的补丁

该问题已在macOS 14.1中修复:

void handle_xpc_message(void *, void *msg) {...  v70 = copyfile_state_alloc();    copyfile_state_set(v70, 6u, &copyfile_callback); // COPYFILE_STATE_STATUS_CB    v71 = copyfile(from, to, v70, 0xC800Fu);    copyfile_state_free(v70);    if ( v71 ) {       // "pid[%d]: copyfile(3) failed on service: %d, (errno %{errno}d)"       goto EXIT;    }...}

在该copyfile_callback函数中,它将检查目标路径

int copyfile_callback(int what, int stage, copyfile_state_t state, const char *src, const char *dst, void *ctx){  memset(&v11, 170, sizeof(v11));  result = 0LL;  if ( stage == COPYFILE_FINISH )  {    if ( lchown(dst, 0, 0) )    {      v7 = sub_100003DF5();      v8 = (os_log_s *)objc_retainAutoreleasedReturnValue(v7);      if ( os_log_type_enabled(v8, OS_LOG_TYPE_ERROR) )        sub_1000067AF(v8);//"chown(2) failed during copyfile(3): %{errno}d"    }    else if ( lstat_INODE64(dst, &v11) )    {      v9 = sub_100003DF5();      v8 = (os_log_s *)objc_retainAutoreleasedReturnValue(v9);      if ( os_log_type_enabled(v8, OS_LOG_TYPE_ERROR) )        sub_100006746(v8);//"lstat(2) failed during copy: %{errno}d"    }    else    {      result = 0LL;      if ( (v11.st_mode & 0xF000) != 0xA000 )//dst is a symbolic link?        return result;      v10 = sub_100003DF5();      v8 = (os_log_s *)objc_retainAutoreleasedReturnValue(v10);      if ( os_log_type_enabled(v8, OS_LOG_TYPE_ERROR) )        sub_100006712(v8);//"encountered symbolic link during copy"    }    objc_release(v8);    return 2LL;//COPYFILE_QUIT, the entire copy is aborted at this stage.  Any filesystem objects created up to this point will remain.  copyfile() will return -1, but errno will be unmodified.  }  return result;}

如果目标路径是符号链接,copyfile_callback将返回2 (COPYFILE_QUIT),整个复制将在此阶段中止。接下来,copyfile将返回-1,但 errno 将保持不变。最后,xpcroleaccountd退出并回复错误。

原文始发于微信公众号(Ots安全):CVE-2023-42942:xpcroleaccountd Root 权限升级

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月3日21:45:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2023-42942:xpcroleaccountd Root 权限升级http://cn-sec.com/archives/2543450.html

发表评论

匿名网友 填写信息