macOS IOKit
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Osnovne informacije
I/O Kit je otvorenog koda, objektno-orijentisan okvir za upravljačke programe uređaja u XNU kernelu, koji rukuje dinamički učitavanim drajverima uređaja. Omogućava modularnom kodu da se dodaje u kernel u hodu (on-the-fly), podržavajući raznovrstan hardver.
IOKit drajveri će u suštini izvoziti funkcije iz kernela. Tipovi parametara tih funkcija su predefinisani i verifikovani. Štaviše, slično XPC-u, IOKit je samo još jedan sloj na vrhu Mach messages.
IOKit XNU kernel code je otvorenog koda i Apple ga objavljuje na https://github.com/apple-oss-distributions/xnu/tree/main/iokit. Takođe, komponente IOKit-a u korisničkom prostoru su otvorenog koda na https://github.com/opensource-apple/IOKitUser.
Međutim, nijedni IOKit drajveri nisu otvorenog koda. Ipak, povremeno izdanje drajvera može sadržati simbole koji olakšavaju njegovo debugovanje. Pogledajte kako preuzeti driver ekstenzije iz firmvera ovde.
Napisano je u C++. Možete dobiti demanglovane C++ simbole sa:
# Get demangled symbols
nm -C com.apple.driver.AppleJPEGDriver
# Demangled symbols from stdin
c++filt
__ZN16IOUserClient202222dispatchExternalMethodEjP31IOExternalMethodArgumentsOpaquePK28IOExternalMethodDispatch2022mP8OSObjectPv
IOUserClient2022::dispatchExternalMethod(unsigned int, IOExternalMethodArgumentsOpaque*, IOExternalMethodDispatch2022 const*, unsigned long, OSObject*, void*)
Caution
IOKit izložene funkcije mogu izvoditi dodatne sigurnosne provere kada klijent pokuša da pozove funkciju, ali imajte na umu da su aplikacije obično ograničene od strane sandbox-a u pogledu toga sa kojim IOKit funkcijama mogu da interaguju.
Drajveri
Na macOS-u se nalaze:
/System/Library/Extensions- KEXT fajlovi ugrađeni u operativni sistem OS X.
/Library/Extensions- KEXT fajlovi koje instalira softver treće strane
Na iOS-u se nalaze:
/System/Library/Extensions
#Use kextstat to print the loaded drivers
kextstat
Executing: /usr/bin/kmutil showloaded
No variant specified, falling back to release
Index Refs Address Size Wired Name (Version) UUID <Linked Against>
1 142 0 0 0 com.apple.kpi.bsd (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
2 11 0 0 0 com.apple.kpi.dsep (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
3 170 0 0 0 com.apple.kpi.iokit (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
4 0 0 0 0 com.apple.kpi.kasan (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
5 175 0 0 0 com.apple.kpi.libkern (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
6 154 0 0 0 com.apple.kpi.mach (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
7 88 0 0 0 com.apple.kpi.private (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
8 106 0 0 0 com.apple.kpi.unsupported (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
9 2 0xffffff8003317000 0xe000 0xe000 com.apple.kec.Libm (1) 6C1342CC-1D74-3D0F-BC43-97D5AD38200A <5>
10 12 0xffffff8003544000 0x92000 0x92000 com.apple.kec.corecrypto (11.1) F5F1255F-6552-3CF4-A9DB-D60EFDEB4A9A <8 7 6 5 3 1>
Do broja 9, navedeni drivers su loaded in the address 0. To znači da oni nisu pravi drivers, već part of the kernel i ne mogu da budu unloaded.
Da biste pronašli specific extensions možete koristiti:
kextfind -bundle-id com.apple.iokit.IOReportFamily #Search by full bundle-id
kextfind -bundle-id -substring IOR #Search by substring in bundle-id
Da biste učitali i uklonili kernel ekstenzije, uradite:
kextload com.apple.iokit.IOReportFamily
kextunload com.apple.iokit.IOReportFamily
IORegistry
The IORegistry je ključni deo IOKit framework-a u macOS i iOS koji služi kao baza podataka za predstavljanje konfiguracije hardvera sistema i njegovog stanja. To je hijerarhijska kolekcija objekata koja predstavlja sav hardver i drajvere učitane u sistem, i njihove međusobne odnose.
You can get the IORegistry using the cli ioreg to inspect it from the console (specially useful for iOS).
ioreg -l #List all
ioreg -w 0 #Not cut lines
ioreg -p <plane> #Check other plane
Možete preuzeti IORegistryExplorer iz Xcode Additional Tools sa https://developer.apple.com/download/all/ i pregledati macOS IORegistry kroz grafički interfejs.
.png)
U IORegistryExplorer-u, “planes” se koriste za organizovanje i prikaz odnosa između različitih objekata u IORegistry-ju. Svaka plane predstavlja određeni tip odnosa ili poseban pogled na hardver sistema i konfiguraciju drajvera. Evo nekih od uobičajenih “planes” koje možete sresti u IORegistryExplorer-u:
- IOService Plane: Ovo je najopštija ravan, prikazuje servisne objekte koji predstavljaju drajvere i nubs (kanale za komunikaciju između drajvera). Prikazuje provider-client odnose između ovih objekata.
- IODeviceTree Plane: Ova ravan predstavlja fizičke veze između uređaja kako su povezani na sistem. Često se koristi za vizuelizaciju hijerarhije uređaja povezanih preko sabirnica kao što su USB ili PCI.
- IOPower Plane: Prikazuje objekte i njihove odnose u kontekstu upravljanja napajanjem. Može pokazati koji objekti utiču na stanje napajanja drugih, što je korisno za otklanjanje problema vezanih za napajanje.
- IOUSB Plane: Fokusirana posebno na USB uređaje i njihove odnose, prikazuje hijerarhiju USB hub-ova i povezanih uređaja.
- IOAudio Plane: Ova ravan služi za predstavljanje audio uređaja i njihovih odnosa unutar sistema.
- …
Primer koda za komunikaciju sa drajverom
Sledeći kod se povezuje na IOKit servis YourServiceNameHere i poziva selector 0:
- Prvo poziva
IOServiceMatchingiIOServiceGetMatchingServicesda dobije servis. - Zatim uspostavlja konekciju pozivom
IOServiceOpen. - Na kraju poziva funkciju sa
IOConnectCallScalarMethodkoja koristi selector 0 (selector je broj dodeljen funkciji koju želite da pozovete).
Primer user-space poziva na selector drajvera
```objectivec #importint main(int argc, const char * argv[]) { @autoreleasepool { // Get a reference to the service using its name CFMutableDictionaryRef matchingDict = IOServiceMatching(“YourServiceNameHere”); if (matchingDict == NULL) { NSLog(@“Failed to create matching dictionary”); return -1; }
// Obtain an iterator over all matching services io_iterator_t iter; kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter); if (kr != KERN_SUCCESS) { NSLog(@“Failed to get matching services”); return -1; }
// Get a reference to the first service (assuming it exists) io_service_t service = IOIteratorNext(iter); if (!service) { NSLog(@“No matching service found”); IOObjectRelease(iter); return -1; }
// Open a connection to the service io_connect_t connect; kr = IOServiceOpen(service, mach_task_self(), 0, &connect); if (kr != KERN_SUCCESS) { NSLog(@“Failed to open service”); IOObjectRelease(service); IOObjectRelease(iter); return -1; }
// Call a method on the service // Assume the method has a selector of 0, and takes no arguments kr = IOConnectCallScalarMethod(connect, 0, NULL, 0, NULL, NULL); if (kr != KERN_SUCCESS) { NSLog(@“Failed to call method”); }
// Cleanup IOServiceClose(connect); IOObjectRelease(service); IOObjectRelease(iter); } return 0; }
</details>
Postoje **druge** funkcije koje se mogu koristiti za pozivanje IOKit funkcija pored **`IOConnectCallScalarMethod`**, kao što su **`IOConnectCallMethod`**, **`IOConnectCallStructMethod`**...
## Reverzovanje ulazne tačke drajvera
Te funkcije, na primer, možete dobiti iz [**firmware image (ipsw)**](#ipsw). Zatim image učitajte u vaš omiljeni dekompajler.
Možete početi dekompajlirati funkciju **`externalMethod`**, jer je to drajverska funkcija koja će primati poziv i pozivati odgovarajuću funkciju:
<figure><img src="../../../images/image (1168).png" alt="" width="315"><figcaption></figcaption></figure>
<figure><img src="../../../images/image (1169).png" alt=""><figcaption></figcaption></figure>
Ta užasna demanglovana poziv znači:
```cpp
IOUserClient2022::dispatchExternalMethod(unsigned int, IOExternalMethodArgumentsOpaque*, IOExternalMethodDispatch2022 const*, unsigned long, OSObject*, void*)
Primetite da u prethodnoj definiciji parametar self nedostaje; ispravna definicija bi bila:
IOUserClient2022::dispatchExternalMethod(self, unsigned int, IOExternalMethodArgumentsOpaque*, IOExternalMethodDispatch2022 const*, unsigned long, OSObject*, void*)
Zapravo, pravu definiciju možete pronaći u https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/Kernel/IOUserClient.cpp#L6388:
IOUserClient2022::dispatchExternalMethod(uint32_t selector, IOExternalMethodArgumentsOpaque *arguments,
const IOExternalMethodDispatch2022 dispatchArray[], size_t dispatchArrayCount,
OSObject * target, void * reference)
Sa ovim informacijama možete prepraviti Ctrl+Right -> Edit function signature i postaviti poznate tipove:
.png)
Novi dekompilovani kod će izgledati ovako:
.png)
Za sledeći korak potrebno je da bude definisan struct IOExternalMethodDispatch2022. On je opensource u https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/IOKit/IOUserClient.h#L168-L176, možete ga definisati:
.png)
Sada, prateći (IOExternalMethodDispatch2022 *)&sIOExternalMethodArray, možete videti mnogo podataka:
.png)
Promenite tip podatka u IOExternalMethodDispatch2022:
.png)
posle promene:
.png)
I kao što sada vidite, tamo imamo niz od 7 elemenata (pogledajte finalni dekompilovani kod), kliknite da kreirate niz od 7 elemenata:
.png)
Nakon što je niz kreiran, možete videti sve eksportovane funkcije:
.png)
Tip
Ako se sećate, da biste pozvali an exported funkciju iz user space-a ne treba da pozivate ime funkcije, već selector number. Ovde možete videti da je selector 0 funkcija
initializeDecoder, selector 1 jestartDecoder, selector 2initializeEncoder…
Nedavno IOKit attack surface (2023–2025)
- Keystroke capture via IOHIDFamily – CVE-2024-27799 (14.5) je pokazao da permisivan
IOHIDSystemclient može da uhvati HID događaje čak i uz secure input; osigurajte daexternalMethodhandleri primenjuju entitlements umesto da se oslanjaju samo na tip user-client-a. - IOGPUFamily memory corruption – CVE-2024-44197 i CVE-2025-24257 su ispravili OOB writes dostupne iz sandboxed aplikacija koje šalju malformirane variable-length podatke GPU user clientima; uobičajeni bug su loše granice oko argumenata
IOConnectCallStructMethod. - Legacy keystroke monitoring – CVE-2023-42891 (14.2) je potvrdio da HID user clients ostaju vektor za bekstvo iz sandboksa; fuzz any driver exposing keyboard/event queues.
Brza trijaža & fuzzing saveti
- Enumerišite sve external methods za user client iz userlanda kako biste seed-ovali fuzzer:
# list selectors for a service
python3 - <<'PY'
from ioreg import IORegistry
svc = 'IOHIDSystem'
reg = IORegistry()
obj = reg.get_service(svc)
for sel, name in obj.external_methods():
print(f"{sel:02d} {name}")
PY
- Prilikom reverziranja, obrati pažnju na
IOExternalMethodDispatch2022counts. Čest obrazac buga u nedavnim CVE-ovima je neusaglašenoststructureInputSize/structureOutputSizeu odnosu na stvarnu dužinucopyin, što dovodi do heap OOB uIOConnectCallStructMethod. - Dostupnost Sandboxa i dalje zavisi od entitlements. Pre nego što potrošiš vreme na cilj, proveri da li je klijent dozvoljen iz aplikacije treće strane:
strings /System/Library/Extensions/IOHIDFamily.kext/Contents/MacOS/IOHIDFamily | \
grep -E "^com\.apple\.(driver|private)"
- Za GPU/iomfb ranjivosti, prosleđivanje prevelikih nizova kroz
IOConnectCallMethodčesto je dovoljno da izazove pogrešno rukovanje granicama. Minimalni harness (selector X) za izazivanje size confusion:
uint8_t buf[0x1000];
size_t outSz = sizeof(buf);
IOConnectCallStructMethod(conn, X, buf, sizeof(buf), buf, &outSz);
Reference
- Apple Security Updates – macOS Sequoia 15.1 / Sonoma 14.7.1 (IOGPUFamily)
- Rapid7 – IOHIDFamily CVE-2024-27799 summary
- Apple Security Updates – macOS 13.6.1 (CVE-2023-42891 IOHIDFamily)
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.


