Lucene search

K
zdtGoogle Security Research1337DAY-ID-30278
HistoryMay 01, 2018 - 12:00 a.m.

macOS 10.13.2 - Double mach_port_deallocate in kextd due to Failure to Comply with MIG Ownership Rul

2018-05-0100:00:00
Google Security Research
0day.today
16

0.003 Low

EPSS

Percentile

65.2%

Exploit for macOS platform in category dos / poc

Here's a kextd method exposed via MIG (com.apple.KernelExtensionServer)
 
  kern_return_t _kextmanager_unlock_kextload(
      mach_port_t server,
      mach_port_t client)
  {
      kern_return_t mig_result = KERN_FAILURE;
       
      if (gClientUID != 0) {
          OSKextLog(/* kext */ NULL,
              kOSKextLogErrorLevel | kOSKextLogIPCFlag,
              "Non-root kextutil doesn't need to lock/unlock.");
          mig_result = KERN_SUCCESS;
          goto finish;
      }
       
      if (client != (mach_port_t)dispatch_source_get_handle(_gKextutilLock)) {
          OSKextLog(/* kext */ NULL,
              kOSKextLogErrorLevel | kOSKextLogIPCFlag,
              "%d not used to lock for kextutil.", client);
          goto finish;
      }
 
      removeKextutilLock();
       
      mig_result = KERN_SUCCESS;
       
  finish:    
      // we don't need the extra send right added by MiG
      mach_port_deallocate(mach_task_self(), client);
       
      return mig_result;
  }
 
If the client has UID 0 but passes an invalid client port this code will
drop a UREF on client port then return KERN_FAILURE.
 
Returning KERN_FAILURE in MIG means all resources will be released which will
cause client to be passed to mach_port_deallocate again, even though only 
one UREF was taken.
 
You'll have to use a debugger attached to kextd to see this behaviour.
 
This class of bug is exploitable; please see the writeup for mach_portal from 2016
where I exploited a similar issue [https://bugs.chromium.org/p/project-zero/issues/detail?id=959]
The TL;DR is that an attacker can drop an extra UREF on any send rights in kextd for which the
attacker also has a send right; you could use this to cause a name for a privileged service
to be deallocated then cause the name to be reused to name a port you control.
 
Exploitation of this would be a privesc from unentitled root to root with
com.apple.rootless.kext-management and com.apple.rootless.storage.KernelExtensionManagement entitlements,
which at least last time I looked was equal to kernel code execution.
 
tested on MacOS 10.13.2
 
 
Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/44561.zip

#  0day.today [2018-05-07]  #

0.003 Low

EPSS

Percentile

65.2%