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

Linux下的Rootkit駐留技術(shù)分析

系統(tǒng) Linux 服務(wù)器
針對Linux設(shè)備的惡意軟件(以下稱為rootkit)通常需要長期駐留于目標操作系統(tǒng)以達到獲利目的,所以如何實現(xiàn)駐留也是Linux rootkit作者的重點考慮內(nèi)容之一,對此,實驗室進行了可能的思路探索和分析。

 前言

Linux作為服務(wù)器和IoT設(shè)備使用的主要操作系統(tǒng),針對它的惡意軟件也層出不窮。針對Linux設(shè)備的惡意軟件(以下稱為rootkit)通常需要長期駐留于目標操作系統(tǒng)以達到獲利目的,所以如何實現(xiàn)駐留也是Linux rootkit作者的重點考慮內(nèi)容之一,對此,實驗室進行了可能的思路探索和分析。

在接下來的說明中,我們統(tǒng)一使用一個名為evil的靜態(tài)鏈接ELF文件作為我們要實現(xiàn)駐留的rootkit,所有的駐留嘗試均圍繞這個程序展開。

技術(shù)匯總

1. 用戶態(tài)下的可利用點

1.1 各種init的利用

Linux init

在systemd成為主流之前,sysvinit是大多數(shù)發(fā)行版的選擇,即使是Ubuntu之前使用的upstart,和sysvinit也是完全兼容的,直到今天,Debian系發(fā)行版仍保留sysvinit的兼容性。作為Linux的init程序,也就是PID 1,負責(zé)啟動之后的所有進程,所有的服務(wù)都是由它管理,因此它是實現(xiàn)rootkit駐留的最常見手段。

對于傳統(tǒng)的sysvinit,常見的駐留點都需要以root身份寫入:

  1. /etc/init.d/etc/rc[runlevel].d/etc/rc.local 

其實sysv的服務(wù)文件就是遵循sysv規(guī)范的shell腳本,它在嵌入式設(shè)備中也很常見。給出一個sysv風(fēng)格的服務(wù)文件如下:

  1. #!/bin/shPATH=/bin:/usr/bin:/sbin:/usr/sbin 
  2. DESC="cron daemon"NAME=cron 
  3. DAEMON=/usr/sbin/cron 
  4. PIDFILE=/var/run/crond.pid 
  5. SCRIPTNAME=/etc/init.d/"$NAME"test -f $DAEMON || exit 0 
  6.  
  7. . /lib/lsb/init-functions 
  8.  
  9. [ -r /etc/default/cron ] && . /etc/default/cronparse_environment() {    for ENV_FILE in /etc/environment /etc/default/locale; do 
  10.         [ -r "$ENV_FILE" ] || continue 
  11.         [ -s "$ENV_FILE" ] || continue 
  12.  
  13.         for var in LANG LANGUAGE LC_ALL LC_CTYPE; do 
  14.             value=$(egrep "^${var}=" "$ENV_FILE" | tail -n1 | cut -d= -f2) 
  15.             [ -n "$value" ] && eval export $var=$value 
  16.  
  17.             if [ -n "$value" ] && [ "$ENV_FILE" = /etc/environment ]; then 
  18.                 log_warning_msg "/etc/environment has been deprecated for locale information; use /etc/default/locale for $var=$value instead" 
  19.             fi 
  20.         done 
  21.     done 
  22.  
  23.     # Get the timezone set
  24.     if [ -z "$TZ" -a -e /etc/timezone ]; then 
  25.         TZ=$(cat /etc/timezone)    fi}# Parse the system's environmentif [ "$READ_ENV" = "yes" ]; then 
  26.     parse_environmentficase "$1" instart)    log_daemon_msg "Starting periodic command scheduler" "cron" # 這一行是我們修改的目標 
  27.     start_daemon -p $PIDFILE $DAEMON $EXTRA_OPTS 
  28.     log_end_msg $? 
  29.     ;; 
  30. stop)    log_daemon_msg "Stopping periodic command scheduler" "cron" 
  31.     killproc -p $PIDFILE $DAEMON 
  32.     RETVAL=$? 
  33.     [ $RETVAL -eq 0 ] && [ -e "$PIDFILE" ] && rm -f $PIDFILE 
  34.     log_end_msg $RETVAL 
  35.     ;; 
  36. restart)    log_daemon_msg "Restarting periodic command scheduler" "cron" 
  37.     $0 stop    $0 start 
  38.     ;; 
  39. reload | force-reload)    log_daemon_msg "Reloading configuration files for periodic command scheduler" "cron" 
  40.     # cron reloads automatically 
  41.     log_end_msg 0 
  42.     ;; 
  43. status) 
  44.     status_of_proc -p $PIDFILE $DAEMON $NAME && exit 0 || exit $? 
  45.     ;; 
  46. *)    log_action_msg "Usage: /etc/init.d/cron {start|stop|status|restart|reload|force-reload}" 
  47.     exit 2 
  48.     ;;esacexit 0 

