KASLR繞過及提權利用(CVE-2023-35001)

前言

本文將介紹如何繞過KASLR以及如何提權利用。

KASLR繞過

可以利用byteorder操作加上netlink組訂閱可以泄露rule中的handle字段。該方法應該是可以用來泄露kernel基地址的,但是作者還提出另一種方法進行泄露。應該是爲了提權利用做鋪墊。

由於發現已經泄露的模塊的基地址,因此可以利用模塊地址僞造表達式。

作者找到了range表達式,用於僞造其餘表達式。總大小爲0x23。並且表達式是八字節對齊的,因此該結構體會佔用0x28字節。

struct nft_range_expr {
    struct nft_data     data_from;
    struct nft_data     data_to;
    u8          sreg;
    u8          len;
    enum nft_range_ops  op:8;
};

具體的佈局如下

image-20240227185357673

可以看到data_fromdata_to都是從用戶態中傳遞過去的數據,因此我們可以在這些區域內僞造表達式,這有點像在CTF中,我們泄露了堆塊基址後,隨意僞造堆塊。

由於我們有0x28字節的空間,但是實際能夠操作的空間是data_fromdata_to兩段,即0x20的空間大小。因此我們需要挑選小於0x20的規則表達式進行僞造,並且能夠執行泄露功能的。

這裏作者選用了byteorder表達式,可以看到該表達式在對齊後只佔用八字節。

struct nft_byteorder {
    u8          sreg;
    u8          dreg;
    enum nft_byteorder_ops  op:8;
    u8          len;
    u8          size;
};

構造後,可以發現還有八字節的data_to沒有用,但是並不能直接丟棄不適用,因爲在調用完byteorder操作後還需要繼續執行其他規則表達式。

image-20240227190243722

但是其他表達式都是需要大於0x8的,畢竟一個操作指針就佔用八字節了,此時作者選用了meta表達式。可以看到meta表達式也只用到了三個字節,剛好對應range表達式的sreglen以及op

struct nft_meta {
    enum nft_meta_keys  key:8;
    u8          len;
    union {
        u8      dreg;
        u8      sreg;
    };
};

meta表達式的操作如下,在meta表達式中meta->key執行具體的操作,如[1],但是若該值是非法值則會執行[2],可以看到該meta表達式僅會拋出異常,但是不會終止運行,這就說明即使meta->key是非法值也不會影響後續規則表達式的正常執行。

File: linux-5.19\net\netfilter\nft_meta.c
418: void nft_meta_set_eval(const struct nft_expr *expr,
419:               struct nft_regs *regs,
420:               const struct nft_pktinfo *pkt)
421: {
422:    const struct nft_meta *meta = nft_expr_priv(expr);
423:    struct sk_buff *skb = pkt->skb;
424:    u32 *sreg = &regs->data[meta->sreg];
425:    u32 value = *sreg;
426:    u8 value8;
427: 
428:    switch (meta->key) { ----> [1]
429:    case NFT_META_MARK:
430:        skb->mark = value;
431:        break;
432:    case NFT_META_PRIORITY:
433:        skb->priority = value;
434:        break;
435:    case NFT_META_PKTTYPE:
436:        value8 = nft_reg_load8(sreg);
437: 
438:        if (skb->pkt_type != value8 &&
439:            skb_pkt_type_ok(value8) &&
440:            skb_pkt_type_ok(skb->pkt_type))
441:            skb->pkt_type = value8;
442:        break;
443:    case NFT_META_NFTRACE:
444:        value8 = nft_reg_load8(sreg);
445: 
446:        skb->nf_trace = !!value8;
447:        break;
448: #ifdef CONFIG_NETWORK_SECMARK
449:    case NFT_META_SECMARK:
450:        skb->secmark = value;
451:        break;
452: #endif
453:    default:
454:        WARN_ON(1); ---->[2]
455:    }
456: }

因此第二個僞造的表達式也找到了,就是meta表達式。由於我們直接僞造了規則表達式,因此不會進行寄存器參數的校驗,只要選擇內核地址選擇泄露即可。

image-20240227191748571

這裏簡單說一下僞造的規則頭,此時的len需要設置爲0x20以及islast需要設置爲0。

最後泄露的效果如下,即使內核已經拋出了異常,但是不會影響後續表達式的正常執行。

image-20240227192131407

【---- 幫助網安學習,以下所有學習資料免費領!領取資料加 we~@x:dctintin,備註 “開源中國” 獲取!】

① 網安學習成長路徑思維導圖
② 60 + 網安經典常用工具包
③ 100+SRC 漏洞分析報告
④ 150 + 網安攻防實戰技術電子書
⑤ 最權威 CISSP 認證考試指南 + 題庫
⑥ 超 1800 頁 CTF 實戰技巧手冊
⑦ 最新網安大廠面試題合集(含答案)
⑧ APP 客戶端安全檢測指南(安卓 + IOS)

提權利用

既然可以隨意僞造表達式,因此我們可以僞造payload表達式。

struct nft_payload {
    enum nft_payload_bases  base:8;
    u8          offset;
    u8          len;
    u8          dreg;
};

image-20240227194109554

regs下方存在着nft_do_chain函數返回地址,因此可以直接通過payload表達式將提權payload注入進來。

image-20240227194544551

由於我們可以僞造payload表達式,因此注入的payload長度不受限,因此採用

  • commit_creds(prepare_kernel_cred(0)),構造root憑證

  • 接着利用find_task_by_vpidinit_nsproxy以及switch_task_namespaces切換命名空間。

  • 最後利用蹦牀swapgs_restore_regs_and_retrun_to_usermode返回到用戶空間完成提權利用。

image-20240227195613084

完整exphttps://github.com/h0pe-ay/Vulnerability-Reproduction/tree/master/CVE-2023-35001(nftables)

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章