Linux Kernel Pwn - Environment
Author: 堇姬Naup
前言
如果想把一個 kernel 跑起來,理論上是不能直接在你的 VM 跑起來啦,想想蠻合理的
我們必須要將整個環境都模擬起來,並指定我們想要的 kernel image 作為整個環境的 kernel
另外還需要 file system
本篇主要說明如何
- 編譯 kernel
- 打包一個 file system
- Qemu 模擬起來
- kernel driver
- gdb debug
我使用的環境是 VMware + Ubuntu 22.04
編譯 kernel
這步驟常常遇到超多問題 www
先安裝一些依賴
1 | sudo apt-get update |
這上面有 kernel source code,可以下載下來編譯
https://www.kernel.org/
1 | wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.11.tar.xz |
下載下來後,進到資料夾設定東西
1 | tar -xvf linux-5.11.tar.xz |
之後直接 make -j$(nproc) bzImage
接下來會遇到一些問題
make[1]: *** No rule to make target ‘debian/canonical-certs.pem’, needed by ‘certs/x509_certificate_list’. Stop. make: *** [Makefile:1809: certs] Error 2
sed -i 's|CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"|CONFIG_SYSTEM_TRUSTED_KEYS=""|' .config
BTFIDS vmlinux FAILED: load BTF from vmlinux: Invalid argument make: *** [Makefile:1165: vmlinux] Error 255
sed -i 's/CONFIG_DEBUG_INFO_BTF=y/CONFIG_DEBUG_INFO_BTF=n/' .config
我們就得到了 bzimage (在 /arch/x86/boot 底下)
當前目錄則有 vmlinux
- vmlinux: 原始 kernel
- bzimage: 壓縮 kernel
https://zh.wikipedia.org/zh-tw/Vmlinux
btw,若多次編譯導致你的空間被占滿可以用
1 | sudo rm -rf /tmp/* |
buzybox
接下來為我們的環境打包一個 file system,這邊選擇 buzybox,另外 buzybox 有提供常用的 Unix 指令
這邊將 busybox source code 載下來,之後 make menuconfig
配置 makefile 後一樣 make -j 8
編譯
配置時將 Build static binary (no shared libs) 打勾,因為 kernel 沒有 libc
PS: 這邊版本用 1.34.1,我試了其他版本用這方法會出問題
1 | wget https://busybox.net/downloads/busybox-1.34.1.tar.bz2 |
之後建立 _install 資料夾,進去裡面建立我們需要的根目錄
1 | make install |
之後編寫 init ,並給他執行權限 chmod +x init
1 |
|
現在已經建構好完整的 file system 了
通過這兩種方式打包和解包 roots file system
1 | # 打包命令 |
Qemu 模擬
最後就使用 kernel image、roots file system 來模擬整個環境
sudo apt install qemu-system-x86
編寫 start.sh
1 | qemu-system-x86_64 \ |
看到這樣就表示啟動成功了
這邊我們把 ASLR 關掉,方便 debug

kernel driver
建一個資料夾後先寫個測試的 kernel drivernaupdriver.c
1 |
|
以及 makefile
1 | obj-m += naupdriver.o |
執行完就出現 .ko 了

之後我們將我們 .ko 貼到 busybox 內,包進去 rootfs.img
另外需要調整 init ,讓我們在啟動時載入我們的 kernel module
1 | naup96321@naup96321-virtual-machine:~/Desktop/mykernel/linux-5.11/busybox-1.34.1/_install$ cat init |
如果看到 kernel driver start 代表你的 kernel driver 啟動成功
lsmod 可以看到載入了 kernel driver

debug
最後一步驟是 debug
首先是 attach 到 qemu
修改 start.sh ,加入 -gdb tcp::1234
在 1234 port 開啟一個 gdb,加入 -S
他啟動時就會卡住,等待 gdb 連上去
1 | qemu-system-x86_64 \ |
將 qemu 跑起來
之後開啟下 gdb -q -ex "target remote localhost:1234"
開 gdb 連上去
在 gdb 內先add-symbol-file vmlinux
載入 kernel 的 symbolb start_kernel
下斷點在啟動 kernelc
繼續執行就會卡在 qemu 啟動畫面
在按下一次 c 就會一直跑了
再來是 attach drivers
grep "0x" /sys/module/naupdriver/sections/.*
印出 kernel driver 每個區段的 address
1 | /sys/module/naupdriver/sections/.gnu.linkonce.this_module:0xffffffffc0004000 |
抓出來,進gdb 下
1 | add-symbol-file MyDriver/naupdriver.ko 0xffffffffc0002000 \ |
把 symbol load 進去
之後 b naup_init
下斷點在 naup_init 的地方b naup_exit
下斷點在結束的地方
c 之後就會看到卡住了

之後在 qemu 內下 rmmod naupdriver.ko 後
他會去卸下 kernel driver
此時 gdb 會卡在 naup_exit

總之通過此種方式就可以 debug kernel driver 了
after all
以上就是 kernel pwn 環境的部分,接下來就可以把上述概念用來打題目了