我們在start case中做些修改,使之在啟動時執(zhí)行我們的evil程序:

 

對于systemd,我們可以用更多手段實現(xiàn)駐留,甚至不需要root權(quán)限也可以:

  1. /etc/systemd/system/etc/systemd/user/lib/systemd/system/lib/systemd/user 
  2. ~/.local/share/systemd/user 
  3. ~/.config/systemd/user 

以下是一個利用systemd服務(wù)文件的示例:

 

systemctl --user enable service可以使服務(wù)隨用戶登錄啟動,systemctl enable service可以讓服務(wù)隨系統(tǒng)啟動。

  1. bashrc 

bashrc或者zshrc等文件會隨著shell的運行而被執(zhí)行,利用時只需在里面加入惡意的shell script即可。

常見位置:

  1. /etc/profile 
  2. ~/.bashrc 
  3. ~/.bash_profile 
  4. ~/.bash_logout 

示例如下:

  1. xinitrc 

如果目標主機有安裝Xorg,我們也可以以下位置寫入shell script實現(xiàn)rootkit駐留,不需要root權(quán)限。

  1. ~/.xinitrc 
  2. ~/.xserverrc/etc/X11/xinit/xinitrc/etc/X11/xinit/xserverrc 
  3. 其它initrc 

任何應(yīng)用程序都可能在啟動時執(zhí)行代碼,而且它們很可能會執(zhí)行用戶home目錄的rc文件。例如,我們甚至可以在vimrc里 寫入vimscript來執(zhí)行代碼實現(xiàn)rookit的駐留,這同樣不需要root權(quán)限。

一個可能的示例如下:

 

1.2 圖形化環(huán)境的利用

雖然標準的服務(wù)器版Linux發(fā)行版是不會預(yù)裝Xorg的,但還是存在相當(dāng)一部分用戶使用CentOS預(yù)裝gnome2的版本作為服務(wù)器操 作系統(tǒng)。因此,基于gnome等桌面環(huán)境和Xorg的駐留有時候也是重要的而且會容易被忽略的手段。

  1. XDG autostart for system 

/etc/xdg/autostart下的desktop文件會被主流桌面環(huán)境在啟動時執(zhí)行。一個可能的示例如下:

  1. XDG autostart for user 

類似的,用戶可以在自己的~/.config/autostart目錄下加入需要自啟動的desktop文件。

1.3 crond的利用

這是一個很常見的駐留點,但需要注意的是,很多惡意軟件并不僅僅會把自己寫入用戶的crontab(如/var/spool/cron/root),它們會把自己寫入軟件包使用的crontab里面,如/etc/cron.d,這樣更不容易引起用戶注意。

 

1.4 替換文件

替換或者patch一些會被服務(wù)或用戶本身執(zhí)行的程序文件,以同時執(zhí)行惡意代碼,也是很常見的駐留方式。

我們可以方便的獲取到開源項目的源碼,進行修改,加上我們的惡意代碼并重新編譯,替換目標系統(tǒng)的相應(yīng)文件。這樣我們的代碼就會隨之執(zhí)行。

下面我們修改openssh portable 7.9的源碼,使之在特定條件下執(zhí)行我們的代碼:

 

這里修改的函數(shù)是uncompress_buffer,用于處理壓縮傳輸?shù)膕sh連接。我們需要觸發(fā)它的時候,只需發(fā)起一個ssh -C即可。

 

如果沒有源碼,我們同樣可以給現(xiàn)有的binary注入shellcode,不過這種實現(xiàn)達到的功能相對有限,且可能會導(dǎo)致原文件損壞 。下面使用backdoor-factory進行shellcode注入,這個工具支持自定義shellcode:

 

如果我們的目標主機是git或svn服務(wù)器,有機會接觸到項目源碼的話,也可以通過修改目標的源碼植入惡意代碼,或者把編譯環(huán)境動手腳,在項目構(gòu)建時插入惡意代碼,比如在configure腳本里或者Makefile里插入代碼,既可以在本機運行,又有可能在編譯之后在更多主機(取決于項目用途)上運行,進一步擴大感染范圍。這個思路也是當(dāng)年中國xcode事件黑客的思路。

