<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    CVE-2022-23222:Linux 內核 eBPF 本地權限提升

    VSole2022-10-18 09:41:08

    近期在對Linux eBPF進行代碼審計的過程中,發現了一枚權限提升漏洞CVE-2022-23222。    此漏洞影響Linux Kernel 5.8 - 5.16,并在5.10.92 / 5.15.15 / 5.16.1中修復。完整利用代碼詳見:https://github.com/tr3ee/CVE-2022-23222----[ 1.1 - eBPF verifer

    我們在寫eBPF程序時,會發現調用bpf_map_lookup_elem()返回的結果,一定要判斷是否為NULL,否則就會被拒

    絕加載。因為,bpf_map_lookup_elem()運行結果的結果,可能是有效的指針,但也可能返回NULL來表示沒有查找到與key相關的值。在eBPF中有很多類似的用法,那么eBPF verifi er是如何跟蹤這些值的類型呢?* bpf.h *

    /* types of values stored in eBPF registers */
    /* Pointer types represent:
     * pointer
     * pointer + imm
     * pointer + (u16) var
     * pointer + (u16) var + imm
     * if (range > 0) then [ptr, ptr + range - off) is safe to access
     * if (id > 0) means that some 'var' was added
     * if (off > 0) means that 'imm' was added
     */
    enum bpf_reg_type {
        NOT_INIT = 0,         /* nothing was written into register */
        SCALAR_VALUE,         /* reg doesn't contain a valid pointer */
        PTR_TO_CTX,           /* reg points to bpf_context */
        CONST_PTR_TO_MAP,     /* reg points to struct bpf_map */
        PTR_TO_MAP_VALUE,     /* reg points to map element value */
        PTR_TO_MAP_VALUE_OR_NULL,  /* points to map elem value or NULL */
        PTR_TO_STACK,         /* reg == frame_pointer + offset */
        PTR_TO_PACKET_META,   /* skb->data - meta_len */
        PTR_TO_PACKET,        /* reg points to skb->data */
        PTR_TO_PACKET_END,    /* skb->data + headlen */
        PTR_TO_FLOW_KEYS,     /* reg points to bpf_flow_keys */
        PTR_TO_SOCKET,        /* reg points to struct bpf_sock */
        PTR_TO_SOCKET_OR_NULL,      /* reg points to struct bpf_sock or NULL */
        PTR_TO_SOCK_COMMON,   /* reg points to sock_common */
        PTR_TO_SOCK_COMMON_OR_NULL, /* reg points to sock_common or NULL */
        PTR_TO_TCP_SOCK,      /* reg points to struct tcp_sock */
        PTR_TO_TCP_SOCK_OR_NULL,    /* reg points to struct tcp_sock or NULL */
        PTR_TO_TP_BUFFER,     /* reg points to a writable raw tp's buffer */
        PTR_TO_XDP_SOCK,      /* reg points to struct xdp_sock */
        /* PTR_TO_BTF_ID points to a kernel struct that does not need
         * to be null checked by the BPF program. This does not imply the
         * pointer is _not_ null and in practice this can easily be a null
         * pointer when reading pointer chains. The assumption is program
         * context will handle null pointer dereference typically via fault
         * handling. The verifier must keep this in mind and can make no
         * assumptions about null or non-null when doing branch analysis.
         * Further, when passed into helpers the helpers can not, without
         * additional context, assume the value is non-null.
         */
        PTR_TO_BTF_ID,
        /* PTR_TO_BTF_ID_OR_NULL points to a kernel struct that has not
         * been checked for null. Used primarily to inform the verifier
         * an explicit null check is required for this struct.
         */
        PTR_TO_BTF_ID_OR_NULL,
        PTR_TO_MEM,           /* reg points to valid memory region */
        PTR_TO_MEM_OR_NULL,   /* reg points to valid memory region or NULL */
        PTR_TO_RDONLY_BUF,    /* reg points to a readonly buffer */
        PTR_TO_RDONLY_BUF_OR_NULL,  /* reg points to a readonly buffer or NULL */
        PTR_TO_RDWR_BUF,      /* reg points to a read/write buffer */
        PTR_TO_RDWR_BUF_OR_NULL,    /* reg points to a read/write buffer or NULL */
        PTR_TO_PERCPU_BTF_ID,       /* reg points to a percpu kernel variable */
    };
    

        上面是eBPF中寄存器的完整類型列表,可以知道它通過`*_OR_NULL`類型來表示一個未知的指針類型。當寄存器的類型是`*_OR_NULL`時,它能做的操作是很有限的,一般只能進行NULL比較或者作為參數調用輔助函數。    一個類型為`*_OR_NULL`的寄存器做完!=NULL的比較后,才可能變為`PTR_TO_*`類型,或者`SCALAR_VALUE`也就是數值0。----[ 1.2 - 漏洞分析* C *

    /* Handles arithmetic on a pointer and a scalar: computes new min/max and var_off.
     * Caller should also handle BPF_MOV case separately.
     * If we return -EACCES, caller may want to try again treating pointer as a
     * scalar.  So we only emit a diagnostic if !env->allow_ptr_leaks.
     */
    static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
                       struct bpf_insn *insn,
                       const struct bpf_reg_state *ptr_reg,
                       const struct bpf_reg_state *off_reg)
    {
    ...
        switch (ptr_reg->type) {
        case PTR_TO_MAP_VALUE_OR_NULL:
            verbose(env, "R%d pointer arithmetic on %s prohibited, null-check it first\n",
                dst, reg_type_str[ptr_reg->type]);
            return -EACCES;
        case CONST_PTR_TO_MAP:
            /* smin_val represents the known value */
            if (known && smin_val == 0 && opcode == BPF_ADD)
                break;
            fallthrough;
        case PTR_TO_PACKET_END:
        case PTR_TO_SOCKET:
        case PTR_TO_SOCKET_OR_NULL:
        case PTR_TO_SOCK_COMMON:
        case PTR_TO_SOCK_COMMON_OR_NULL:
        case PTR_TO_TCP_SOCK:
        case PTR_TO_TCP_SOCK_OR_NULL:
        case PTR_TO_XDP_SOCK:
            verbose(env, "R%d pointer arithmetic on %s prohibited\n",
                dst, reg_type_str[ptr_reg->type]);
            return -EACCES;
        default:
            break;
        }
    ...
        return 0;
    }
    

        上面的代碼中adjust_ptr_min_max_vals()是eBPF verifier用于檢驗指針加減運算的函數。其中的switch分支用于過濾不支持加減運算的指針類型,比如各種OR_NULL類型。但是這個switch分支卻少了很多類型的判斷,比如`PTR_TO_MEM_OR_NULL`, `PTR_TO_RDONLY_BUF_OR_NULL`,`PTR_TO_RDWR_BUF_OR_NULL`。這意味著,我們可以對一些OR_NULL類型做加減運算!

    參考資料

    [1] Advisory: https://www.openwall.com/lists/oss-security/2022/01/13/1[2] Exploit Overview: https://www.openwall.com/lists/oss-security/2022/01/18/2[3] Patch: []()[4] Source: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/kernel/bpf/verifier.c?h=v5.10.83
    
    linux系統kernel
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    處于用戶態的程序只能執行非特權指令, 如果需要使用某些特權指令。
    拿到一臺 linux 主機普通權限之后,如何獲取更高的 root 權限?0x01 查看操作系統信息,內核版本等查看操作系統類型:cat /etc/issue?ls /boot | grep vmlinuz-可以看到當前系統是 64 位。
    360漏洞云監測到Linux kernel存在拒絕服務漏洞(CVE-2021-38207)。
    360漏洞云監測到Linux kernel存在信息泄露漏洞(CVE-2021-34556, CVE-2021-35477)。
    2021年12月23日,360漏洞云團隊在互聯網上監測到一則關于Linux kernel中存在競爭漏洞的信息。漏洞編號: CVE-2021-20321,漏洞威脅等級:中危。
    s等命令用于socket狀態。他可以顯示PACKET sockets,TCP sockets,UDP sockets,DCCP sockets,RAW sockets,Unix domain sockets。它比其他工具展示等多tcp和狀態信息。它是一個非常實用、快速、有效的跟蹤 IP 連接和套接字的新工具。
    "請用root用戶執行此腳本!#最近啟動時間?#運行時間(天)?#相同ID的用戶?#密碼過期(天)?#允許root遠程登錄?#僵尸進程數量?#自啟動服務數量?"系統巡檢腳本:Version $VERSION"
    360漏洞云監測到安全研究人員近日公開了Linux kernel eBPF本地提權漏洞(CVE-2021-3490)的POC。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类