SlideShare a Scribd company logo
Find Your Own iOS
    Kernel Bug
      Chen Xiaobo
           &
        Xu Hao




           1
Content
iOS Kernel Basics

Summary of Known Bugs

Passive Fuzz

Active Fuzz

Analyze Real Bug

Conclusion

                    2
iOS Kernel Basics
OSX is older that iOS
  Guess iOS kernel is developed based on OSX kernel

  Learn from OSX kernel

OSX kernel concepts
  Early derived from FreeBSD kernel

  Named as XNU

    Open source


                           3
XNU
Open Source

 http://www.opensource.apple.com/source/xnu/
 xnu-2050.7.9/

Important components

 Mach - Low level abstraction of kernel

 BSD - High level abstraction of kernel

 IOKit - Apple kernel extension framework

                           4
BSD
Implement File System, Socket and ...

Export POSIX API
  Basic interface between kernel and user space

  sysent[] - store kernel function address

    typedef int32_t sy_call_t(struct proc *, void *, int *);

  function call number - /usr/include/sys/syscall.h


                                5
IOKit
Framework for kernel extension
  Subset of C++ - Object-Oriented driver programming




                                   6
IOKit Objects
OSObject
  Root object of all IOKit objects

  Overwrite new operator to alloc memory

  Declare “init” method to initialize object self

OSMetaClass
  Run-time object type check

     According to object name

  OSDynamicCast


                                     7
IOKit Objects
IOService
  Define an interface for most kernel
  extension

  Basic methods - init / start / stop /
  attach / detach / probe

ioreg - list all attached IOService
  Available in Cydia


                            8
Write IOKit
Service - Inherit from IOService
  Overwrite basic methods - init / start / stop / probe

Control - Inherit from IOUserClient
  Allow user space control

Modify plist file
  At least one IOKitPersonalities

     CFBundleIdentifier/IOClass/IOProviderClass/IOMatchCategory/
     IOUserClientClass/IOResourceMatch


                                9
Kernelcache
Store all kernel modules (XNU / extensions) into one cache file

iBoot will load the whole kernelcache and jump to entry

An encrypted and packed IMG3 file
  /System/Library/Caches/com.apple.kernelcaches/kernelcache

  For old devices (A4 devices)

     Use xpwntool to decrypt original cache with IV + KEY

  A5 devices

     No IV + KEY available


                                   10
Kernelcache
How to get kernelcache for A5 devices
  Dump from kernel memory

    task_for_pid(0) & vm_read to dump kernel memory

       Read size must less then 0x1000 for once

    Find all Mach-O header - test magic 0xFEEDFACE

       Determine the whole cache size

    Open with IDA - fail

       Lack of prelink info

                                11
Kernelcache
Dump each kernel extension
  Write a kextstat for iOS

     Just call CFDictionaryRef OSKextCopyLoadedKextInfo(CFArrayRef, CFArrayRef)
     from IOKit framework




                                    12
Reverse Kernel
Kernelcache is combined with lots of Mach-O files

IDA Pro 6.2 could identify each Mach-O file
  Reverse the whole kernel together

  Open “Segmentation” view




                               13
Reverse IOKit Extension
IOKit constructor
example
  First call
  OSObject::new to
  allocate memory

  Then init IOService

  At last init
  OSMetaClass

                        14
Debug iOS Kernel
KDP code is included in kernel

KDP via UART
  SerialKDPProxy to perform proxy between serial and UDP

Need serial communicate between USB and Dock connector
  Make a cable by your own

Using redsn0w to set boot-args
  -a “-v debug=0x09”


                             15
Debug iOS Kernel

A5 CPU Devices
 No limera1n vulnerability - no way to set boot-arg

 Need a kernel exploit to cheat kernel with boot-arg &
 debug enable

 See “iOS5 An Exploitation Nightmare” from Stefan Esser
 for details



                          16
Content
iOS Kernel Basics

Summary of Known Bugs

Passive Fuzz

Active Fuzz

Analyze Real Bug

Conclusion

                    17
