Lucene search

K
myhack58佚名MYHACK58:62201785818
HistoryMay 04, 2017 - 12:00 a.m.

In-depth analysis of exception-based iOS exploit technology-vulnerability warning-the black bar safety net

2017-05-0400:00:00
佚名
www.myhack58.com
164

0.006 Low

EPSS

Percentile

78.1%

This article will provide the reader a detailed description numbered CVE-2017-2370 mach_voucher_extract_attr_recipe_trap mach trap heap overflow discovery and use of the process. Here not only describes this vulnerability itself, but also to explain a loophole in the use of technology development process, including how to repeatedly and intentionally cause the system to crash, as well as how to use the old kernel vulnerability building activities of kernel introspection functions.
This is a trap!
In addition to a large number of BSD system calls such as ioctl, mmap and execve, etc. besides, the MAP also provides a few other system calls, often referred to as the mach trap, used for kernel MACH characteristics of the support. Mach traps the system call number is from 0x1000000 to start. The following code from the definition of the trap table syscall_sw. c file:
/* 12 / MACH_TRAP(_kernelrpc_mach_vm_deallocate_trap, 3, 5, munge_wll),
/
13 / MACH_TRAP(kern_invalid, 0, 0, NULL),
/
14 */ MACH_TRAP(_kernelrpc_mach_vm_protect_trap, 5, 7, munge_wllww),
For most of the Mach trap, which is actually the core API of the flash channel, and also through the standard MACH MIG kernel API to the outside world provides the interface. For example, mach_vm_allocate is also a the task can be port of Call of the MIG RPC.
By avoiding calls to the kernel MIG API relates to the serialization and deserialization of the cause of the overhead, and therefore the Mach trap to for these kernel functions provide a faster interface. However, since there is no complex code automatically generated features, so the mach traps are usually needed to manually complete the parameter analysis, however, to properly finish the job, then it is very needed skills.
In iOS 10, mach_traps the table appears a new entry:

/* 72 */ MACH_TRAP(mach_voucher_extract_attr_recipe_trap, 4, 4, munge_wwww),
mach trap entry code from the user space is passed to the trap of the parameters Packed into a structure as shown below:
struct mach_voucher_extract_attr_recipe_args {
PAD_ARG_(mach_port_name_t, voucher_name);
PAD_ARG_(mach_voucher_attr_key_t, key);
PAD_ARG_(mach_voucher_attr_raw_recipe_t, recipe);
PAD_ARG_(user_addr_t, recipe_size);
};
And then will point to the structure pointer as the first parameter passed to the trap of the implementation code. It is worth noting that, add a new system call, we can from the system on each sandboxed process calling it. Until you reach the one without the sandbox protection of the mandatory access control hooks and here also not so far.
We look at the trap code:
kern_return_t
mach_voucher_extract_attr_recipe_trap(
struct mach_voucher_extract_attr_recipe_args *args)
{
ipc_voucher_t voucher = IV_NULL;
kern_return_t kr = KERN_SUCCESS;
mach_msg_type_number_t sz = 0;
if (copyin(args->recipe_size, (void )&sz, sizeof(sz)))
return KERN_MEMORY_ERROR;
On Linux, copyin having copy_from_user similar semantics. It will be from the user space pointer args-> recipe_size in the 4 bytes is copied to the kernel stack on of the sz variables, to ensure that the entire source zone Real is located in the user space, if the source segment is not completely mapped or point to the kernel, it returns an error code. Thus, the attacker can control the sz variable.
if (sz > MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE)
return MIG_ARRAY_TOO_LARGE;
Due to the mach_msg_type_number_t is a 32-bit unsigned type, so sz must be less than or equal to MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE(5120 in.
voucher = convert_port_name_to_voucher(args->voucher_name);
if (voucher == IV_NULL)
return MACH_SEND_INVALID_DEST;
convert_port_name_to_voucher in the calling task mach port namespace lookup args-> voucher_name mach port name, and check whether it is named a ipc_voucher object, if Yes, then returns the credentials of the references. Therefore, we need to provide a valid credential port, for processing voucher_name it.
if (sz
/
keep small recipes on the stack for speed */
uint8_t krecipe[sz];
if (copyin(args->recipe, (void *)krecipe, sz)) {
kr = KERN_MEMORY_ERROR;
goto done;
}
kr = mach_voucher_extract_attr_recipe(voucher,
args->key, (mach_voucher_attr_raw_recipe_t)krecipe, &sz);
if (kr == KERN_SUCCESS && sz > 0)
kr = copyout(krecipe, (void *)args->recipe, sz);
}
If sz is less than MACH_VOUCHER_TRAP_STACK_LIMIT(256οΌ‰, then this will be the kernel stack allocate a small variable-length array, and args-> the recipe in the user pointer of sz bytes is copied to the VLA. Then, the code in the call to copyout, which requires the kernel and user space parameters, the role and copyin the opposite will be the result sent back to the user space before calling the target mach_voucher_extract_attr_recipe method. Well, here let’s see if the sz is too large, in order to maintain speed continue to let it stay on the stack what happens:
else {
uint8_t *krecipe = kalloc((vm_size_t)sz);
if (! krecipe) {
kr = KERN_RESOURCE_SHORTAGE;
goto done;
}
if (copyin(args->recipe, (void *)krecipe, args->recipe_size)) {
kfree(krecipe, (vm_size_t)sz);
kr = KERN_MEMORY_ERROR;
goto done;
}
We may wish to carefully look at this code snippet. It calls kalloc the kernel allocated on the heap over a period of sz bytes of memory, and the corresponding address points assigned to krecipe it. And then call the copyin, according to args-> recipe user-space pointer to copy args-> recipe_size bytes to krecipe kernel heap buffer.

[1] [2] [3] [4] [5] [6] [7] next

0.006 Low

EPSS

Percentile

78.1%