1.5 動態(tài)鏈接庫劫持

替換動態(tài)鏈接庫

libc會被幾乎所有的ELF調(diào)用,而特定的lib則會被特定的ELF調(diào)用,只要某個ELF的執(zhí)行概率夠高,我們同樣可以用我們重新編譯的惡意so替換掉它所鏈接的某個so文件,達到執(zhí)行惡意代碼的效果。

當(dāng)然,以這種思路來看,替換掉整個libc也是未嘗不可的。

下面以sshd的動態(tài)鏈接庫為例,sshd使用的so文件如下:

 

libz.so.1看上去像是zlib的文件,可以驗證一下:

 

那么我們可以去下載zlib源碼,在可能會被調(diào)用的函數(shù)里加上我們的私貨。

經(jīng)過grep搜索openssh portable 7.9的源碼,可以看到packet.c使用了zlib的函數(shù):

 

確定了我們需要注入代碼的函數(shù),就可以去修改zlib源碼了,在inflate.c的inflate函數(shù)里加入簡單的system調(diào)用,來執(zhí)行我們的evil程序:

 

完成修改之后我們make構(gòu)建項目,然后用我們的惡意libz.so替換原本的文件。

此處修改的zlib,通常只會在ssh客戶端指定了使用壓縮時,才會被使用。所以我們需要使用ssh -C命令去測試。

 

提醒一點,作為動態(tài)鏈接庫,它們的函數(shù)可能被頻繁調(diào)用,我們在利用的時候要避免造成不必要的負載。另外,由于大部分程序都是動態(tài)鏈接庫文件,我們也需要格外小心,避免加入的代碼調(diào)用的程序最終往回調(diào)用我們修改的庫文件本身(尤其是在修改libc的時候),造成死循環(huán),導(dǎo)致系統(tǒng)停止響應(yīng)。

  1. ld.so.preload 

最常見的實現(xiàn)是在/etc/ld.so.preload中寫入我們需要讓libc執(zhí)行的so文件,或者設(shè)置LD_PRELOAD環(huán)境變量,這樣,任何依賴系統(tǒng)libc的user space程序,都會在運行之前執(zhí)行我們的so文件,從而實現(xiàn)了有效的rootkit駐留(鑒于幾乎所有目標主 機都是動態(tài)編譯的,幾乎所有程序都要使用系統(tǒng)libc)。

下面我們編寫一個簡單的惡意so(shared object)作為說明:

這里的惡意so將編譯為libevil.so。通常的lib都是為主程序提供庫函數(shù)的,只有被調(diào)用的代碼才會被執(zhí)行,于是我們需要 解決的第一個問題是讓我們的代碼在lib被加載時直接自動運行。類似于Windows下的DllMain,gcc提供了function attributes,我們可以用形如__attribute__((constructor))的attribute來達到目的。對應(yīng)的,__attribute__((destructor)) 則會在lib被unload的時候執(zhí)行。

具體解釋見官方文檔:

 

我們使用如下代碼構(gòu)建libevil,這里有一個坑,execl函數(shù)只有出錯時才返回,如果使用它執(zhí)行了外部程序,那么在外部程 序執(zhí)行完之后,libevil將會退出當(dāng)前進程(也就是我們本來要執(zhí)行的進程),使任何ELF都無法正常執(zhí)行。解決方法是使用 fork 函數(shù)創(chuàng)建子進程,在子進程里執(zhí)行execl啟動外部程序。

 

 

使用如下命令構(gòu)建我們的 libevil.so:

 

設(shè)置LD_PRELOAD環(huán)境變量,使我們的libevil在ld執(zhí)行任何ELF之前被執(zhí)行。

 

需要注意的是,我們的libevil會在每個動態(tài)ELF執(zhí)行之前被執(zhí)行,如果在其中調(diào)用了外部的動態(tài)ELF,那個ELF執(zhí)行時會再次調(diào)用libevil,就會造成死循環(huán),使系統(tǒng)處于不可用狀態(tài)。

我們也可以在libevil里實現(xiàn)rootkit的所有功能。

2. 內(nèi)核態(tài)的駐留

傳統(tǒng)的rootkit就是指這類惡意軟件,對于Linux rootkit來說,最有效的方法就是把自己作為kernel module加載,因為大多數(shù)Linux目標都是允許動態(tài)加載kernel module的。

在kernel space里運行惡意代碼的好處顯而易見,由于大部分審計工具都在user space運行,管理員通常很難發(fā)現(xiàn)惡意軟件的存在,這就帶來了上面的方法所不能達到的隱蔽性。

