API 퍼징을통한취약점탐지 카이스트 차상길
API Fuzzing? void foo(int x) // This is an API function { // (side-effect-free) //... } void fuzz() { while (1) { foo(rand()); } } // Fuzzer MAIN Found a crash in foo when x = 42 2
No Sound Result! int foo(int x) // This is an API function { // (side-effect-free) //... } int somefunc(int input) { if (input >= 42) return 0; else return foo(input); } But the function foo is never called with x = 42 in a real program! 3
Why API Fuzzing? How about when crossing the trust boundary? Kernel is the right target! 4
https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=kernel 5
https://www.linuxcounter.net/statistics/kernel 6
7
Kernel should be tested! 8
How to Find Kernel Bugs? 1. Source-based analysis 2. White-box kernel fuzzing 3. Black-box kernel fuzzing 9
1. Source-based Analysis #include CQUAL, Sec 04 KINT, OSDI 12 Source code is not fully available µchex, ASPLOS 16 (e.g., macos, Windows) 10
2. White-box Kernel Fuzzing KLEE, OSDI 08 CAB-Fuzz, ATC 16 Too many paths 11
3. Black-box Kernel Fuzzing? Do not need source code Not limited by path explosion Many practical black-box kernel fuzzers 12
3. Black-box Kernel Fuzzing read( ) write( ) a) Random-based b) Type-based? c) Hooking-based 13
Black-box: Random-based Fuzzer Type Weakness L a) Random-based fuzzer (e.g., tsys, sysfuzz) b) Type-aware fuzzer (e.g., iknowthis, Trinity) c) Hooking-based fuzzer (e.g., IOKit Fuzzer ) 14
Black-box: Random-based Fuzzer Type a) Random-based fuzzer (e.g., tsys, sysfuzz) Weakness L Shallow exploration b) Type-aware fuzzer (e.g., iknowthis, Trinity) c) Hooking-based fuzzer (e.g., IOKit Fuzzer ) 15
Weakness of Random-based Fuzzer WRITE(2) Linux Programmer s Manual WRITE(2) #include <unistd.h> ssize_t write(int fd, const void *buf, size_t n) write(rand(), rand(), rand()); CRASH Cannot explore deep paths 16
Black-box: Type-aware Fuzzer Type a) Random-based fuzzer (e.g., tsys, sysfuzz) Weakness L Shallow exploration b) Type-aware fuzzer (e.g., iknowthis, Trinity) c) Hooking-based fuzzer (e.g., IOKit Fuzzer ) 17
Black-box: Type-aware Fuzzer Type a) Random-based fuzzer (e.g., tsys, sysfuzz) b) Type-aware fuzzer (e.g., iknowthis, Trinity) Weakness L Shallow exploration Flow- & context-insensitivity c) Hooking-based fuzzer (e.g., IOKit Fuzzer ) 18
Weakness of Type-aware Fuzzer int fd = open( /tmp/test, O_WRONLY); int r = write(fd, buf, 0x100); Returns valid memory pointer write(rand_int(), rand_void(), rand_size_t()); -1 Flow-insensitive 19
Weakness of Type-aware Fuzzer int fd = open( /tmp/test, O_WRONLY); int r = write(fd, buf, 0x100); write(rand_fd(), rand_void(), rand_size_t()); -1 Context-insensitive 20
Black-box: Hooking-based Fuzzer Type a) Random-based fuzzer (e.g., tsys, sysfuzz) b) Type-aware fuzzer (e.g., iknowthis, Trinity) Weakness L Shallow exploration Flow- & context-insensitivity c) Hooking-based fuzzer (e.g., IOKit Fuzzer ) 21
Black-box: Hooking-based Fuzzer Type a) Random-based fuzzer (e.g., tsys, sysfuzz) Program b) Type-aware fuzzer API calls (e.g., iknowthis, Trinity) Weakness L Shallow exploration API Hooks Mutated API calls Kernel Flow- & context-insensitivity c) Hooking-based fuzzer (e.g., IOKit Fuzzer ) 22
Black-box: Hooking-based Fuzzer Type a) Random-based fuzzer (e.g., tsys, sysfuzz) Program b) Type-aware fuzzer API calls (e.g., iknowthis, Trinity) c) Hooking-based fuzzer (e.g., IOKit Fuzzer ) Weakness L Shallow exploration API Hooks Mutated API calls Kernel Flow- & context-insensitivity Uncontrollable call sequences 23
Weakness of Hooking-based Fuzzer int fd = open( /tmp/test, O_WRONLY); int r = write(fd, buf, 0x100); if(r<0) exit(-1); Cannot reach here close(fd); // if(r<0) Kernel Panic here Cannot control call sequence 24
Our Goal: Design a Kernel Fuzzer Type Weakness L a) Random-based fuzzer (e.g., tsys, sysfuzz) 1. Deep exploration Shallow exploration b) Type-aware fuzzer (e.g., iknowthis, Trinity) macos c) Hooking-based fuzzer (e.g., IOKit Fuzzer ) 2. Flow- & context-sensitivity Flow- & context-insensitivity 3. Controllable call sequences Uncontrollable call sequences 25
Our Design Principle Make it simple & practical 26
IMF: Inferred Model-based Fuzzer Executions 3. Controllable execution API Logs API Model Logger Inferrer Fuzzer 1. Deep exploration 2. Flow- & context-sensitivity 27
How to Infer API Models? Executions 3. Controllable execution API Logs API Model Logger Inferrer Fuzzer 1. Deep exploration 2. Flow- & context-sensitivity 28
Intuition: Various API Logs from the same Execution $ strace /bin/ls... fstat(3, {st_mode=s_ifreg 0755, st_size=1868984,...}) = 0 mmap(null, 3971488, PROT_READ PROT_EXEC, MAP_PRIVATE MAP_DENYWRITE, 3, 0) = 0x7f2bd963e000 mprotect(0x7f2bd97fe000, 2097152, PROT_NONE) = 0 $ strace /bin/ls... fstat(3, {st_mode=s_ifreg 0755, st_size=1868984,...}) = 0 mmap(null, 3971488, PROT_READ PROT_EXEC, MAP_PRIVATE MAP_DENYWRITE, 3, 0) = 0x7f9b69411000 mprotect(0x7f9b695d1000, 2097152, PROT_NONE) = 0 29
On macos io_iterator_t iterator; CFDictionarayRef r; io_object_t service; r = IOServiceMatching( IntelAccelerator ); iterator = IOServiceGetMatchingService(0x0, r); service = IOIteratorNext(iterator); IOServiceMatching( IntelAccelerator ) => 0xd32e0a90 IOServiceGetMatchingService(0x0,\ 0xd32e0a90) => 0x10127 IOIteratorNext(0x10127) => 0x10128 IOServiceMatching( IntelAccelerator ) => 0x487e0a90 IOServiceGetMatchingService(0x0,\ 0x487e0a90) => 0x10327 IOIteratorNext(0x10327) => 0x10328 30
Inferring Ordering Dependences io_iterator_t iterator; CFDictionarayRef r; io_object_t service; r = IOServiceMatching( IntelAccelerator ); iterator = IOServiceGetMatchingService(0x0, r); service = IOIteratorNext(iterator); IOServiceMatching( IntelAccelerator ) => 0xd32e0a90 IOServiceGetMatchingService(0x0,\ 0xd32e0a90) => 0x10127 IOIteratorNext(0x10127) => 0x10128 IOServiceMatching( IntelAccelerator ) => 0x487e0a90 IOServiceGetMatchingService(0x0,\ 0x487e0a90) => 0x10327 IOIteratorNext(0x10327) => 0x10328 31
Inferring Constant Parameters io_iterator_t iterator; CFDictionarayRef r; io_object_t service; r = IOServiceMatching( IntelAccelerator ); iterator = IOServiceGetMatchingService(0x0, r); service = IOIteratorNext(iterator); IOServiceMatching( IntelAccelerator ) => 0xd32e0a90 IOServiceGetMatchingService(0x0,\ 0xd32e0a90) => 0x10127 IOIteratorNext(0x10127) => 0x10128 IOServiceMatching( IntelAccelerator ) => 0x487e0a90 IOServiceGetMatchingService(0x0,\ 0x487e0a90) => 0x10327 IOIteratorNext(0x10327) => 0x10328 32
Inferring Value Dependences io_iterator_t iterator; CFDictionarayRef r; io_object_t service; r = IOServiceMatching( IntelAccelerator ); iterator = IOServiceGetMatchingService(0x0, r); service = IOIteratorNext(iterator); IOServiceMatching( IntelAccelerator ) => 0xd32e0a90 IOServiceGetMatchingService(0x0,\ 0xd32e0a90) => 0x10127 IOIteratorNext(0x10127) => 0x10128 IOServiceMatching( IntelAccelerator ) => 0x487e0a90 IOServiceGetMatchingService(0x0,\ 0x487e0a90) => 0x10327 IOIteratorNext(0x10327) => 0x10328 33
How to Fuzz with API Models? Executions 3. Controllable execution API Logs API Model Logger Inferrer Fuzzer 1. Deep exploration 2. Flow- & context-sensitivity 34
Observation: Model-based Userland Fuzzer Model (Grammar) Inputs Javascript Engine Relationships between inputs CVE-2014-1705 35
Our Approach: Model-based Kernel Fuzzer Model API Model (Grammar) API calls Inputs Javascript Kernel Engine Relationships between API inputs calls CVE-2014-1705 36
Example of an API Model io_iterator_t iterator; CFDictionarayRef r; io_object_t service; r = IOServiceMatching( IntelAccelerator ); iterator = IOServiceGetMatchingService(0x0, r); service = IOIteratorNext(iterator); 37
Parameter Mutation PRNG Seed Mutation probability (P) io_iterator_t iterator; # of fixed bits (F) CFDictionarayRef r; io_object_t service; r = IOServiceMatching(mut_str( IntelAccelerator )); iterator = IOServiceGetMatchingService(mut_int(0x0), mut_ptr(r)); service = IOIteratorNext(mut_int(iterator)); 38
API Model Replication while(loop < max_loop){ # of iterations (I) io_iterator_t iterator; CFDictionarayRef r; io_object_t service; r = IOServiceMatching(mut_str( IntelAccelerator )); iterator = IOServiceGetMatchingService(mut_int(0x0), mut_ptr(r)); service = IOIteratorNext(mut_int(iterator)); } loop++; 39
Evaluation Executions API Logs API Model Logger Inferrer Fuzzer 40
Experiment Setup macos Sierra 10.12.3 (from 2017.1.23) 93 IOKitLib functions 105 apps (top 5 popular apps from 21 categories) Manually generated inputs (e.g., mouse clicks) for each program 41
API Model Accuracy 42
Comparison against IOKit Fuzzer IOKit Fuzzer: A state-of-the-art macos fuzzer developed by Google Project Zero Running time: 24 hours x 5 Apps (game category) = 120 hours IOKit Fuzzer 3 unique panics IMF 10 unique panics Crashing process: - Fuzzer process Crashing process: - Fuzzer process - reboot - mdworker - ReportCrash - mds_stores 43
Large-scale Bug Finding IMF Ran 12 hours for 95 API models (1,140 hours) With 95 apps from 21 categories Found 32 unique kernel panics Likely exploitable: 6 kernel panics NULL dereference: 3 kernel panics macos Sierra (from 2017.1.23) DoS: 23 kernel panics 44
macos is Still Vulnerable! IMF Ran 12 hours for 10 API models (120 hours) Found 39 unique kernel panics Likely exploitable: 25 kernel panics 5 RIP corruptions DoS: 14 kernel panics macos High Sierra (from 2017.10.5) 45
Limitation Program selection for getting API logs Reference: Optimizing Seed Selection for Fuzzing, Sec 14 Simple mutation strategy Non-deterministic bugs 46
Open Science https://github.com/softsec-kaist/imf 47
Question? 48