linux漏洞緩解機制介紹

linux漏洞緩解機制介紹

這只是一篇給我這種小白看的科普文,大牛繞道。

linux各種發行版眾多,同樣的內核同樣的漏洞,往往某個發行版可以利用而另一個不能,要說起這些安全機制的演變顯得有些複雜,本文的目的就是對它們做一個淺顯的梳理。

一、應用層安全防護

1. ASLR

ASLR(Address space layout randomization,地址空間佈局隨機化)通過隨機放置數據區域的地址空間來防止攻擊者跳轉到內存的特定位置。在windows上ASLR主要包括堆棧隨機化、PEB與TEB隨機化、映像隨機化,windows系統上雖然xp時代就提出來了,但是從vista開始ASLR才真正發揮作用。

在linux上ASLR主要包括棧地址隨機化、LIBS/MMAP隨機化、EXEC隨機化、BRK隨機化、VDSO隨機化。在沒有ASLR的情況下讓程序跳轉到一個已經存在的系統函數的漏洞利用方式被稱為ret2libc。

1.1 棧地址隨機化:2.6.15內核開始支持。

1.2 LIBS/MMAP隨機化:程序每次執行動態庫都被加載到不同的內存位置。2.6.15內核開始支持。

1.3 EXEC隨機化:程序每次執行都將加載到不同的內存位置。2.6.25內核開始支持(會在第二點Built as PIE中詳細討論)。

可以這麼理解,LIBS/MMAP隨機化相當於windows中dll的隨機化,而EXEC隨機化相當於windows中exe的隨機化。

1.4 BRK隨機化:linux系統中brk和mmap這兩個系統調用用來分配內存。當brk ASLR關閉的時候,start_brk和brk都是指向bss段的尾部的;當brk ASLR開啟的時候,start_brk和brk初始位置是bss段的尾部加一個隨機的偏移。2.6.26內核開始支持。

linux漏洞緩解機制介紹

1.5 VDSO隨機化:VDSO(Virtual Dynamically-linked Shared Object,虛擬動態共享庫)將內核態的調用映射到用戶態的地址空間中,使得調用開銷更小,路徑更好。

拿x86下的系統調用舉例,傳統的int 0x80有點慢,Intel和AMD分別實現了sysenter/sysexit和syscall/sysret,即所謂的快速系統調用指令,使用它們更快,但是也帶來了兼容性的問題。

於是linux實現了vsyscall,程序統一調用vsyscall,具體的選擇由內核來決定,vsyscall的實現就在VDSO中。執行ldd /bin/sh,會發現有個linux-vdso.so.1的動態文件,而系統中卻找不到它,它就是VDSO。linux內核從2.6.18(x86/PPC)和2.6.22(x86_64)開始支持VDSO的隨機化。

linux漏洞緩解機制介紹

1.6 linux中ASLR的等級

在linux系統中ASLR被分為0,1,2三個等級,可以通過 sudo bash -c "echo 2 > /proc/sys/kernel/randomize_va_space" 設置。

0)沒有隨機化。即關閉ASLR。

1)保留的隨機化。共享庫、棧、mmap()分配的內存空間以及VDSO將被隨機化。

2)完全的隨機化。在1的基礎上,通過 brk()分配的內存空間也將被隨機化。

2. NX

NX(Non-Executable Memory,不可執行內存)類似於 windows 中的 DEP(Data Execution Prevention,數據執行保護)。Windows系統從xp sp2開始啟用DEP。

使用gcc在彙編時 --noexecstack 或在鏈接時 -z noexecstack 或者使用execstack修改ELF文件中 PT_GNU_STACK中的p_flags 可以設置程序是否需要具有可執行權限的堆棧。cat /proc/cpuinfo 在 flags 中如果有NX表示CPU支持NX。

一些BIOS廠商可能默認會禁止這個功能,不過從Ubuntu 11.04開始內核就會忽略BIOS中關於NX的設置。下面這張圖是在Ubuntu中NX的啟用情況。

linux漏洞緩解機制介紹

二、編譯器安全防護

1. Built as PIE

前面說了EXEC的隨機化,實際上更準確的說法是 PIE(Position Independent Executables,位置無關可執行文件)。PIE只有在系統開啟ASLR和編譯時開啟-fpie -pie選項這兩個條件同時滿足時才會生效。

最初因為在像x86這樣通用寄存器較少的架構上PIE的性能損失比較明顯,所以並不是所有的程序都啟用了PIE。從Ubuntu 17.10和Fedora 23開始為所有的架構都啟用了PIE。

2. Built with RELRO

RELRO(RELocation Read-Only,只讀重定位)讓加載器將重定位表中加載時解析的符號標記為只讀,這減少了GOT覆寫攻擊的面積。

RELRO可以分為Partial RELRO(部分RELRO)和 Full RELRO (完整RELRO)。開啟Partial RELRO的話GOT表是可寫的;開啟 FULL RELRO 的話GOT表是隻讀的。

從Fedora 23開始所有軟件包都已啟用了Full RELRO。開啟-Wl,-z,relro選項即可開啟Partial RELRO;開啟-Wl,-z,relro,-z,now選項即可開啟Full RELRO。

3. Stack Protector

Stack Protector又名canary,stack cookie……等等,類似於VS編譯器中的GS。gcc4.2中添加了 -fstack-protector 和 -fstack-protector-all 編譯參數以支持該功能,gcc4.9中添加了 -fstack-protector-strong 編譯參數讓保護的範圍更廣。

linux漏洞緩解機制介紹

三、內核安全防護