Summary of Known Bugs
iOS kernel attack surface
  Socket/Syscalls

    ioctl

  FileSystem drivers

    HFS

  iOKit

    Device drivers (USB/Baseband etc)


                             18
CVE-2010-2973
CVE-2010-2973 - IOSurfaceRoot integer overflow

  Used in the jailbreakme 2 as PE exploit

    Can be triggered by mobile user apps (MobileSafari)

  Malformed IOSurfaceAllocSize/IOSurfaceBytesPerRow/
  IOSurfaceHeight/IOSurfaceWidth values in the plist

  Create a Surface object using above plist and return a userland ptr

  Calling memcpy to overflow the important kernel structure to
  disable the security protection


                                 19
CVE-2010-2973
CVE-2010-2973 - IOSurfaceRoot integer overflow
  The plist




  Exploit: https://github.com/comex/star/blob/master/goo/zero.py


                             20
CVE-2011-0227
CVE-2011-0227 - IOMobileFrameBuffer Type
Conversion Issue
 RootCause happens in the IOMobileFrameBuffer are not
 properly to check the object when doing conversion

 Suppose to call OSDynamicCast() while doing type
 casting/conversion

 The user able to control the vtable function pointer to get
 code execution

                           21
CVE-2011-0227
CVE-2011-0227 - IOMobileFrameBuffer Type Conversion Issue
  PoC:




  Fully exploit: https://github.com/comex/star_/blob/master/
  catalog/catalog.py


                             22
Summary of Known Bugs

 Conclusion

   They are both PE vulns because it is happens in the IOKit
   drivers framework

   Closed source and less people pay attention

   Good target for bug hunting!




                            23
Content
iOS Kernel Basics

Summary of Known Bugs

Passive Fuzz

Active Fuzz

Analyze Real Bug

Conclusion

                    24
Passive Fuzz
Passive Fuzz

  First idea coming out is fuzzing

  Less work with good results

  Write a IOKit client to understand how the IOKit works

  Fuzzing parameters for IOConnectCallStructMethod/
  IOConnectCallScalarMethod

  In the low-level both above APIs are calling to the
  IOConnectCallMethod


                            25
Passive Fuzz

Why we need passive fuzzing?

  They key point is pay less works because we are lazy to audit
  code :P

  Just like hook DeviceIoControl on the win32 to hunting kernel
  bugs

  We are going to hook IOConnectCallMethod to do the passive
  fuzzing



                           26
Passive Fuzz
The Preparation

  Finding a good hook framework for iOS

    MobileSubstrate

       http://iphonedevwiki.net/index.php/MobileSubstrate

    MSHookFunction/MSHookMessage for C/Object Method
    hook

    Not much documents but enough to make it work


                         27
Passive Fuzz
TheOS/Tweak

  Base the mobilesubstrate but more user-friendly




  https://github.com/DHowett/theos


                              28
Passive Fuzz

You can also using interpose (dyld function)

    Redirect the functions in the import table

    No libmobilesubstrate required.

Inject your dylib via DYLD_INSERT_LIBRARIES to
make your fuzzer running!




                           29
Passive Fuzz
Tips

  Struct object could be Data/Plist(XML), So pay some work
  here.

  Scalar object are integer values only, random enough to find
  some interesting stuffs.

  Results:

       NULL pointer deference/Kernel Use-after-free/handled
       panic exception


                            30
Content
iOS Kernel Basics

Summary of Known Bugs

Passive Fuzz

Active Fuzz

Analyze Real Bug

Conclusion

                    31
Active Fuzz
Weakness of passive fuzz
  Only cover small amount of IOKit interfaces

  Needs interaction - keep using your iPhone

  Not so efficient - waste time

Advantage of active fuzz
  Cover most of IOKit interfaces

  Automatically and efficient


                             32
Rough Idea


Find all IOKit drivers with IOUserClient

Identify all external methods of the driver

Test all those methods




                         33
External Methods
External methods are used by IOKit to provide function to user-
space application

Application call IOConnectCallMethod to control driver




selector - which method should be called

input / output - Array of uint64_t or struct data

                              34
Kernel Dispatch
IOConnectCallMethod -> IOUserClient:: externalMethod




