簡體   English   中英

PAGE_EXECUTE_READWRITE 作為 VirtualAlloc 中的一個選項的存在是否意味着 W^X 僅由 DEP 在 Windows 中提供便利?

[英]Does the existence of PAGE_EXECUTE_READWRITE as an option in VirtualAlloc mean that the W^X is only facilitated in Windows by DEP?

W^X(“write xor execute”,發音為 W xor X)是操作系統和虛擬機中的一項安全功能。 這是一個 memory 保護策略,進程或內核地址空間中的每個頁面都可以是可寫的或可執行的,但不能兩者兼而有之。

我對為什么這是一個很好的安全功能的基本觀點是,系統的所有者理論上有機會在 kernel 內,或者特別是在 VirtualAlloc function 內,掛鈎一些分析 ZC1C425268E68385D14ZA5074 之前允許新編寫的代碼執行一些安全驗證在機器上執行。

我已經熟悉DEP ,但直到現在才意識到它與 Windows 中的 W^X 有關:

Windows 上的可執行空間保護稱為“數據執行保護”(DEP)。 在 Windows XP 或 Server 2003 NX 下,默認情況下僅對關鍵 Windows 服務使用保護。 如果 x86 處理器在硬件上支持此功能,則在 Windows XP/Server 2003 中默認自動打開 NX 功能。 如果 x86 處理器不支持該功能,則不提供保護。 DEP 的早期實現沒有提供地址空間布局隨機化 (ASLR),這允許潛在的返回 libc 攻擊,這些攻擊本可以在攻擊期間用於禁用 DEP。

我的印象是 W^X一般適用於 Windows ,無需配置流程。 但我只是注意到VirtualProtect允許選項PAGE_EXECUTE_READWRITE ,它被記錄為:

啟用對已提交頁面區域的執行、只讀或讀/寫訪問。

這似乎完全違背了 W^X 的概念。 那么 W^X 不是 Windows 上的強制安全策略,除非啟用 DEP?

如果您關閉 DEP,則不會強制執行 W^X。 當 DEP 打開時,W^X 由所有要求它的 memory 頁面強制執行(當硬件支持它時)。 它是x86上頁表中的第63位,稱為NX位。

現在問題變成了,這個位是什么時候設置的?

PE header 有一個位指示是否支持 DEP/W^X ( IMAGE_DLLCHARACTERISTICS_NX_COMPAT ),如果支持,當該代碼映射到 memory 時,文件中沒有寫入屬性的代碼部分將設置 NX 位。

對於在運行時動態分配的 memory,開發人員可以進行選擇。 PAGE_EXECUTE_READWRITE沒有故意設置 NX 位。 如果他們有舊代碼可以動態更改可執行代碼,同時仍然在 PE 上設置了 DEP 位,那么這很有用,因此他們的大部分代碼是 W^X。

早期的 x86 CPU 不支持未經 eXec 許可的頁面。 傳統的 32 位 x86 頁表中,只有一個用於寫入權限的位,即 R/W 位。 (讀取權限始終隱含在有效頁面中,無論該頁面是否可寫)。 x86-64 也使用的頁表條目的 PAE 格式添加了一個 NX 位(“no exec”),又名 XD(eXecute Disable)。

操作系統仍然必須決定哪些頁面不可執行。 Windows 似乎使用 DEP 來描述將邏輯頁權限實際映射到硬件頁表的特性,由 CPU 強制執行。

在糟糕的過去,當每個可讀頁面都是可執行的時,一些程序可能會草率地告訴操作系統他們希望頁面是可執行的。 尤其是那些只針對 32 位 x86 的。 這就是 Windows 通過要求可執行文件選擇加入 DEP 來滿足的要求,以表明它們知道並兼容沒有對未明確標記為這種方式的頁面的 exec 權限。


一些操作系統,尤其是 OpenBSD,真正強制執行W^X。 例如, mmap(..., PROT_WRITE | PROT_EXEC, ...)將在 OpenBSD 上返回錯誤。 他們的mmap(2)手冊頁記錄了這樣的 mmap 或 mprotect 系統調用將返回

[ENOTSUP] 不允許在prot參數中請求的訪問。 特別是PROT_WRITE | PROT_EXEC PROT_WRITE | PROT_EXEC映射是不允許的,除非文件系統被掛載wxallowed並且進程在鏈接時被標記為wxneeded (有關診斷故障的方法,另請參見sysctl(2)中的kern.wxabort )。


大多數其他操作系統(包括 Linux 和 Windows)允許用戶空間同時創建可寫和可執行的頁面。 但是,如果您不使用gcc -zexecstack類的任何選項,標准工具鏈和動態鏈接機制默認針對 W^X 合規性,這將使操作系統創建帶有一些 R|W|X 頁面的進程映像。

Older 32-bit x86 Linux for example used to use PLT entries (dynamic linking stubs) with jmp rel32 direct jumps, and rewrite the machine code to have the right displacement to reach wherever the shared library got loaded in memory. 但是現在,PLT 代碼使用間接跳轉(通過 GOT = 全局偏移表),因此可執行的 PLT 代碼可以位於只讀頁面中。

像這樣的更改已經消除了使用標准工具構建的正常進程中對 write+exec 頁面的任何需求

但是在 Windows、MacOS 和 Linux 上,操作系統不強制執行W^X。 像 Windows VirtualAlloc / VirtualProtect和它們的 POSIX 等效項mmap / mprotect這樣的系統調用可以正常工作。

@Ander 的回答說 DEP 不強制執行 W^X,只是讓操作系統在為 .text /.data /.bss 和堆棧空間創建初始映射時尊重可執行文件中的 exec 權限設置,以及在進程啟動期間的類似內容.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM