漏洞详细信息
CVE-2023-40713 漏洞
受影响的版本:2.0.65 (11)
Impact: 权限提升
CVSS:7.8 — 高
安装GOG Galaxy后,它会在/Library/LaunchDaemons目录中创建一个名为com.galaxy.ClientService.plist的新文件。此行为会导致创建启动守护程序,该守护程序是以高权限运行的后台进程。通常,这些进程用作帮助工具,由低特权应用程序执行特权操作。
检查GOG Galaxy创建的PLIST文件,显示名为com.gog.galaxy.ClientService的XPC服务由位于/Library/PrivilegedHelperTools/com.gog.galaxy.ClientService中的特权助手工具公开。
这些在下面的 PLIST 文件的内容中突出显示:
?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN”
“http://www.apple.com/DTDs/PropertyList-1.0.dtd”>
<plist version=”1.0″>
<dict>
<key>Label</key>
<string>com.gog.galaxy.ClientService</string>
<key>MachServices</key>
<dict>
<key>com.gog.galaxy.ClientService</key>
<true/>
</dict>
<key>Program</key>
<string>/Library/PrivilegedHelperTools/com.gog.galaxy.ClientService<
/string>
<key>ProgramArguments</key>
<array>
<string>/Library/PrivilegedHelperTools/com.gog.galaxy.ClientService</string>
</array>
</dict>
</plist>
XPC服务快速介绍
XPC 服务是 macOS 中大量使用的进程间通信机制。它允许您创建可以代表应用程序执行某些任务的帮助程序工具。这通常用于在后台运行的任务或需要提升权限的任务。它通常由充当服务器的 XPC 服务和连接到 XPC 服务的应用程序组成。
下图显示了应用程序与 XPC 服务之间的连接:
我不会详细介绍 XPC,因为它是一个复杂的主题,但只是把它看作是通常的进程间通信,客户端可以调用 XPC 服务公开的方法。
GOG Galaxy中的连接验证
调用以高权限运行的服务公开的方法的能力听起来是个坏主意。应用程序只需连接到 XPC 服务,调用公开的方法,并代表 XPC 服务执行操作。尽管这是可能的,但大多数应用程序会验证客户端应用程序,并且只允许特定应用程序调用公开的方法。
例如,在GOG Galaxy Privileged Helper工具中,负责检查连接是否有效的函数(shouldAcceptNewConnection)如下所示:
-(char)listener:(void *)arg2 shouldAcceptNewConnection:(void *)arg3 {
r14 = self;
rax = [arg3 retain];
r15 = rax;
if ([r14 areRequirementsValidForProcessId:[rax processIdentifier]] !=
0x0) {
rax = [NSXPCInterface
interfaceWithProtocol:@protocol(ClientServiceProtocol)];
rax = [rax retain];
[r15 setExportedInterface:rax];
[rax release];
[r15 setExportedObject:r14];
rbx = 0x1;
[r15 resume];
[REDACTED]
应用程序使用 processIdentifier 参数调用 areRequirementsValidForProcessId 函数,该参数是连接进程的 PID。如果此函数返回 0,它将导出对象并允许连接,否则将退出。
查看 areRequirementsValidForProcessId 函数,它将 processID 接收为参数,使用 PID 复制进程的安全属性,并根据以下安全要求检查它们:
[REDACTED]
void galaxy::service_library::Logger::Info
signature of calling process at path {}.”, 0x33);
rax = SecRequirementCreateWithString(@”identifier ”com.gog.galaxy” and
anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /*
exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */
and certificate leaf[subject.OU] = ”9WS36Q8886”“, 0x0, &var_48);
[REDACTED]
安全检查本身是有效的,因为它会检查软件包标识符是否为 com.gog.galaxy,认证是否为有效的 Apple 证书,以及团队标识符是否为 9WS36Q8886(这是 GOG Galaxy 的团队标识符)。
PID重用问题
之所以存在这个问题,是因为所有这些检查都是针对不安全的 PID 执行的。在 macOS 中,PID 可以重用,我们甚至可以在保留旧 PID 的同时,用 posix_spawn() 将当前的可执行文件替换为不同的进程。本文最初发表在Warcon 18的演示文稿中,不要相信PID(PDF)。
此攻击基于竞争条件,即漏洞利用将向 XPC 服务发送多条消息,然后使用满足所有安全要求的二进制文件执行posix_spawn以替换恶意二进制 PID。通过对大量消息进行排队,消息处理和进程验证之间的时间将允许漏洞利用将漏洞利用 PID 替换为验证连接的真实应用程序。
下图显示了攻击的图形表示形式:
特权帮助程序工具的公开方法
尽管我们可以操作特权帮助程序并调用任何公开的方法,但除非这些方法提供了利用机会,否则它没有用。XPC 服务和客户端之间使用的协议称为 ClientServiceProtocol。
此协议公开了以下方法:
– (void)requestShutdown; – (void)removeOldClientService;
– (void)fillProcessInformationForPids:(NSArray *)arg1 authorization: (NSData
*)arg2 withReply:(void (^)(NSArray *))arg3;
– (void)createFolderAtPath:(NSString *)arg1 authorization:(NSData *)arg2
withReply:(void (^)(NSError *))arg3;
– (void)renameClientBundleAtPath:(NSString *)arg1 withReply:(void (^)
(NSError *))arg2;
– (void)changeFolderPermissionsAtPath:(NSString *)arg1 authorization:
(NSData *)arg2 withReply:(void (^)(NSError *))arg3;
– (void)getVersionWithReply:(void (^)(NSString *))arg1;
虽然公开了多个方法,但最有趣的方法是 changeFolderPermissionsAtPath,它需要三个参数。
Arg1 – 授权数据
Arg2 – 将权限更改为
Arg3 – 响应数组
该函数首先检查授权数据,这些数据可以通过创建没有任何权限的授权结构来绕过。检查授权后,该函数会执行各种操作,但最重要的是调用 chmod 函数。chmod 函数是使用 arg2 和 0x1ff 中提供的路径调用的,这使得任何目标文件都是全局可读、可写和可执行的。
-(void)changeFolderPermissionsAtPath:(void *)arg2 authorization:(void *)arg3
withReply:(void *)arg4 {
r13 = [arg2 retain];
r14 = [arg3 retain];
var_C8 = [arg4 retain];
rax = objc_retainAutorelease(r13); <—- RAX is initated from r13, which
is initiated from arg2
var_F8 = rax;
[REDACTED]
rax = [NSFileManager defaultManager];
rax = [rax retain];
r13 = rax;
var_E8 = [[rax subpathsAtPath:var_F8] retain];
rax = objc_retainAutorelease(var_F8);
var_E0 = rax;
rax = [rax UTF8String];
rax = chmod(rax, 0x1ff); <— Permissions are changed using chmod
var_B4 = rax;
if (rax == 0x0) goto loc_1000c1be9;
[REDACTED]
作为低权限用户,我们可以与XPC服务进行通信,并更改系统中任何文件的权限。这可用于以多种方式滥用系统,例如通过修改启动守护程序以在加载守护程序时执行恶意二进制文件。但是,此方法需要重新启动,因此更好的替代方法是修改 /etc/pam.d/login 文件。
/etc/pam.d/login 文件是 macOS 上可插入身份验证模块 (PAM) 系统的配置文件。它包含使用 PAM 的所有服务的默认身份验证配置。修改身份验证条目以使用 pam_permit.so 模块将允许任何身份验证尝试成功。这意味着我们将能够在目标计算机上运行 sudo,而无需输入密码。
源文件:
sh-3.2# cat /etc/pam.d/login
# login: auth account password session
auth optional pam_krb5.so use_kcminit
auth optional pam_ntlm.so try_first_pass
auth optional pam_mount.so try_first_pass
auth required pam_opendirectory.so try_first_pass
account required pam_nologin.so
account required pam_opendirectory.so
password required pam_opendirectory.so
session required pam_launchd.so
session required pam_uwtmp.so
session optional pam_mount.so
sh-3.2#
替换文件:
sh-3.2# cat /etc/pam.d/login
# login: auth account password session
auth optional pam_permit.so
auth optional pam_permit.so
auth optional pam_permit.so
auth required pam_permit.so
account required pam_nologin.so
account required pam_opendirectory.so
password required pam_opendirectory.so
session required pam_launchd.so
session required pam_uwtmp.so
session optional pam_mount.so
sh-3.2#
漏洞利用步骤
以下是成功利用此漏洞所需的步骤:
通过分叉进程连接到 XPC,并将子进程替换为合法的二进制文件。
调用 XPC 公开的 changeFolderPermissionsAtPath 方法,修改 /etc/pam.d/login 文件的权限。将登录文件替换为允许无密码身份验证的文件。升级到运行 sudo su 的 root。
我们选择不发布此漏洞的攻击代码,因为它仍然是 0 天。但是,我们提供了重现该漏洞所需的所有信息。
原文始发于微信公众号(若水实验室):cve-2023-40713
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论