Varsayılan macOS güvenliği yanılgısı
“macOS varsayılan olarak zaten güvenlidir” iddiası, işletim sisteminin sunduğu platform yeteneklerini iş istasyonunun gerçek operasyonel duruşuyla karıştırdığı için yanıltıcıdır.
Kutusundan yeni çıkmış bir Mac, güçlü savunma mekanizmalarıyla gelir: System Integrity Protection (SIP) sistem dizinlerini ve NVRAM değişkenlerini kilitler, FileVault APFS konteynerini XTS-AES-128 ile şifreler, Gatekeeper ise kod imzalama ve noter onayını (notarization) zorunlu kılar.
# Temiz bir macOS kurulumunda varsayılan durum
$ csrutil status
System Integrity Protection status: enabled.
$ spctl --status
assessments enabled
$ fdesetup status
FileVault is On.
Ancak bir yazılımcı veya güvenlik mühendisi o makineyi günlük çalışma ortamına dönüştürdüğü anda, varsayılan güvenlik garantileri aşınmaya başlar:
- Homebrew ve Gelen Soket İstisnaları: Geliştirme araçları (yerel Python, Node.js veya Docker servisleri) güvenlik duvarı uyarıları üretir. Zaman içinde geliştirici gelen bağlantılara izin verir;
socketfilterfwkullanıcının çalışma dizinindeki yorumlayıcıları sessizce beyaz listeye ekler. - Paket Filtresi İzinleri: Wireshark veya benzeri bir ağ analiz aracı kurulduğunda sistemde
access_bpfgrubu oluşturulur ve/dev/bpf*izinlerini0660yapan bir LaunchDaemon kurulur. Artık root olmayan standart kullanıcı süreçleri bile parola girmeden yerel arayüzlerdeki şifresiz ağ trafiğini dinleyebilir. - Düz Metin Sır Birikimi: Kabuk profillerinde (
~/.zshrc,~/.bashrc) kritik bulut anahtarları (AWS_SECRET_ACCESS_KEY,OPENAI_API_KEY, GitHub tokenları) birikir. Projelerin kök dizinlerinde veritabanı parolaları içeren ve herkes tarafından okunabilen.envdosyaları unutulur. - Kalıcılık ve İmzasız Yardımcılar: Geliştirici araçları
/Library/LaunchDaemons/ve/Library/PrivilegedHelperTools/dizinlerine arka plan servisleri bırakır. Kaldırılan bir uygulamanın plist dosyası temizlenmezse, dosya sisteminde yetki yükseltmeye (privilege escalation) açık sahipsiz bir daemon kalır.
Bu saldırı yüzeyini harici bir araç kurup ek risk yaratmadan denetlemek, gerilemeleri (drift) izlemek ve iyileştirmek için açık kaynaklı macharden aracını geliştirdik.
macharden’ın 4 denetim alanı
macharden, CIS ve NIST standartlarıyla uyumlu 54 güvenlik kontrolünü dört operasyonel alanda toplar:
| Kategori | Ağırlık Aralığı | Odak Noktaları | Temel Güvenlik Araçları |
|---|---|---|---|
| Hardening | 4 – 10 | Sistem bütünlüğü, çekirdek bayrakları, disk şifreleme, kilit ilkeleri | csrutil, fdesetup, spctl, defaults, bputil |
| Network | 4 – 9 | Uygulama güvenlik duvarı, gizli mod, paket filtresi izinleri, kablosuz | socketfilterfw, /dev/bpf*, ifconfig, awdl0 |
| Persistence | 5 – 8 | Başlangıç öğeleri, arka plan daemon’ları, sudoers, kod imzaları | launchctl, plutil, /Library/LaunchDaemons, codesign |
| Secrets | 5 – 9 | Profil dosyalarındaki anahtarlar, açık .env dosyaları, Keychain kilidi | ~/.zshrc, ~/.docker/config.json, kern.coredump, SSH anahtarları |
Sıfır bağımlılık: yerel araçlar ağır ajanlara karşı
Piyasadaki birçok ticari uç nokta denetim aracı, makineye 150MB’ın üzerinde çalışma zamanı (Electron, Python veya hantal servisler) kurar ve root yetkisiyle çalışır. Bu yaklaşım yeni saldırı yüzeyleri yaratır, Gatekeeper ve TCC onay pencereleri üretir ve gereksiz sistem kaynağı tüketir.
macharden tam tersi bir mimariyle tasarlanmıştır: sıfır harici bağımlılık. Tamamen yerel macOS Zsh yorumlayıcısı ve dahili sistem araçları üzerinden çalışır:
- Dosya ve plist ayrıştırma işlemleri doğrudan
plutilvedefaultsile yapılır. - Kod imzaları ve noter onayları
/usr/bin/codesign -dvile doğrulanır. - Sudoers kuralları, kullanıcı grupları ve ACL izinleri
dseditgroup,stat,awkvesedile analiz edilir.
Bir komutun etkileşimli bir parola veya anahtarlık penceresi açıp terminali kilitlemesini önlemek için macharden, sorguları yerel Perl fork’u kullanan katı bir zaman aşımı sarmalayıcısına alır:
# macharden lib/audit_secrets.sh: Katı zaman aşımı sarmalayıcısı
_sec_run_limited() {
local secs="${1:-5}"
shift
[[ $# -gt 0 ]] || return 1
perl -e '
use strict;
my $timeout = shift @ARGV;
my $pid = fork();
if (!defined $pid) { exit 1 }
if ($pid == 0) {
open(STDIN, "<", "/dev/null") or exit 1;
open(STDERR, ">", "/dev/null");
exec { $ARGV[0] } @ARGV;
exit 127;
}
$SIG{ALRM} = sub {
kill "TERM", $pid;
select(undef, undef, undef, 0.2);
kill "KILL", $pid;
exit 142;
};
alarm $timeout;
waitpid($pid, 0);
exit ($? >> 8);
' "$secs" "$@"
}
Ayrıca kabuk dosyalarında sızmış API anahtarları taranırken, regex motoru yalnızca değişken adını (NAME=***) kaydeder. Gerçek anahtar değerleri bellekte maskelenir; raporlara, terminale veya SARIF çıktılarına asla yazılmaz.
Gerçek iş istasyonunda denetim adımları
Geliştirme için aktif olarak kullanılan bir Apple Silicon iş istasyonunda denetim çalıştırıldığında:
# Tüm alanlarda 54 kontrollük tam denetim çalıştır
macharden audit --json report.json --sarif report.sarif --html report.html
1. Hardening Index ve kategori bazlı görünüm
Motor, kritik kontrollere daha yüksek ağırlık vererek 0% ile 100% arasında ağırlıklı bir Hardening Index (Sıkılaştırma Skoru) hesaplar:
# macOS Security Hardening Audit Report
Hardening Index: 82.2% — GOOD / ACCEPTABLE (Grade: B+)
Total Checks Audited: 50
Passed Checks: 30 (🟢 PASS)
Warnings: 10 (🟡 WARN)
Failed Checks: 2 (🔴 FAIL)
Informational: 5 (🔵 INFO)
Suggestions: 3 (🟣 SUGG)
Earned Points: 235.0 / 286.0
Kategori bazlı sonuçlar, makinenin asıl zayıf noktalarını net bir şekilde gösterir:
Category Posture Breakdown:
Hardening 100.0% [🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩] 🟢 PASS (96.0 / 96.0 pts)
Network 82.0% [🟨🟨🟨🟨🟨🟨🟨🟨⬜⬜] 🟡 WARN (61.5 / 75.0 pts)
Persistence 85.9% [🟩🟩🟩🟩🟩🟩🟩🟩⬜⬜] 🟢 PASS (39.5 / 46.0 pts)
Secrets 55.1% [🟥🟥🟥🟥🟥⬜⬜⬜⬜⬜] 🔴 DEFICIENT (38.0 / 69.0 pts)
Temel işletim sistemi sıkılaştırması (SIP, FileVault, Gatekeeper) tam puan alırken; asıl güvenlik açıkları Network ve Secrets kategorilerinde ortaya çıkmıştır.
2. Geliştirici makinesindeki kritik bulgular
Üretilen uyarı ve hata detayları incelendiğinde tipik geliştirici ortamı zaafları görülür:
Bulgu 1: Güvenlik duvarının Python yorumlayıcılarına izin vermesi (NET-03)
$ sudo /usr/libexec/ApplicationFirewall/socketfilterfw --listapps
# /opt/homebrew/Cellar/[email protected]/3.14.7/.../Python.app (Incoming: ALLOWED)
Geliştirici yerel bir test sunucusu çalıştırırken ekrana gelen uyarıya onay vermiş ve güvenlik duvarı ilgili Python ikilisini kalıcı olarak izinli listeye eklemiştir. Bu durum, yerel bir porta bağlanan herhangi bir betiğin dış ağdan doğrudan bağlantı kabul edebilmesine yol açar.
Bulgu 2: Root yetkisi olmadan paket dinleme izni (NET-04)
$ ls -la /dev/bpf*
crw-rw---- 1 root access_bpf 0x17, 0x00 Nov 9 02:00 /dev/bpf0
Wireshark kullanıcısı access_bpf grubuna eklenmiştir. Bu durum, sisteme sızan yetkisiz bir betiğin sudo parolası olmadan /dev/bpf0 üzerinden ağ trafiğini koklamasına (sniffing) imkan tanır.
Bulgu 3: Kabuk profillerinde düz metin API anahtarları (SEC-01)
🔴 FAIL [SEC-01] Plaintext secrets found in shell profiles (4):
.zshrc:6 (H1_API_TOKEN=***)
.zshrc:24 (DEEPSEEK_API_KEY=***)
.zshrc:28 (HUNT_PX_TOKEN=***)
.zshrc:56 (OPENAI_API_KEY=***)
API anahtarları .zshrc içinde doğrudan export edilmiştir. Kullanıcı izinleriyle çalışan herhangi bir yerel işlem bu anahtarları okuyup dışarı sızdırabilir.
Bulgu 4: Güvensiz Docker kimlik bilgisi dosya izinleri (SEC-11)
$ ls -la ~/.docker/config.json
-rw-r--r-- 1 johndoe staff 342 Nov 3 12:00 ~/.docker/config.json
Docker CLI ayar dosyası 644 (herkese açık okunabilir) izinleriyle durmaktadır. Dosya içindeki base64 kodlu özel kayıt defteri parolaları makinedeki diğer yerel kullanıcılar tarafından okunabilir durumdadır.
3. Etkileşimli Liquid Glass paneli ve SARIF çıktısı
macharden, terminal çıktısına ek olarak sıfır harici kütüphane kullanan bağımsız bir tek dosya HTML5 paneli üretir:
Çıktı aynı zamanda doğrudan OASIS SARIF v2.1.0 formatında (--sarif report.sarif) üretilebilir; bu da GitHub Code Scanning ve CI ardışık düzenlerine sorunsuz entegrasyon sağlar:
{
"version": "2.1.0",
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
"runs": [
{
"tool": {
"driver": {
"name": "macharden",
"version": "1.3.0",
"informationUri": "https://github.com/jankesec/macharden"
}
},
"results": [
{
"ruleId": "SEC-11",
"level": "error",
"message": { "text": "Sensitive credential files have insecure permissions: ~/.docker/config.json (644, expected 600)" }
}
]
}
]
}
Baseline drift takibi: macharden diff
Güvenlik tek seferlik bir yapılandırma değil, sürekli korunması gereken bir durumdur. Yeni yazılımlar yüklendikçe veya ayarlar değiştirildikçe güvenlik duruşunda kaçınılmaz olarak sapmalar (drift) meydana gelir.
macharden, merkezi bir veritabanına gerek duymadan yerel drift analizi sunar:
# 1. İlk güvenli referans durumunu kaydet
macharden audit --json baseline.json
# 2. Daha sonra mevcut durumu denetle ve farkı hesapla
macharden diff baseline.json current.json
Diff motoru iki durum arasındaki değişimleri analiz eder; giderilen eksikleri, yeni gerilemeleri ve skor farkını anında gösterir:
╭─ Baseline Drift Analysis ────────────────────────────────────────────────────╮
│ Baseline: 2026-09-12 18:58:06 (82.2% - Grade: B+) │
│ Current: 2026-11-09 02:45:10 (87.4% - Grade: A-) │
│ Delta: +5.2% (IMPROVED) │
╰──────────────────────────────────────────────────────────────────────────────╯
RESOLVED DEFICIENCIES (2):
🟢 [SEC-11] Cloud and API Credentials File Permissions: FAIL -> PASS
🟢 [NET-03] Firewall Permissive Exceptions: WARN -> PASS
NEW REGRESSIONS (0):
No posture regressions detected.
Otomatik ve kontrollü (dry-run) iyileştirme
Eyleme dönüştürülemeyen denetim raporları yalnızca kafa karışıklığı yaratır. macharden, her kuralı doğrudan çalıştırılabilir somut bir iyileştirme komutuyla eşleştirir.
Sistemde değişiklik yapmadan önce ne yapılacağını görmek için --dry-run bayrağı kullanılabilir:
# Sistem ayarlarını değiştirmeden iyileştirme adımlarını listele
macharden remediate --dry-run
Yukarıda tespit edilen bulgular için üretilen örnek iyileştirme komutları:
# NET-03: Güvenlik duvarındaki tehlikeli Python istisnasını engelle
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --blockapp \
"/opt/homebrew/Cellar/[email protected]/3.14.7/Frameworks/Python.framework/Versions/3.14/Resources/Python.app"
# NET-04: Standart kullanıcının BPF paket dinleme iznini kaldır
sudo dseditgroup -o edit -d johndoe -t user access_bpf 2>/dev/null
sudo chmod 600 /dev/bpf*
# SEC-11: Docker kimlik bilgisi dosya izinlerini kısıtla
chmod 600 ~/.docker/config.json
| Bulgu Kodu | Tehdit Mekanizması | Saldırı Yüzeyi | İyileştirme Primitifi |
|---|---|---|---|
NET-03 | Gelen soket erişimi | Python süreçlerine yetkisiz uzaktan erişim | socketfilterfw --blockapp |
NET-04 | Root dışı BPF erişimi | Yerel ağ trafiğinin yetkisiz dinlenmesi | dseditgroup -d, chmod 600 /dev/bpf* |
PERS-07 | İmzasız yetkili yardımcı | Sahte ikili dosya üzerinden yetki yükseltme | launchctl bootout, imzasız plist temizliği |
SEC-11 | Herkese açık kimlik bilgisi | ~/.docker/config.json dosyasından token hırsızlığı | chmod 600 ~/.docker/config.json |
Kanıt ve sınırlar
Tüm testler ve denetim doğrulamaları Apple Silicon donanımlı (M serisi) macOS 15 (Sequoia) üzerinde yerel olarak yürütülmüştür. SIP, Gatekeeper ve FileVault kontrolleri çekirdek düzeyindeki aktif kuralları yansıtır. macharden işletim sistemi düzeyindeki yapılandırma hatalarını tespit edip iyileştirirken; donanıma bağlı korumalar (Secure Enclave parola ilkeleri ve Recovery Mode MDM kayıtları gibi) etkileşimli kurtarma konsolu veya Mobile Device Management profili gerektirir.
Referanslar
- jankesec, macharden (macOS Security Audit & Hardening Engine): github.com/jankesec/macharden
- Center for Internet Security, CIS Apple macOS Benchmark: cisecurity.org/benchmark/apple_os
- NIST, Security and Privacy Controls for Information Systems and Organizations (SP 800-53 Rev. 5): csrc.nist.gov/pubs/sp/800/53/r5/upd1/final
- MITRE ATT&CK, macOS Enterprise Matrix: attack.mitre.org/matrices/enterprise/macos
Bu teknik not ne kadar güncel?
En son kaynak incelemesi, içerik güncellemesi veya yayın tarihi gösterilmektedir.
Yazar teknik incelemeyi tamamladı. Bu etiket tek başına laboratuvar yeniden üretimi iddiası taşımaz.

