CVE-2021-43527 Mozilla加密库NSS存在一个简单却很严重的缓存溢出漏洞
字数 1434 2025-08-07 08:21:50
CVE-2021-43527 Mozilla NSS加密库缓冲区溢出漏洞分析报告
漏洞概述
CVE-2021-43527是Mozilla加密库NSS中存在的一个严重缓冲区溢出漏洞。NSS(Network Security Services)是由Mozilla开发维护的密码学库,广泛应用于Firefox、Thunderbird、LibreOffice等主流软件中。
该漏洞由Google P0实验室安全研究员Tavis Ormandy发现并披露,其本质是由于未对证书长度进行适当限制,导致内存复制操作时触发缓冲区溢出。
漏洞复现步骤
1. 生成特殊长度的RSA-PSS密钥
openssl genpkey -algorithm rsa-pss \
-pkeyopt rsa_keygen_bits:$((16384 + 64*5)) \
-pkeyopt rsa_keygen_primes:5 \
-out bigsig.key
- 使用RSA-PSS算法
- 密钥长度设置为16384 + 64*5 = 16704位
- 使用5个素数生成密钥
- 输出到bigsig.key文件
2. 对证书进行自签名
openssl req -x509 -new \
-key bigsig.key \
-subj "/CN=BigSig" \
-sha256 \
-out bigsig.cer
- 使用x509证书格式
- 使用新生成的密钥
- 设置主题为"BigSig"
- 使用SHA-256哈希算法
- 输出到bigsig.cer文件
3. 使用NSS工具验证证书触发漏洞
vfychain -a bigsig.cer
漏洞技术分析
漏洞位置
漏洞存在于vfy_CreateContext函数中,位于NSS源代码的/nss/lib/cryptohi/secvfy.c文件477-490行。
关键代码分析
// 内存复制操作 - 漏洞触发点
memcpy(cx->u.buffer, sig->data, sigLen);
// 结构体定义
typedef struct VFYContextStr VFYContext;
struct VFYContextStr {
// ... 其他成员
union {
unsigned char buffer[1]; // 固定长度缓冲区
// ... 其他联合成员
} u;
// ... 其他成员
};
漏洞触发机制
-
可控参数:
cx->u.buffer: 固定长度的缓冲区sig->data: 完全由攻击者控制的签名数据sigLen: 可被攻击者控制的公钥长度
-
绕过检查:
- 484行检查
sigLen与sig->len是否相等 - 自签名情况下两者必然相等
- 检查通过后直接执行不安全的
memcpy
- 484行检查
-
精心构造的长度:
- 16704位(2088字节) = 16384(NSS定义的RSA_MAX_MODULUS_BITS) + 64*5
- 5个64字节分别对应:
- pkcs1RSADigestInfoLen
- pkcs1RSADigestInfo
- wincx
- hashcx
- hashobj
动态调试分析
-
启动调试:
gdb vfychain -
设置断点:
b SECKEY_SignatureLen -
观察关键值:
sigLen和sig->len均为2088(16704位/8)- 该长度正好覆盖
VFYContext结构体中的hashobj指针
-
崩溃点:
- 崩溃发生在
VFY_Begin函数的call指令 - 通过修改
bigsig.cer结尾数据可控制rax寄存器值
- 崩溃发生在
漏洞利用分析
利用条件
- 构造特定长度的证书(2088字节)
- 精心设计溢出数据覆盖
hashobj指针 - 控制程序执行流
利用限制
- 直接验证证书时
rax为随机值 - 需要人工修改证书结尾数据才能精确控制
rax
漏洞影响
受影响软件
- Firefox浏览器
- Thunderbird邮件客户端
- LibreOffice办公套件
- 其他使用NSS加密库的应用程序
潜在危害
- 远程代码执行
- 权限提升
- 系统崩溃
漏洞修复建议
-
更新到修复版本:
- NSS 3.73或更高版本
-
代码修复方案:
- 添加证书长度验证
- 使用安全的内存操作函数
经验教训
-
Fuzz测试局限性:
- Mozilla拥有强大的安全团队和fuzz工具
- 但仍多年未发现此漏洞
- 表明现有fuzz工具存在检测盲区
-
简单漏洞的持久性:
- 原理简单的漏洞可能长期存在
- 需要改进代码审计方法