2.1 LKM – 可加載內(nèi)核模塊

目前有一些開源的LKM (Loadable Kernel Modules) 木馬demo,比較有代表性的是Reptile,它使用自己的kernel module實現(xiàn)了隱藏和駐留。

下面我們使用這個思路來實現(xiàn)一個簡單的內(nèi)核惡意代碼執(zhí)行:

這里的LKM實現(xiàn)比較簡單,只是在加載和退出的時候執(zhí)行了兩個shell腳本,并使用printk輸出了內(nèi)核調(diào)試信息。我們只需定義兩個函數(shù)分別用于initialize和exit即可完成LKM的主體框架了,module.h會有相應(yīng)函數(shù)module_init和module_exit用來實現(xiàn)。

MODULE_LICENSE也需要設(shè)置,因為Linux是GPL授權(quán),我們需要聲明兼容的授權(quán)協(xié)議,否則Linux會提示tainted kernel(雖然不影響正常使用,但會比較容易引起注意)。編譯LKM的方法可以參考Linux內(nèi)核文檔,或者直接參考現(xiàn)有的LKM項目的Makefile,這里的Makefile內(nèi)容如下:

 

 

 

 

LKM代碼如下,使用user space helper達到了執(zhí)行外部程序的目的:

 

 

 

 

使用insmod命令動態(tài)加載LKM到內(nèi)核,立即生效:

 

下面是dmesg的相關(guān)輸出:

 

LKM執(zhí)行惡意代碼有比較大的局限性,因為必須針對相同內(nèi)核版本編譯才能正常使用,從而引入了Linux headers的依賴,實現(xiàn)大范圍傳播的難度較大。防范此類攻擊(也是最危險和隱蔽的一種)的最有效方法就是關(guān)閉Linux的動態(tài)模塊加載功能,對于大多數(shù)Linux服務(wù)器,關(guān)掉這個功能通常不會造成額外影響。

2.2 initrd的利用

Reptile會把自己寫入/etc/rc.modules以便在系統(tǒng)啟動時插入自己的module。但通過initrd實現(xiàn)更加隱蔽可靠。initrd即init ram disk,用于提供一個基本的環(huán)境以便啟動完整的Linux。

鑒于initrd很少受到關(guān)注和保護,它又一定會在啟動時被加載入內(nèi)存,我們可以在這個內(nèi)存文件系統(tǒng)中插入自己的LKM并修改init腳本使我們的LKM在啟動時被加載,從而實現(xiàn)惡意代碼執(zhí)行。

這里以Kali(Linux 4.18,基于Debian Sid)為例,分析可能的利用點:

下圖是init腳本functions定義中,加載自定義kernel module的函數(shù),我們可以把自己的LKM放到modules目錄下(例如 ./usr/lib/modules/4.17.0-kali3-amd64/kernel),然后在 ./conf/modules里寫上自己的LKM,我們的LKM就會隨著initrd加載到內(nèi)核。

或者我們也可以直接在load_modules函數(shù)內(nèi)增加modprobe操作來加載惡意LKM。

 

總結(jié)

Linux下的惡意軟件雖然種類不多,但就其駐留技術(shù)實現(xiàn)而言,還是有不少的方法。本文除了主流的實現(xiàn)之外,也提出了一些通常很少有人注意的實現(xiàn)方法,希望對Linux攻防對抗的朋友有所幫助。

責(zé)任編輯:武曉燕 來源: 瘋貓網(wǎng)絡(luò)
相關(guān)推薦

2015-10-22 15:38:22

2010-01-14 20:57:59

2010-01-15 10:32:40

2009-07-27 08:50:29

2017-01-03 16:57:58

2010-09-07 21:25:22

2010-01-11 10:17:12

2020-05-21 14:28:00

Linux故障分析工具

2017-02-23 10:30:49

2021-10-11 09:21:14

惡意軟件黑客網(wǎng)絡(luò)攻擊

2017-01-12 16:02:18

2011-04-02 10:29:20

Linux工具

2023-12-11 07:21:36

2016-09-20 22:04:55

Docker Linux Names

2009-04-01 14:33:33

2010-09-09 23:14:45

2020-05-15 08:28:18

二進制文件binLinux

2009-07-04 20:16:50

2011-04-07 15:02:02

LinuxMySQL數(shù)據(jù)庫

2022-02-12 10:47:58

Rootkit僵尸網(wǎng)絡(luò)攻擊
點贊
收藏

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