Linux eBPF JIT權限提升漏洞(CVE-2020-27194)分析與驗證

發布時間 2020-11-03

漏洞背景


近日,國外安全研究人員披露一個Linux eBPF verifier組件錯誤驗證漏洞,此漏洞源于bpf驗證系統在Linux內核中沒有正確計算某些操作的寄存器邊界跟蹤,導致本地攻擊者可以利用此缺陷進行內核信息泄露或特權提升,該漏洞編號為CVE-2020-27194。


影響范圍與防護措施


1、影響范圍
  • Linux-5.7 ~ Linux-5.8.14

  • Ubuntu 20.10

2、防護措施

  • 及時更新升級內核;

  • 將kernel.unprivileged_bpf_disabled.sysctl設置為1,臨時限制普通用戶權限。

漏洞原理與調試分析


1、漏洞原理


該漏洞和Pwn2own2020比賽中使用的CVE-2020-8835漏洞原理一致,均是錯誤計算了寄存器邊界跟蹤,導致可以繞過驗證器檢查達到越界讀寫。缺陷代碼出現在kernel/bpf/verifier.c的scalar32_min_max_or()函數中,該函數是在commit_id:3f50f132d840中引入的,該功能實現了顯式的ALU32(32位計算類操作)寄存器邊界跟蹤,處理OR運算時,調用scalar32_min_max_or()函數進行32位寄存器邊界跟蹤,該函數實現如下:



行5365和行5366,直接將dst_reg寄存器中的64位無符號值賦值給32位有符號值,這明顯是錯誤的。例如設置dst_reg->umin_value=1,dst_reg->umax_value=0x600000001,當進行如上操作后,dst_reg->s32_min_value為1,但是dst_reg->s32_max_value也將是1,因為0x600000001的高位將被截斷,這時dst_reg寄存器的范圍從[1,0x600000001]變成了[1,1],這會被驗證器識別為常數1,進而繞過驗證器檢查。漏洞補丁中,進行了正確的32位有符號值賦值操作,如下所示:


 


2、調試分析


首先將寄存器的umin_value設置為0x1,可以通過如下BPF指令實現:



此時,寄存器的狀態如下所示:



設置完umin_value后,設置umax_value為0x600000001,可以通過如下BPF指令實現:



斷點命中后,調用棧如下所示:



執行完BPF_JMP_REG(BPF_JLT,BPF_REG_6,BPF_REG_5,1)指令后,將R6寄存器范圍設置為0x1到0x600000001之間。R6寄存器狀態如下所示:



接著,設置R6寄存器中32位的無符號最小值和最大值,



設置完之后,R6寄存器狀態如下所示:



紅框中設置的值是必須要保證的,需要提前進行設置,方便后面繞過if判斷進入缺陷代碼塊中。接著設置R6寄存器32位有符號最小值和最大值,代碼如下所示:



行5355,if語句判斷不成立,會走到行5362分支中,調試情況如下所示:



觸發漏洞后,R6寄存器狀態如下:



此時s32_min_value和s32_max_value都為0x1,在驗證器中,R6寄存器的32位有符號取值為常數1。但R6寄存器的取值實際是有范圍的。接著將R6寄存器進行32位MOV到R7寄存器中,執行到如下代碼所示:



此時,src_reg寄存器如下所示:



執行MOV操作之前,R7寄存器狀態如下所示:



執行MOV操作后,R7寄存器狀態如下所示:


R7寄存器為常量1,實際運行情況下是有范圍的,可以設置為2。執行BPF_ALU64_IMM(BPF_RSH,BPF_REG_7,1)后,即R7 >>= 1,R7寄存器如下所示:



此時umin_value和umax_value為0,即為R7寄存器進行右移操作后,在驗證器中被識別為常數0,此時R7寄存器進行加減運算都不會發生越界,繞過了驗證器的邊界檢查。但是如果R7寄存器實際設置為2,2>>1為1,R7寄存器為1,此時和R7寄存器進行加減運算,達到越界讀寫。


漏洞復現


在Linux-5.7.7版本中進行漏洞利用,成功提權。



參考鏈接:


[1] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-27194

[2] https://github.com/torvalds/linux/commit/5b9fbeb75b6a98955f628e205ac26689bcb1383e

[3] https://github.com/torvalds/linux/commit/3f50f132d8400e129fc9eb68b5020167ef80a244

[4] https://scannell.me/fuzzing-for-ebpf-jit-bugs-in-the-linux-kernel/


啟明星辰積極防御實驗室(ADLab)


ADLab成立于1999年,是中國安全行業最早成立的攻防技術研究實驗室之一,微軟MAPP計劃核心成員,“黑雀攻擊”概念首推者。截止目前,ADLab已通過CVE累計發布安全漏洞近1100個,通過 CNVD/CNNVD累計發布安全漏洞900余個,持續保持國際網絡安全領域一流水準。實驗室研究方向涵蓋操作系統與應用系統安全研究、移動智能終端安全研究、物聯網智能設備安全研究、Web安全研究、工控系統安全研究、云安全研究。研究成果應用于產品核心技術研究、國家重點科技項目攻關、專業安全服務等。


1.jpg