---
# System prepended metadata

title: ARM hardware bug to bypass PAN
tags: [exploitation]

---

# 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