1.某些發行版中特有的

1)dmesg restrictions

在dmesg裡可以查看到開機信息。若研究內核代碼,在代碼中插入printk函數,然後通過dmesg觀察是一個很好的方法。從Ubuntu 12.04 LTS開始,可以將/proc/sys/kernel/dmesg_restrict 設置為1將dmesg輸出的信息當做敏感信息(默認為0)。

linux漏洞緩解機制介紹

2)Kernel Address Display Restriction

在linux內核漏洞利用中常常使用commit_creds和 prepare_kernel_cred 來完成提權,它們的地址可以從 /proc/kallsyms 中讀取。從Ubuntu 11.04和RHEL 7開始,/proc/sys/kernel/kptr_restrict 被默認設置為1以阻止通過這種方式洩露內核地址。

linux漏洞緩解機制介紹

2.所有發行版中都有的

1)KPTI

今年年初的CPU漏洞讓 KPTI(Kernel PageTable Isolation,內核頁表隔離)進入了人們的視野。進程地址空間被分成了內核地址空間和用戶地址空間,其中內核地址空間映射到了整個物理地址空間,而用戶地址空間只能映射到指定的物理地址空間。

內核地址空間和用戶地址空間共用一個頁全局目錄表。為了徹底防止用戶程序獲取內核數據,可以令內核地址空間和用戶地址空間使用兩組頁表集。linux內核從4.15開始支持KPTI,windows上把這個叫KVA Shadow,原理類似。更多細節請見參考資料。

2)KASLR

KASLR中的K指kernel,也就是內核地址空間佈局隨機化。可以在內核命令行中加入nokaslr關閉KASLR。

下面這張圖就是幾大主流操作系統(windows/linux/ios/os x/android)中ASLR和KASLR的啟用情況。不過值得注意的是Android 8.0中為4.4及以後的內核引入了KASLR。

linux漏洞緩解機制介紹

3)SMAP/SMEP

SMAP(Supervisor Mode Access Prevention,管理模式訪問保護)和SMEP(Supervisor Mode Execution Prevention,管理模式執行保護)的作用分別是禁止內核訪問用戶空間的數據和禁止內核執行用戶空間的代碼。arm裡面叫 PXN(Privilege Execute Never) 和PAN(Privileged Access Never)。

SMEP類似於前面說的NX,不過一個是在內核態中,一個是在用戶態中。和NX一樣SMAP/SMEP需要處理器支持,可以通過cat /proc/cpuinfo查看,在內核命令行中添加nosmap和nosmep禁用。

windows系統從win8開始啟用SMEP,windows內核枚舉哪些處理器的特性可用,當它看到處理器支持SMEP時通過在CR4寄存器中設置適當的位來表示應該強制執行SMEP,可以通過ROP或者jmp到一個RWX的內核地址繞過。linux內核從3.0開始支持SMEP,3.7開始支持SMAP。

在沒有SMAP/SMEP的情況下把內核指針重定向到用戶空間的漏洞利用方式被稱為ret2usr。physmap是內核管理的一塊非常大的連續的虛擬內存空間,為了提高效率,該空間地址和RAM地址直接映射。

RAM相對physmap要小得多,導致了任何一個RAM地址都可以在physmap中找到其對應的虛擬內存地址。另一方面,我們知道用戶空間的虛擬內存也會映射到RAM。

這就存在兩個虛擬內存地址(一個在physmap地址,一個在用戶空間地址)映射到同一個RAM地址的情況。也就是說,我們在用戶空間裡創建的數據,代碼很有可能映射到physmap空間。

基於這個理論在用戶空間用mmap()把提權代碼映射到內存,然後再在physmap裡找到其對應的副本,修改EIP跳到副本執行就可以了。因為physmap本身就是在內核空間裡,所以SMAP/SMEP都不會發揮作用。這種漏洞利用方式叫ret2dir。

4)Stack Protector

當然在內核中也是有這種防護的,編譯內核時設置CONFIG_CC_STACKPROTECTOR 選項即可,該補丁是Tejun Heo在09年給主線kernel提交的。

2.6.24:首次出現該編譯選項並實現了x64平臺的進程上下文棧保護支持

2.6.30:新增對內核中斷上下文的棧保護和對x32平臺進程上下文棧保護支持

3.14:對該功能進行了一次升級以支持gcc的 -fstack-protector-strong 參數,提供更大範圍的棧保護

5)address protection

由於內核空間和用戶空間共享虛擬內存地址,因此需要防止用戶空間mmap的內存從0開始,從而緩解NULL解引用攻擊。windows系統從win8開始禁止在零頁分配內存。

從linux內核2.6.22開始可以使用sysctl設置mmap_min_addr 來實現這一保護。從Ubuntu 9.04開始,mmap_min_addr設置被內置到內核中(x86為64k,ARM為32k)。

想了想還缺glibc一些東西,但是這個資料比較多,篇幅也較長,所以就不寫了。一些稍微冷門一點的由於不太熟悉,也沒寫了。

1.Fedora Security Features

2.Ubuntu Security Features

3.Debian Security Features

4.linux kernel defence map

5.Address space layout randomization

6.Vulnerability and threat mitigation features in Red Hat Enterprise Linux

7.Breaking Kernel Address Space Layout Randomization with Intel TSX

8.CPU漏洞分析彙總貼

9.原創技術乾貨|解讀Linux安全機制之棧溢出保護

原文出自:[原創]linux漏洞緩解機制介紹-『二進制漏洞』-看雪安全論壇


分享到:


相關文章: