ubuntu內核編譯與Kasan初探

最近在復現一篇論文的時候發現linux內核的強大之處了,就簡單的學習了下關於內核的一些知識,其中主要用到了Kasan這個檢測UAF漏洞的工具(嚴格來說只能是內核編譯插樁),本以爲很簡單,結果搞了好長時間,鑑於目前這方面資料很少,設置過程也缺乏,故將這個設置過程記錄下來,以便交流(本文僅限學術交流,嚴謹轉載)

一 內核編譯

內核編譯過程主要參考了《鳥哥的Linux私房菜》,以及https://www.jianshu.com/p/e1f550ba164d

1  查看自己ubuntu的內核版本 uname -a(-r)

2 查看可用的內核版本:

3 安裝與自己內核頭文件相應的的內核源碼 sudo apt-get install linux-source-4.10.0(內核文件並不大,一般的也就在100M左右),下載完後會直接在/usr/src中看到相應的內核源碼,運行 cd /usr/src 轉到目錄後解壓源碼:sudo tar -axvf linux-source-4.10.0.tar.bz2,轉到相應的源碼目錄:cd /usr/src/linux-source-4.10.0

源碼中一些基本的信息:

arch:與硬件平臺有關的選項,大部分指的是CPU的類別,例如 x86,x86_64,Xen虛擬支持等;
block:與區塊設備較相關的設置數據,區塊數據通常指的是大量存儲媒體,還包括ext3等文件系統的支持是否允許等;
crypto:內核所支持的加密技術,如 md5或des等;
Documention:與內核有關的幫助文檔;
drivers:一些硬件的驅動程序,如顯卡、網卡、PCI相關硬件;
firmware:一些舊式硬件的微指令(固件)數據;
fs:內核所支持的filesystems,如vfat、nfs等;
include:一些可讓其他程序調用的頭(header)定義數據;
init:一些內核初始化的定義功能,包括掛載與init程序的調用等;
ipc:定義Linux操作系統內各程序的通信;
kernel:定義內核的程序、內核狀態、線程、程序的調度(schedule)、程序的信號(signal)等;
lib:一些函數庫;
mm:與內存單元有關的各種信息,包括swap與虛擬內存等;
net:與網絡有關的各項協議信息,還有防火牆(net/ipv4/netfilter/*)等;
security:包括SELinux等安全性設置;
sound:與音效有關的各項模塊;
virt:與虛擬化及其有關的信息,目前內核支持的是KVM(Kernel base Virtual Machine)

4 修改設置:sudo make menuconfig(==make oldconfig ==make xconfig == make gconfig == make config ==sudo vim .config)

報錯,其原因是缺少庫,解決方法:

   sudo apt-get install libncurses5-dev

之後再次運行 sudo make menuconfig,得到圖形化界面,在kernel hacking/memory debugging中,可以使用空格進行選擇,前面有M的表示模塊

找到kasan,首先查看Help,查看相關的依賴選項:

注意,KASAN[=n]表示的是目前的狀態時未打開,selects 則和symbol保持着一致性(symbol是啥,selects就是啥),而相關的依賴需要打開。要是找不到,可以在選好後保存,然後 sudo gedit .config進行修改,不過相關的依賴前面會加上CONFIG_的前綴。同時還要注意:enable,don‘t work with後面的選項。當然你也可以使用別人已經設置好的.config文件。

在Kasan的子目錄裏,進行模式選擇,inline比outline要快一些,所以設置

另外還有SLUB,設置後,保存,退出,在源碼的目錄下,Ctrl+H,會發現多出了.config文件,這個就是配置文件了。

5 編譯內核、模塊

make -j 2 clean    #先清除臨時文件

make -j 2 bzImage    #先編譯內核,生成bzImage文件(中量時間)

sudo make -j 2 modules    #再編譯模塊,要權限(大量時間)

製作出來的資料是被放置在/usr/src/linux-source-4.10.0/kernel 目錄下,還沒有被放到系統的相關路徑中

##-j [N], --jobs[=N]       同時允許 N 個任務;無參數表明允許無限個任務

6 安裝模塊

上步編譯內核、模塊後,還沒有將其放入相關的系統路徑中,模塊需要安裝,內核也需要移動位置。模塊會被安裝在/lib/modules的目錄下,這兒一定要注意,當兩個版本一模一樣時,模塊放置的目錄也一樣,此時就會產生衝突,解決方法:

方法1:先將舊的模塊目錄更名,然後才安裝內核模塊到目標目錄中去;
方法2:在 make menuconfig 時,將General setup內的Local version修改成新的名稱;

我在我的機子上實驗並沒有遇到這個問題,所以直接運行:sudo make modules_install,安裝之後,會在/lib/modules下生成一個新目錄

7 移動內核

內核文件通常以 vmlinuz 爲開頭,後面跟上內核版本的文件格式。複製新內核文件到 /boot/ 下並改名 vmlinuz-3.10.107,保留舊內核文件。(命名時,我參考了我的模塊生成的目錄)

sudo cp  /usr/src/linux-source-4.10.0/arch/x86/boot/bzImage  /boot/vmlinuz-4.10.17
sudo cp  /usr/src/linux-source-4.10.0/.config  /boot/config-4.10.17
#給新內核文件添加 X 權限
sudo chmod  a+x  /boot/vmlinuz-4.10.17
sudo cp  /usr/src/linux-source-4.10.0/System.map  /boot/System.map-4.10.17
sudo gzip -c  /usr/src/linux-source-4.10.0/Module.symvers  > /boot/symvers-4.10.17(這個要最高權限)
##sudo passwd設置密碼(第一次時)
##su
##獲取最高權限

8 建立相對應的 Initial Ram Disk(initrd)

首先安裝dracut:sudo apt install dracut

其次:sudo dracut  -v  /boot/initramfs-4.10.17.img  4.10.17

9 編輯開機選項(grub)

在/boot/grub下沒有發現grub2,只能用grub

grub-mkconfig  -o  /boot/grub/grub.cfg

由此,就可以重新開機並選擇新內核來啓動系統啦!(啓動時進入ubuntu界面按住shift,進入ubuntu高級選項,可以自由選擇內核啓動)

注意:在虛擬機上編譯內核後重啓會出現一個錯誤:

VBoxClient (seamless): failed to start. Stage: Setting guest IRQ filter mas Error: VERR_INTERNAL_ERROR

這個錯誤是關於VBOX的增強功能的,通過以下命令來解決:

參考:https://askubuntu.com/questions/985815/vboxclient-seamless-failed-to-start-stage-setting-guest-irq-filter-mask-err

sudo apt-get install gcc make perl
cd /media/$USER/VBox_GAs_5.2.22
sudo ./VBoxLinuxAdditions.run
sudo reboot

至此,我們完成了內核編譯的整個過程。

二 內核模塊的操作

上節內容講解了內核、模塊的編譯,安裝過程。事實上,有時候我們僅僅只是想安裝一個模塊,而不想重新編譯內核,那麼在內核需要的功能開啓的情況下,單獨編譯模塊是否可行呢?,回答是正確的,可以實現內核模塊的編譯過程。本節內容主要參考:https://blog.csdn.net/yeshennet/article/details/82315604

簡單的hello world模塊

1 hello.c文件

/*  
 *  hello.c - The simplest kernel module.
 */
#include <linux/module.h>   /* Needed by all modules */
#include <linux/kernel.h>   /* Needed for KERN_INFO */
int init_module(void)
{
    printk(KERN_INFO "Hello world 1.\n");
    /* 
     * A non 0 return means init_module failed; module can't be loaded. 
     */
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world 1.\n");
}

2 Makefile文件

obj-m += hello.o

all:
    make -C /lib/modules/4.10.17/build M=$(PWD) modules

clean:
    make -C /lib/modules/4.10.17/build M=$(PWD) clean

注意三點:1 hello.o要和hello.c對應,2 Makefile中的目錄是你安裝模塊時的模塊安裝目錄,3 Makefile中make前面是一個TAB符。運行:make,結果如下

同時在目錄裏生成一些文件

其中hello.ko文件就是我們說的模塊

我們對這個hello模塊文件進行操作

1插入一個模塊:

sudo insmod hello.ko

要是報錯:
insmod: ERROR: could not insert module hello.ko: Invalid module format
可能原因:make時使用的內核版本和本系統的內核版本不一致

需要重新啓動,選擇內核來實現模塊插入等操作

uname -r

運行插入模塊的命令

2 查看模塊的相關信息

sudo modinfo hello.ko

3 卸載模塊

sudo rmmod hello.ko

4 lsmod 命令是查看當前已載入的模塊

模塊的基本介紹就到此結束,下節介紹對kasan功能的實現

三 對KASAN功能的實現

實際上,linux內核源碼提供了關於測試kasan的模塊,在內核編譯中可以直接選擇,但是作者本人太笨,一直不知道怎麼搞,另外也想簡單的學習下內核模塊是怎麼搞出來的,就沒打開test_kasan模塊,而是採用上一小節的方法嘗試着將test_kasan.ko做出來。

在內核源碼usr/src/linux-source-4.10.0/lib中可以找到test_kasan.c文件,之後,我們選擇其中的一個函數進行測試就行,不過依然需要我們編寫一個Makefile文件。

首先從test_kasan.c中抽出一個函數作爲test.c文件

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/module.h>
int init_module(void)
{
	char *ptr;
	size_t size = 123;

	pr_info("out-of-bounds to right\n");
	ptr = kmalloc(size, GFP_KERNEL);
	if (!ptr) {
		pr_err("Allocation failed\n");
		return 0;
	}
	ptr[size] = 'x';
	kfree(ptr);
}
void cleanup_module(void)
{
    printk(KERN_INFO "GOODBYE\n");
}

其次,製作Makefile文件

obj-m += test.o
all:
	make -C /lib/modules/4.10.17/build M=$(PWD) modules
clean:
	make -C /lib/modules/4.10.17/build M=$(PWD) clean

之後,sudo make和 make 產生了不同的結果(先sudo make,後make)

最終還是生成了相關的文件

運行sudo insmod test.ko後,在運行 dmesg 查看相關信息

會在打印的內容中找到以下的字樣:

或者,也可以在/usr/log/kern.log中找到相關的記錄

由此來看,kasan是一個自動化的內核插樁工具,他不會給你任何的提示來說明是否打開了kasan,需要在對內核的相關過程中實現自動化的檢測,要是不懂dmesg命令,還真不知道這個kasan怎麼搞。KASAN藏的真夠深的!!

想了解kasan原理的可以參考:https://www.cnblogs.com/alantu2018/p/8457420.html

四 總結

到此,我們實現了整個過程,從中學習到了內核的編譯,模塊的編譯,kasan的相關操作。內核的編譯很容易出錯,要是在虛擬機中做,最好要學會時刻保存備份。模塊的編譯,我只看了最基礎的那部分內容,其他的並沒有深入,有興趣的可以參考文中的網址。Kasan的操作是一個很有用的工具,能夠自動化檢測UAF漏洞。總之,經過這次學習,總算理解了爲啥搞安全的都喜歡Linux,這個功能真的強大。

再次感謝文中的博客提供的寶貴資料!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章