Linux内核提权(CVE-2024-1086)
2024-4-1 16:18:21 Author: mp.weixin.qq.com(查看原文) 阅读量:83 收藏

0x00 漏洞简介

Linux内核的netfilternf_tables组件中存在释放后使用漏洞,可被利用来实现本地权限提升。 nft_verdict_init() 函数允许在钩子判定中使用正值作为丢弃错误,因此当 NF_DROP 发出类似于 NF_ACCEPT 的丢弃错误时,nf_hook_slow() 函数可能会导致双重释放漏洞。

0x01 漏洞详情

nf_hook_slow()函数该函数循环遍历链中的所有规则,并在NF_DROP发出时立即停止评估(返回函数) 。

NF_DROP处理过程中,它释放数据包并允许用户使用设置返回值NF_GET_DROPERR()NF_ACCEPT在处理时使用 drop 错误使函数返回NF_DROP。经过一系列分析后,发现了一个双重释放。

// looping over existing rules when skb triggers chainint nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, const struct nf_hook_entries *e, unsigned int s){unsigned int verdict;int ret;// loop over every rulefor (; s < e->num_hook_entries; s++) {// acquire rule's verdictverdict = nf_hook_entry_hookfn(&e->hooks[s], skb, state);switch (verdict & NF_VERDICT_MASK) {case NF_ACCEPT:break;  // go to next rulecase NF_DROP:kfree_skb_reason(skb, SKB_DROP_REASON_NETFILTER_DROP);// check if the verdict contains a drop errret = NF_DROP_GETERR(verdict);if (ret == 0)ret = -EPERM;// immediately return (do not evaluate other rules)return ret;// [snip] alternative verdict casesdefault:WARN_ON_ONCE(1);return 0;}}return 1;}nf_hook_slow()内核函数,它迭代 nftables 规则。

当为 netfilter 挂钩创建判决对象时,内核允许正丢弃错误。这意味着攻击用户可能会导致以下情况,即从钩子/规则返回nf_hook_slow()时释放 skb 对象,然后返回,就像链中的每个钩子/规则都返回一样。这会导致调用者误解情况,并继续解析数据包并最终双重释放它。

// userland API (netlink-based) handler for initializing the verdictstatic int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,    struct nft_data_desc *desc, const struct nlattr *nla){u8 genmask = nft_genmask_next(ctx->net);struct nlattr *tb[NFTA_VERDICT_MAX + 1];struct nft_chain *chain;int err;// [snip] initialize memory// malicious user: data->verdict.code = 0xffff0000switch (data->verdict.code) {default:// data->verdict.code & NF_VERDICT_MASK == 0x0 (NF_DROP)switch (data->verdict.code & NF_VERDICT_MASK) {case NF_ACCEPT:case NF_DROP:case NF_QUEUE:break;  // happy-flowdefault:return -EINVAL;}fallthrough;case NFT_CONTINUE:case NFT_BREAK:case NFT_RETURN:break;  // happy-flowcase NFT_JUMP:case NFT_GOTO:// [snip] handle casesbreak;}// successfully set the verdict value to 0xffff0000desc->len = sizeof(data->verdict);return 0;}

nft_verdict_init()内核函数,构造一个netfilter verdict对象

// looping over existing rules when skb triggers chainint nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,const struct nf_hook_entries *e, unsigned int s){unsigned int verdict;int ret;for (; s < e->num_hook_entries; s++) {// malicious rule: verdict = 0xffff0000verdict = nf_hook_entry_hookfn(&e->hooks[s], skb, state);  // 0xffff0000 & NF_VERDICT_MASK == 0x0 (NF_DROP)switch (verdict & NF_VERDICT_MASK) {  case NF_ACCEPT:break;case NF_DROP:// first free of double-freekfree_skb_reason(skb,SKB_DROP_REASON_NETFILTER_DROP);  
// NF_DROP_GETERR(0xffff0000) == 1 (NF_ACCEPT)ret = NF_DROP_GETERR(verdict); if (ret == 0)ret = -EPERM;
// return NF_ACCEPT (continue packet handling)return ret; // [snip] alternative verdict casesdefault:WARN_ON_ONCE(1);return 0;}}return 1;}

nf_hook_slow()内核函数,它迭代 nftables 规则

static inline int NF_HOOK(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk,struct sk_buff *skb, struct net_device *in, struct net_device *out,int (*okfn)(struct net *, struct sock *, struct sk_buff *)){// results in nf_hook_slow() callint ret = nf_hook(pf, hook, net, sk, skb, in, out, okfn);// if skb passes rules, handle skb, and double-free itif (ret == NF_ACCEPT)ret = okfn(net, sk, skb);return ret;}

NF_HOOK()内核函数,成功时调用回调函数

释放会影响slab缓存struct sk_buff中的对象skbuff_head_cache,以及动态大小的sk_buff->head对象,范围从kmalloc-256直接来自伙伴分配器的最多4个页面(65536字节)与ipv4数据包 。

sk_buff->head对象kmalloc_reserve()通过__alloc_skb()这允许我们分配动态大小的对象。因此,我们可以从分配器分配大小从 256 65536 字节的完整页面的slab对象。

漏洞详见:https://pwning.tech/nftables/

0x02 影响版本

该漏洞影响从(包括)v5.14 到(包括)v6.6 的版本,不包括修补分支 v5.15.149>v6.1.76>v6.6.15>。这些版本的补丁于 2024 2 月发布。底层漏洞影响从 v3.15 v6.8-rc1 的所有版本(不包括已修补的稳定分支)。

0x03 漏洞验证

验证环境: ubuntu 23.04

0x04参考链接

https://github.com/Notselwyn/CVE-2024-1086


文章来源: https://mp.weixin.qq.com/s?__biz=MzI2MzA3OTgxOA==&mid=2657165462&idx=1&sn=449cfe25143f2b0e51cca7cbc5efb668&chksm=f1d4d273c6a35b655e853a017a8ce4b9bccdf19c6510614462d602dca17ac449fdc67724e844&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh