內核、虛擬化以及Intel CPU特性初涉
內核、虛擬化以及Intel CPU特性初涉
組會上超哥肯定了Digtool在內核漏洞挖掘上的工業價值,但是同時指出全虛擬化的策略降低了模糊測試的效能,而現在基於硬體加速的模糊測試或許是不錯的選擇。而什麼又是基於硬體的模糊測試呢,在 Usenix 26th 的論文列表中,Digtool的後一篇便是 kAFL: Hardware-Assisted Feedback Fuzzing for OS Kernels
。kAFL同時利用了Intel牙膏廠的兩個Feature: Intel VT-X 以及 Intel Process Trace ,通過改造以後的 Qemu 和 KVM 實現內核態的路徑反饋Fuzzing(AFL-American Fuzzing Lop)。
虛擬化的系統設計使kAFL有良好的跨平台特性,並且由於Intel PT的支持,可以將模糊測試的開銷降到最低,同時解決了由於內核崩潰帶來的效率和恢復的困難。
作者團隊在不同OS上進行了測試評估,發現了新的內核漏洞,並且編寫了測試用的驅動加入內核模塊,橫向比較了幾款內核模糊測試方法的效能,證明kAFL擁有廣闊的發展空間。
初涉計算機系統,對於一些內核、虛擬化等技術似懂非懂,為了更好地理解 the State Of Art, 需要基本的計算機素養。內核是什麼?內核中有什麼?如何添加內核模塊?什麼是內核漏洞?觸發內核漏洞有什麼條件?虛擬化技術的基本原理?KVM和Qemu的關係?CPU特性如何使用……後文是我的理解。
內核 Kernel
什麼是內核?
一言以蔽之,任何計算機系統都包含了一個名為操作系統的基本程序集合,而內核就是這個集合裡面最重要的一組程序。概括內核的任務:
- 與硬體交互,控制所有底層的可編程部件,這一部分稱作設備驅動
- 為運行在OS上的應用程序(用戶程序)提供執行環境 (Syscall)
而用現代OS為了限制程序濫用硬體資源,利用硬體特性(ring0~4)建立了一套嚴格的等級制度,從而將指令執行區分用戶態和內核態。這裡不再詳述。
內核中的組成部分
- 內存管理
- 進程管理
- 文件系統 (也可視作軟體驅動程序)
- 設備控制
- 網路功能
Linux的內核特性可以在運行時進行拓展(利用insmod程序連接,rmmod程序移除),在運行時被添加到內核的功能稱作模塊。
驅動程序和一般程序的區別是什麼?
驅動分為硬體驅動和廣義上的軟體驅動,硬體驅動程序包含我們所熟知的顯卡驅動、鍵盤滑鼠驅動等等,這一類驅動在Linux內核中被抽象為一類設備文件節點,通過open、write、ioctl等syscall,傳遞特定的參數信息進行讀寫控制,從而完成與硬體設備的交互。硬體驅動程序往往常駐內存,所以用戶可以正常操控計算機。
而軟體驅動則是為用戶態程序取得內核中的數據產生的介面。很多時候,用戶程序需要內核數據來實現相應的功能,而能獲得的ring0數據被嚴格限制。於是軟體驅動作為模塊加入內核,用戶態程序想要獲得內核數據只需要通過軟體驅動提供的api介面。而除了文件管理驅動,很多軟體驅動一類是殺毒、安全防護軟體,還有一類則是高性能的遊戲,或許是為了改善交互特性,需要獲取內核數據 ?
內核漏洞
進入內核的方法有4種:
- syscall 系統調用
- exception 錯誤
- 外部中斷
- 內核內部進程被執行
而漏洞挖掘的對象集中在 syscall 上。挖掘對象可以使進程、內存管理和文件系統的內核漏洞,也可以是第三方設備驅動上。硬體設備驅動往往會定製自己的數據結構和邏輯,但是它們總是通過內核提供的介面函數(open、write、ioctl)來實現調用。而它們的邏輯並不能被系統調用保證安全性。所以我理解的內核漏洞,並非對於特定的某個syscall函數,而是說通過註冊的內核模塊,給予特定的數據流,可能觸發模塊內部的BUG。
因此作者團隊可以在文中編寫json解析驅動,測試kAFL的Fuzzing效果。理解被測試的對象僅僅是駐留在內核的driver,而非syscall函數本身 , syscall僅僅提供可擴展內核的介面罷了。
虛擬化技術 Virtual Machine Tech
VM的發展
對於虛擬化技術,最直觀的認識在於虛擬機的使用。將硬體資源抽象,產生多個虛擬實體分享同一硬體資源。其最大的好處在於增大了硬體的使用域,復用計算能力。而虛擬機最顯著的一大特點便是跨平台、跨架構。
試想,在真實計算機中模擬另一個機器,我們可以劃分一片內存作為cpufile存儲guest機器cpu的各個寄存器以及運行狀態,我們解析目標程序的每一條指令,翻譯為host cpu的指令將執行的每一步結果保存到cpufile的數據結構中,這樣就為guest機器模擬了一個虛擬的運行環境,而在host上運行轉譯執行的程序稱作emulator。這個便是最早的虛擬機實現。
經過各種優化加速,qemu從眾多解決方案中脫穎而出。然而由於指令的解析依舊造成了性能上的overhead。於是有人取巧,通常我們只是在x86機器上虛擬x86機器,為什麼還要解釋指令呢,直接交給cpu執行就可以了。另外,為了維持虛擬機本省的特性,我們只需要篩選出guest的特權命令,交給host做特殊處理,就可以保證虛擬環境不影響host本身了。按照這個思路便誕生了KVM(kernel virtual machine)。
Intel VT-X
可以把KVM理解作VMM也就是通常所說的hypervisor,KVM作為Linux內核的模塊發布。在支持intel vt-x的機器上,cpu的等級ring0和ring3可以等同於vmm層和vm層,host機器作為dom0可以當做佔據I/O資源的特權vm,另外的guest機器和host機器同處於vm層,這裡可以把hypervisor當做一個特殊的kernel。
每當host或者guest產生一個系統調用,就會觸發hypercall事件,KVM根據設置可以忠實地執行正常kernel下的所有系統調用,也可以對機器做限制,比如說對於guest限制它調用usb介面等等。這時候的VMM可以當做一個cpu指令的調度中心,而不再有翻譯執行的職能。
另外,如果不與計算機交互就沒法設置KVM,所以位於Host的Qemu擔任了與KVM交互的工作,原本Qemu是一個獨立的集成內存管理、cpu模擬和I/O介面的獨立虛擬機程序,而KVM僅僅負責內存管理和cpu模擬,兩個項目merge以後形成Qemu-KVM,可以把KVM當做Qemu的硬體加速選項,KVM會將內核數據交給Qemu,通過Qemu就可以觀測Guest在內核層的行為了。
CPU 相關
對於macOS
sysctl -a | grep machdep.cpu
對於linux
cat /proc/cpuinfo
或者 ` lscpu ` 可以顯示詳細的cpu硬體配置
本機測試 ** Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz **
ubuntu 虛擬機,設置雙核cpu,然而 cat /proc/cpuinfo
processor
:
0
vendor_id
:
GenuineIntel
cpu
family
:
6
model
:
142
model
name
:
Intel(R)
Core(TM)
i5-7267U
CPU
@
3.10GHz
stepping
:
9
microcode
:
0x5e
cpu
MHz
:
3095.164
cache
size
:
4096
KB
physical
id
:
0
siblings
:
1
core
id
:
0
.......
cache_alignment
:
64
address
sizes
:
42
bits
physical,
48
bits
virtual
power
management:
processor
:
1
vendor_id
:
GenuineIntel
cpu
family
:
6
model
:
142
model
name
:
Intel(R)
Core(TM)
i5-7267U
CPU
@
3.10GHz
stepping
:
9
microcode
:
0x5e
cpu
MHz
:
3095.164
cache
size
:
4096
KB
physical
id
:
2
siblings
:
1
<======表明了每個core的線程數,如果大於1,說明開啟了超線程
core
id
:
0
cpu
cores
:
1
apicid
:
2
initial
apicid
:
2
........
power
management:
lscpu
? ~ lscpu
NUMA node(s): 1
Vendor ID: GenuineIntelCPU family: 6Model: 142Model name: Intel(R) Core(TM) i5-7267U CPU @ 3.10GHzStepping: 9CPU MHz: 3095.164BogoMIPS: 6190.32Virtualization: VT-x......以上顯示虛擬機有兩個插槽(socket)(一個插槽一塊cpu),每個插槽有一核心(core),每個核心支持一個線程(thread),這樣看來虛擬機並沒有開啟hyperthreading超線程技術。所以要注意虛擬機中的雙核其實並非物理機意義上的雙核心,而是增加了cpu而已。
而從macOS來看,對於單cpu
? _posts git:(master) ? sysctl -a | grep machdep.cpu
machdep.cpu.tlb.data.small_level1: 64
machdep.cpu.tlb.data.small: 64綜上所述,從硬體角度而言processor指的是cpu個數,也可以精確到core的數目,而從執行軟體的角度cpu就是指logical cpu(邏輯cpu),也就是利用超線程模擬出來的cpu數目,對於以上macOS的案例,logic cpu的個數 = 1 cpu x 2 core/pre cpu x 4 thread_count/per core = 8. 而vCPU(虛擬cpu)則是VM中的概念,我的理解是logical cpu分時分配任務,可以模擬出複數的vCPU,也就是說增大一定的overhead,lcpu最多可以模擬12-24個vcpu。
CPU 型號命名規則
參見筆記本cpu性能排名
第一位代表第幾代CPU,一般越大,架構更優。i7-4770K>i7-3 770K:第4代優於第3代
第二位代表處理器等級,數字越大,性能越好。i7-4810mq>i7-47 10mq
而i7/i5/i3是酷睿品牌下的三個子品牌,分別代表高中低端
另外:
QM代表四核移動版處理器
U代表雙核低電壓移動版處理器M的意思是Mobile,處理器是為筆記本設計的,功耗和發熱量較低,適合筆記本使用)X表示 Extreme,表示性能最高的L表示Low voltage,指的是低電壓版CPU,發熱量跟標準版的相比大約只有一半。U表示Ultra Low Voltage,超低電壓版CPU,發熱量和功耗比L系列的還要低。Q表示Quad,強調這顆CPU是四核心的,而且標明Q的處理器只有筆記本系列的CPU,因為筆記本的處理器一般是雙核的。貌似四核只有i7才有qm的型號。還有一款XM系列,主要針對高端市場ps:台式機的CPU即使是四核,也不標明。Intel Process Trace
簡介
第五代以後的cpu都具有Intel PT擴展,然而在Intel的cpu官方手冊中卻並沒表明Intel PT的特性,Intel在這一方面含糊其辭,也許是因為這一技術並沒有非常成熟吧。
就如Intel PT的名字,這一Feature可以Trace邏輯CPU的每一步執行。指令跳轉、寄存器狀態等不同類型信息以packet為單位存放在cpu subsystem的緩衝區中,通過一配置可以打開關閉Intel pt,可以配置Intel pt的過濾選項,僅僅trace感興趣的packet。
因為是由硬體支持的trace,並不需要下跟蹤斷點(trace breakpoint),通過Intel pt可以記錄完整的控制流信息,甚至是每個狀態下的棧信息。所以Intel pt可以很方便地還原crash前的進程現場,還可以觀測程序執行的時間,記錄循環次數、路勁,探索邊界,倒退狀態,恢復調用棧等等。
詳細的Intel PT使用手冊可以搜索谷歌,關鍵詞:Intel? 64 and IA-32 Architectures Software Developer』s Manual,Volume 3C 近1400page。
Recap
雖然沒有提及論文的核心,但這些知識作為理解論文每個問題解決思路的基礎有理解透徹的必要。
如果時間允許,後續會整理一下kAFL研究的相關內容。
推薦閱讀:
※廣東觀音山:竭力守護綠水青山 勵志打造生態文明
※CSP 課堂筆記之 Hypervisor
※乾貨,幾維安全代碼虛擬化技術原理與實現
※會飛的貓咪很危險,區塊鏈虛擬寵物是場騙局嗎?