# ARM hardware bug to bypass PAN ###### tags: `exploitation` twitter 上看的別人發表的 blog ,講述 arm 在晶片實作上的錯誤導致可以繞過 PAN 保護 [資料](https://siguza.github.io/PAN/) * 基本名詞解釋: * PAN (Privileged Access Never) = SMAP * ELX * EL0: user space * EL1: kernel space ## 簡介 Arm 在硬體實作上支援一種 execute-only 的 mapping ,讓為在 EL0 的 user 可以執行高權限的 mapping 裡面的 code But, EL1 的 kernel 可以去讀取該 mapping 的資料而不會觸發 PAN 理由有 2: 1. PAN 忽略 UXN bit 而且僅在 user 權限為 read 的時候才會觸發 (後面會提) 2. 在 kernel 內無論什麼 map 都會被視為可讀 * 能否執行要看 UXN, PXN 兩個 bit ,但 read 權限是一定有的 ## 不是很詳細的介紹 在 memory page 的權限中可以分為三種: RWX ,而權限還要區分是 user space 還是 kernel space ,所以應該要有六個 bit 控管權限問題 但是根據 arm v8 manual 對於權限的介紹可以發現他們只用了 4 個 bit ![](https://i.imgur.com/wQ2vhAa.png) 其中 UXN, PXN 是兩個執行權限的 bit ,管理 RW 的 bit 只有兩個,而這兩個 bit 的表格是這樣的: ![](https://i.imgur.com/tfXeoG0.png) 可以發現 higher exception level 不論什麼排列都必定有 read 權限 這導致當你在 userland map 一個 --x 的 page ,實際上權限是這樣的 r--/--x (kernel/user) 再看到 PAN handler 的部分 (code 在 [arm v8 manual](https://static.docs.arm.com/ddi0487/ea/DDI0487E_a_armv8_arm.pdf?_ga=2.252048521.1816301954.1578468582-1379312784.1578468582) 7398 頁): ![](https://i.imgur.com/ZCyTQIX.png) 最後面檢查是否要觸發 PAN 的地方,可以看到 PAN 僅在 user 可以讀的時候觸發,換句話說只要 map 一個 user 沒有讀取權限的 page (--x),透過 kernel 讀取 --x 也不會觸發 PAN 防護 這些問題好像在 arm 工程師提出 execute-only page 的時候就有提到這種可能,在[這篇](https://lore.kernel.org/patchwork/patch/706340/)中有提到 execute-only page 可以被 kernel access ,若要啟用該功能請連同 seccomp 一起使用 ## 利用性 Arm v8.1 以上的晶片加上允許 map execute-only 的 os 都可以被利用 (linux 之前也可以,但現在已經將該功能拿掉), IOS/XNU 在該篇文章發表的時候還能利用 (這邊有些看不是很懂...,詳細完整請參考原文) 比較常見的方法包括偽造假的 vtable 或是直接在 map page 上放 rop chain ,但該 --x memory 必須被 faulted in (不是很懂...是 page fault 嗎?),而這個可以靠 mlock() ,但要 fault in 一個 executable page 必須要有合法的 code signature ,這點可以透過兩個常見的 attack vector 達成: Side-loaded app 和 WebContent ,其中一個可以 get-task-allow 允許一個 executable page ,另一個則是允許 dynamic-codesigning