if dispatch != NULL
  Check input and output size & call dispatch->function

else call getTargetAndMethodForIndex



  Check type and size & call method->func


                                 35
IOKit Implement
Overwrite externalMethod
 Example




                     36
IOKit Implement




       37
IOKit Implement
Overwrite getTargetAndMethodForIndex
 Example




                     38
Key Point


Know what to fuzz
 Get IOExternalMethodDispatch sMethods[]

 Get IOExternalMethod methodTemplate[]




                       39
How
For the IOKit drivers without source code
  Reverse the KernelCache with symbol problem resolved

  IOKit structure you should know

    IOExternalMethodDispatch & IOExternalMethod

  Filter the IOKit keywords in the IDA name window

    sMethods etc.

  Will list all the IOKit drivers interface

                              40
sMethods
We have the interface names & address




                       41
sMethods
But there are just bytes in the method dispatch table




IDA pro currently not handle it properly

                          42
sMethods
After some manually work (Mark to the DCD)

  We can see some function pointers, but still ugly




                             43
Work Todo

Need some IDA Python works here

Add IOKit struct information in the idb file

  (IOExternalMethodDispatch & IOExternalMethod)

Find the dispatch table range and mark it to the correct
struct.




                         44
Result
Looks better now

  We have dispatch function, flag, input/output count.




                          45
Correct Input
Flags defines

  I = input O = output

  For example, type 3 means:

    Struct input & output

We must pass the correct input/output type and count,
otherwise the request will be rejected

Start coding your own actively fuzzer!


                            46
Extra
You can also add the vtable information if you like to audit code

Before




After


                            47
Content
iOS Kernel Basics

Summary of Known Bugs

Passive Fuzz

Active Fuzz

Analyze Real Bug

Conclusion

                    48
Are There Bugs?
Definitely YES
  Crashes could be easily generated by our fuzzer

  Actually kernel code of iOS is not as good as you imagine

However analyzing crash is a hard job

  No code or symbols for most IOKit drivers

  Kernel debug is kinda of crap

Any exploitable bug?

  This is a QUESTION


                                  49
IOKit Bug Analysis
Simplify crash code
   Code is generated by fuzzer - there are many IOConnectCallMethod calls

   Simplify the code could help you a lot when doing static analysis

Look at panic log
   fault_type & register values

Static analysis
   Understand the bug and trigger path

Debug
   Write exploit


                                      50
Bug Sample I
Let’s look at the code first




                         51
Bug Sample I
Then the panic log
  PC = 0x80455c3c

  fault_addr = 0x0




                     52
Bug Sample I
Where did it crash
  Try to read data at R1(=0) cause the panic

  R1 is the second parameter of this function

  It is mostly like a NULL ptr reference bug :(

  We shall dig deeper anyway




                            53
Bug Sample I
Locate sMethod array
  First to find AppleVXD375UserClient::externalMethod, which
  should overwrite IOUserClient’s method

  IOUserClient has symbols, see vtable for it

  externalMethod pointer offset in vtable




                              54
Bug Sample I
Locate sMethod array
  Search IOUserClient::registerNotificationPort address in “const”
  segment

  Find externalMethod pointer in vtable for AppleVXD375UserClient



  AppleVXD375UserClient::externalMethod

    Get IOExternalMethodDispatch struct from sMethod array

    Call IOUserClient::externalMethod to dispatch it


                                  55
Bug Sample I
sMethod = 0x80469700




                       56
Bug Sample I
selector = 1 dispatch struct in sMethod
  function address = 0x80457534

  checkStructureInputSize = 0x4

  checkStructureOutputSize = 0x108

  Remember the trigger code?




                           57
Bug Sample I
The whole call path
  externalMethod -> sub_ 80457534 -> sub_ 804577EC ->
  sub_8045779C -> sub_80456768 -> sub_80455C34 -> panic

  sub_ 804577EC call OSObject::release first

    This method should be used to destroy AppleVXD375UserClient itself

  sub_8045779C should be responsible for freeing memory

  R1(=0) maybe some class or struct address stored in
  AppleVXD375UserClient object


                                 58
Bug Sample I
Understand this bug
  We manually try to destroy AppleVXD375UserClient

  When in procedure, it will manipulate some object without
  checking if it is already created

  Lacks of basic check code like

    if (obj->ptr != NULL)

  We are not able to control PC register


                               59
Bug Sample II
Code first




                  60
Bug Sample II
Panic log
  PC = 0x00000000

  Looks better than last one




                               61
Bug Sample II
Where did it crash

  We got useless PC and no call stack

  But luckily we had LR - store return address

  Looks like calling method of certain object

    R4 - object pointer

    R0 - vtable




                            62
Bug Sample II
Crash code snapshot




                      63
Bug Sample II
Crash code analysis
  Input

    R0 - IOAccelUserClient *self

    R1 - int index

  IOAccel *service = self + 0x78

  OSObject *array[] = service + 0x10

  Call array[index]->method = NULL

                              64
Bug Sample II
Weird
 Why the object’s method pointer is NULL

Guess
 Mistake it as a different object without checking

Todo
 Figure out what’s at 0x10 offset


                          65
Bug Sample II
Locate external methods
  This time it overwrite getTargetAndMethodForIndex




                         66
Bug Sample II
IOExternalMethod methodTemplate[5]




                        67
Bug Sample II
Where is selector 6 function ?
  Check reference to IOAccelUserClient::vtable




  It has a child object - IOIMGSGXUserClient

  Easy to find getTargetAndMethodForIndex again


                          68
Bug Sample II
When selector > 5, use its own methodTemplate[3]




                       69
Bug Sample II
What’s at offset 0x10 ?
  Look inside into selector 6 function




                             70
Bug Sample II

Object is created, check vtable 0x8090E5B8
  0x8090E5B8+0x3C = 0x8090E5F4




                        71
Bug Sample II
Here is the story
  selector 6 function call sub_80907A4C to create an object
  and put it in object array at 0x10 offset

  selector 3 function get object pointer from the array and call
  its method without checking its class type

  Actually the child has its own create/destroy method. If the
  child create an object and make father to destroy it, PANIC !

  Apple should call more OSMetaClassBase::safeMetaCast :P


                             72
Content
iOS Kernel Basics

Summary of Known Bugs

Passive Fuzz

Active Fuzz

Analyze Real Bug

Conclusion

                    73
Conclusion

Apple should audit iOS kernel code, especially code
of IOKit extensions

Since debug is quite hard, static analysis according to
panic log is very helpful

Fuzz your own iOS kernel bug !



                         74

More Related Content

Find your own iOS kernel bug

  • 1. Find Your Own iOS Kernel Bug Chen Xiaobo & Xu Hao 1
  • 2. Content iOS Kernel Basics Summary of Known Bugs Passive Fuzz Active Fuzz Analyze Real Bug Conclusion 2
  • 3. iOS Kernel Basics OSX is older that iOS Guess iOS kernel is developed based on OSX kernel Learn from OSX kernel OSX kernel concepts Early derived from FreeBSD kernel Named as XNU Open source 3
  • 4. XNU Open Source http://www.opensource.apple.com/source/xnu/ xnu-2050.7.9/ Important components Mach - Low level abstraction of kernel BSD - High level abstraction of kernel IOKit - Apple kernel extension framework 4
  • 5. BSD Implement File System, Socket and ... Export POSIX API Basic interface between kernel and user space sysent[] - store kernel function address typedef int32_t sy_call_t(struct proc *, void *, int *); function call number - /usr/include/sys/syscall.h 5
  • 6. IOKit Framework for kernel extension Subset of C++ - Object-Oriented driver programming 6
  • 7. IOKit Objects OSObject Root object of all IOKit objects Overwrite new operator to alloc memory Declare “init” method to initialize object self OSMetaClass Run-time object type check According to object name OSDynamicCast 7
  • 8. IOKit Objects IOService Define an interface for most kernel extension Basic methods - init / start / stop / attach / detach / probe ioreg - list all attached IOService Available in Cydia 8
  • 9. Write IOKit Service - Inherit from IOService Overwrite basic methods - init / start / stop / probe Control - Inherit from IOUserClient Allow user space control Modify plist file At least one IOKitPersonalities CFBundleIdentifier/IOClass/IOProviderClass/IOMatchCategory/ IOUserClientClass/IOResourceMatch 9
  • 10. Kernelcache Store all kernel modules (XNU / extensions) into one cache file iBoot will load the whole kernelcache and jump to entry An encrypted and packed IMG3 file /System/Library/Caches/com.apple.kernelcaches/kernelcache For old devices (A4 devices) Use xpwntool to decrypt original cache with IV + KEY A5 devices No IV + KEY available 10
  • 11. Kernelcache How to get kernelcache for A5 devices Dump from kernel memory task_for_pid(0) & vm_read to dump kernel memory Read size must less then 0x1000 for once Find all Mach-O header - test magic 0xFEEDFACE Determine the whole cache size Open with IDA - fail Lack of prelink info 11
  • 12. Kernelcache Dump each kernel extension Write a kextstat for iOS Just call CFDictionaryRef OSKextCopyLoadedKextInfo(CFArrayRef, CFArrayRef) from IOKit framework 12
  • 13. Reverse Kernel Kernelcache is combined with lots of Mach-O files IDA Pro 6.2 could identify each Mach-O file Reverse the whole kernel together Open “Segmentation” view 13
  • 14. Reverse IOKit Extension IOKit constructor example First call OSObject::new to allocate memory Then init IOService At last init OSMetaClass 14
  • 15. Debug iOS Kernel KDP code is included in kernel KDP via UART SerialKDPProxy to perform proxy between serial and UDP Need serial communicate between USB and Dock connector Make a cable by your own Using redsn0w to set boot-args -a “-v debug=0x09” 15
  • 16. Debug iOS Kernel A5 CPU Devices No limera1n vulnerability - no way to set boot-arg Need a kernel exploit to cheat kernel with boot-arg & debug enable See “iOS5 An Exploitation Nightmare” from Stefan Esser for details 16
  • 17. Content iOS Kernel Basics Summary of Known Bugs Passive Fuzz Active Fuzz Analyze Real Bug Conclusion 17
  • 18. Summary of Known Bugs iOS kernel attack surface Socket/Syscalls ioctl FileSystem drivers HFS iOKit Device drivers (USB/Baseband etc) 18
  • 19. CVE-2010-2973 CVE-2010-2973 - IOSurfaceRoot integer overflow Used in the jailbreakme 2 as PE exploit Can be triggered by mobile user apps (MobileSafari) Malformed IOSurfaceAllocSize/IOSurfaceBytesPerRow/ IOSurfaceHeight/IOSurfaceWidth values in the plist Create a Surface object using above plist and return a userland ptr Calling memcpy to overflow the important kernel structure to disable the security protection 19
  • 20. CVE-2010-2973 CVE-2010-2973 - IOSurfaceRoot integer overflow The plist Exploit: https://github.com/comex/star/blob/master/goo/zero.py 20
  • 21. CVE-2011-0227 CVE-2011-0227 - IOMobileFrameBuffer Type Conversion Issue RootCause happens in the IOMobileFrameBuffer are not properly to check the object when doing conversion Suppose to call OSDynamicCast() while doing type casting/conversion The user able to control the vtable function pointer to get code execution 21
  • 22. CVE-2011-0227 CVE-2011-0227 - IOMobileFrameBuffer Type Conversion Issue PoC: Fully exploit: https://github.com/comex/star_/blob/master/ catalog/catalog.py 22
  • 23. Summary of Known Bugs Conclusion They are both PE vulns because it is happens in the IOKit drivers framework Closed source and less people pay attention Good target for bug hunting! 23
  • 24. Content iOS Kernel Basics Summary of Known Bugs Passive Fuzz Active Fuzz Analyze Real Bug Conclusion 24
  • 25. Passive Fuzz Passive Fuzz First idea coming out is fuzzing Less work with good results Write a IOKit client to understand how the IOKit works Fuzzing parameters for IOConnectCallStructMethod/ IOConnectCallScalarMethod In the low-level both above APIs are calling to the IOConnectCallMethod 25
  • 26. Passive Fuzz Why we need passive fuzzing? They key point is pay less works because we are lazy to audit code :P Just like hook DeviceIoControl on the win32 to hunting kernel bugs We are going to hook IOConnectCallMethod to do the passive fuzzing 26
  • 27. Passive Fuzz The Preparation Finding a good hook framework for iOS MobileSubstrate http://iphonedevwiki.net/index.php/MobileSubstrate MSHookFunction/MSHookMessage for C/Object Method hook Not much documents but enough to make it work 27
  • 28. Passive Fuzz TheOS/Tweak Base the mobilesubstrate but more user-friendly https://github.com/DHowett/theos 28
  • 29. Passive Fuzz You can also using interpose (dyld function) Redirect the functions in the import table No libmobilesubstrate required. Inject your dylib via DYLD_INSERT_LIBRARIES to make your fuzzer running! 29
  • 30. Passive Fuzz Tips Struct object could be Data/Plist(XML), So pay some work here. Scalar object are integer values only, random enough to find some interesting stuffs. Results: NULL pointer deference/Kernel Use-after-free/handled panic exception 30
  • 31. Content iOS Kernel Basics Summary of Known Bugs Passive Fuzz Active Fuzz Analyze Real Bug Conclusion 31
  • 32. Active Fuzz Weakness of passive fuzz Only cover small amount of IOKit interfaces Needs interaction - keep using your iPhone Not so efficient - waste time Advantage of active fuzz Cover most of IOKit interfaces Automatically and efficient 32
  • 33. Rough Idea Find all IOKit drivers with IOUserClient Identify all external methods of the driver Test all those methods 33
  • 34. External Methods External methods are used by IOKit to provide function to user- space application Application call IOConnectCallMethod to control driver selector - which method should be called input / output - Array of uint64_t or struct data 34
  • 35. Kernel Dispatch IOConnectCallMethod -> IOUserClient:: externalMethod if dispatch != NULL Check input and output size & call dispatch->function else call getTargetAndMethodForIndex Check type and size & call method->func 35
  • 39. Key Point Know what to fuzz Get IOExternalMethodDispatch sMethods[] Get IOExternalMethod methodTemplate[] 39
  • 40. How For the IOKit drivers without source code Reverse the KernelCache with symbol problem resolved IOKit structure you should know IOExternalMethodDispatch & IOExternalMethod Filter the IOKit keywords in the IDA name window sMethods etc. Will list all the IOKit drivers interface 40
  • 41. sMethods We have the interface names & address 41
  • 42. sMethods But there are just bytes in the method dispatch table IDA pro currently not handle it properly 42
  • 43. sMethods After some manually work (Mark to the DCD) We can see some function pointers, but still ugly 43
  • 44. Work Todo Need some IDA Python works here Add IOKit struct information in the idb file (IOExternalMethodDispatch & IOExternalMethod) Find the dispatch table range and mark it to the correct struct. 44
  • 45. Result Looks better now We have dispatch function, flag, input/output count. 45
  • 46. Correct Input Flags defines I = input O = output For example, type 3 means: Struct input & output We must pass the correct input/output type and count, otherwise the request will be rejected Start coding your own actively fuzzer! 46
  • 47. Extra You can also add the vtable information if you like to audit code Before After 47
  • 48. Content iOS Kernel Basics Summary of Known Bugs Passive Fuzz Active Fuzz Analyze Real Bug Conclusion 48
  • 49. Are There Bugs? Definitely YES Crashes could be easily generated by our fuzzer Actually kernel code of iOS is not as good as you imagine However analyzing crash is a hard job No code or symbols for most IOKit drivers Kernel debug is kinda of crap Any exploitable bug? This is a QUESTION 49
  • 50. IOKit Bug Analysis Simplify crash code Code is generated by fuzzer - there are many IOConnectCallMethod calls Simplify the code could help you a lot when doing static analysis Look at panic log fault_type & register values Static analysis Understand the bug and trigger path Debug Write exploit 50
  • 51. Bug Sample I Let’s look at the code first 51
  • 52. Bug Sample I Then the panic log PC = 0x80455c3c fault_addr = 0x0 52
  • 53. Bug Sample I Where did it crash Try to read data at R1(=0) cause the panic R1 is the second parameter of this function It is mostly like a NULL ptr reference bug :( We shall dig deeper anyway 53
  • 54. Bug Sample I Locate sMethod array First to find AppleVXD375UserClient::externalMethod, which should overwrite IOUserClient’s method IOUserClient has symbols, see vtable for it externalMethod pointer offset in vtable 54
  • 55. Bug Sample I Locate sMethod array Search IOUserClient::registerNotificationPort address in “const” segment Find externalMethod pointer in vtable for AppleVXD375UserClient AppleVXD375UserClient::externalMethod Get IOExternalMethodDispatch struct from sMethod array Call IOUserClient::externalMethod to dispatch it 55
  • 56. Bug Sample I sMethod = 0x80469700 56
  • 57. Bug Sample I selector = 1 dispatch struct in sMethod function address = 0x80457534 checkStructureInputSize = 0x4 checkStructureOutputSize = 0x108 Remember the trigger code? 57
  • 58. Bug Sample I The whole call path externalMethod -> sub_ 80457534 -> sub_ 804577EC -> sub_8045779C -> sub_80456768 -> sub_80455C34 -> panic sub_ 804577EC call OSObject::release first This method should be used to destroy AppleVXD375UserClient itself sub_8045779C should be responsible for freeing memory R1(=0) maybe some class or struct address stored in AppleVXD375UserClient object 58
  • 59. Bug Sample I Understand this bug We manually try to destroy AppleVXD375UserClient When in procedure, it will manipulate some object without checking if it is already created Lacks of basic check code like if (obj->ptr != NULL) We are not able to control PC register 59
  • 60. Bug Sample II Code first 60
  • 61. Bug Sample II Panic log PC = 0x00000000 Looks better than last one 61
  • 62. Bug Sample II Where did it crash We got useless PC and no call stack But luckily we had LR - store return address Looks like calling method of certain object R4 - object pointer R0 - vtable 62
  • 63. Bug Sample II Crash code snapshot 63
  • 64. Bug Sample II Crash code analysis Input R0 - IOAccelUserClient *self R1 - int index IOAccel *service = self + 0x78 OSObject *array[] = service + 0x10 Call array[index]->method = NULL 64
  • 65. Bug Sample II Weird Why the object’s method pointer is NULL Guess Mistake it as a different object without checking Todo Figure out what’s at 0x10 offset 65
  • 66. Bug Sample II Locate external methods This time it overwrite getTargetAndMethodForIndex 66
  • 67. Bug Sample II IOExternalMethod methodTemplate[5] 67
  • 68. Bug Sample II Where is selector 6 function ? Check reference to IOAccelUserClient::vtable It has a child object - IOIMGSGXUserClient Easy to find getTargetAndMethodForIndex again 68
  • 69. Bug Sample II When selector > 5, use its own methodTemplate[3] 69
  • 70. Bug Sample II What’s at offset 0x10 ? Look inside into selector 6 function 70
  • 71. Bug Sample II Object is created, check vtable 0x8090E5B8 0x8090E5B8+0x3C = 0x8090E5F4 71
  • 72. Bug Sample II Here is the story selector 6 function call sub_80907A4C to create an object and put it in object array at 0x10 offset selector 3 function get object pointer from the array and call its method without checking its class type Actually the child has its own create/destroy method. If the child create an object and make father to destroy it, PANIC ! Apple should call more OSMetaClassBase::safeMetaCast :P 72
  • 73. Content iOS Kernel Basics Summary of Known Bugs Passive Fuzz Active Fuzz Analyze Real Bug Conclusion 73
  • 74. Conclusion Apple should audit iOS kernel code, especially code of IOKit extensions Since debug is quite hard, static analysis according to panic log is very helpful Fuzz your own iOS kernel bug ! 74