目标
-
Linux 内核版本 6.1 ~ 6.5
解释
该漏洞是 Linux 内核中一个 Linux 数据包过滤和网络地址转换 (NAT) 框架 netfilter 的 nf_tables 组件中的一个 UAF 漏洞。
该漏洞发生在nftables的数据包处理中, 在nf_hook_slow()和nft_verdict_init()函数中。
以下nf_hook_slow()是该函数的一部分。
int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, conststruct nf_hook_entries *e, unsignedint s){unsignedint verdict;int ret;for (; s < e->num_hook_entries; s++) { verdict = nf_hook_entry_hookfn(&e->hooks展开收缩, skb, state);switch (verdict & NF_VERDICT_MASK) {case NF_ACCEPT:break;case NF_DROP: kfree_skb(skb); ret = NF_DROP_GETERR(verdict);if (ret != 0) // 오타 수정 ret = -EPERM;return ret;case NF_QUEUE: ret = nf_queue(skb, state, s, verdict);if (ret == 1)continue;return ret;default:break; }return0; }return1;}
上述代码nf_hook_slow()是 netfilter 模块中一个函数的一部分,该函数在循环内评估数据包处理规则。获取数据包的判决值,并根据该值和 NF_VERDICT_MASK 宏的值确定数据包处理。 verdict值表示数据包的处理结果,是用户可以设置的值。
nf_hook_slow()在函数中,如果kfree_skb()调用了NF_DROP,则数据包被释放。随后如果攻击者在NF_DROP_GETERR(verdict)中设置的verdict值为“0xFFFF0000”,则通过函数内部操作将ret值设置为-65535。然后将该值视为 NF_ACCEPT,并且数据包将继续被处理。
以下nft_verdict_init()是该函数。
staticintnft_verdict_init(conststruct nft_ctx *ctx, struct nft_data *data, struct nft_data_desc *desc, const struct_nlattr *nla){switch (data->verdict.code) {default:switch (data->verdict.code & NF_VERDICT_MASK) {case NF_ACCEPT:case NF_DROP:case NF_QUEUE:break;default:return -EINVAL; } }return0;}
nft_verdict_init()在函数中data->verdict.code,它作为设置规则的返回值,当攻击者设置值“0xFFFF0000”时,就会出现漏洞。
如果我们通过NF_VERDICT_MASK宏提取verdict.code的低16位,它就变成“0xFFFF0000 & 0x0000FFFF”,也就是“0x00000000”。由于该值表示 NF_DROP,因此该数据包被视为被丢弃。然而nf_hook_slow()在函数中丢弃数据包的处理之后,ret值会被NF_DROP_GETERR(verdict)操作设置为-65535,并作为NF_ACCEPT进行处理。
这会导致kfree_skb()释放后使用 (UAF) 的情况,其中已释放的数据包被重新处理并引用先前释放的套接字内存 (skb),然后当套接字内存再次被释放时就会发生双重释放。
修补的nft_verdict_init()功能包括:
switch (data->verdict.code) {case NF_ACCEPT:case NF_DROP:case NF_QUEUE:break;case NFT_CONTINUE: case NFT BREAK:case NFT_RETURN: data->verdict.chain-chain;break;default:return -EINVAL; }
data->verdict.code添加了值的验证。现在verdict.code该值仅处理允许的值,-EINVAL如果输入了无效值则返回 false,以防止恶意输入。这使得数据包处理能够正常进行并防止漏洞。
综上所述,该漏洞发生nf_hook_slow()在处理数据包时,错误的判定值导致已经释放的内存被引用,从而导致释放后使用 (UAF) 和双重释放问题。修补版本通过直接验证 verdict.code 值并对无效值返回错误来解决此问题。
参考
https://nvd.nist.gov/vuln/detail/cve-2024-1086
原文始发于微信公众号(Ots安全):CVE-2024-1086:Linux 内核中的释放后使用漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论