歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 用戶行為監控:bash history logging攻防

用戶行為監控:bash history logging攻防

日期:2017/2/27 15:48:03   编辑:Linux教程

Bash堪稱*nix世界使用最廣泛的shell,其特性之一是歷史命令(history)機制。此機制主要用於為用戶提供方便--少敲幾下鍵盤, 提高工作效率。然而,被廣泛討論的是bash_history可以用作logging機制以此來監控用戶的活動。此文將對上述問題進行討論並解釋為啥 logging機制在少數人面前會失效。我們將見到各種用於保護history文件的防御措施是如何不費吹灰之力或稍微費點力就被突破的。隨著討論的跟 進,突破的限制也將變得更嚴,但這並不代表突破起來就更困難,與之相反大部分方法都是可以不費腦子的。最後,我們將修改bash的源碼來實現”無 敵”logging機制,也將看到”無敵”並不是真正的無敵。

加固bash_history

假設你所管理的系統提供shell登錄功能,你的用戶當中有個別及其討人厭的家伙,於是你想監控他的活動,因為你非常懷疑他半夜三更使用你所負責保 護的CPU和系統資源作惡意行為(或是其他的,例如下毛片等)。我們暫且叫他二哥(此處原文為Bob,Bob一名在國外經常用來指代壞蛋)。

因為所有用戶都是使用bash作為默認shell,你開始著手修改bash的配置文件:

第1步:使bash歷史記錄文件和相關文件無法被刪除或修改。

二哥所做的第一件事應該是建立history到/dev/null的鏈接。

bob$ rm ~/.bash_history
bob$ ln -s /dev/null  ~/.bash_history

這可以通過修改歷史記錄文件為只能被追加來進行阻止,執行以下命令來改變其屬性:

# chattr +a /home/bob/.bash_history

這是使用文件系統附加屬性來指定文件只能被追加,大多數文件系統支持此功能(例如ext2/3,XFS,JFS)。在FreeBSD上可以執行:

# sappnd /home/bob/.bash_history

你還應修改shell啟動相關的其他文件的這個屬性:

# chattr +a /home/bob/.bash_profile
# chattr +a /home/bob/.bash_login
# chattr +a /home/bob/.profile
# chattr +a /home/bob/.bash_logout
# chattr +a /home/bob/.bashrc

前三個文件在交互式bash shell(或非交互式sehll使用–login選項)調用時被讀取(在讀完全局配置文件/etc/profile後)。.bashrc文件只在當 non-login交互式shell調用時被讀取。這意味著當二哥已登進系統後,用以下方法自己調用一個新shell時:

bob$ bash

此時只有.bashrc文件被讀取,而上面所列的前三個配置文件不會再次被讀取了。

做了以上屬性的修改後再來做更進一步的”加固”,一個所謂的保護措施。

第2步:配置 .bash*配置文件

所有的配置將針對.bashrc文件,因為其他三個配置文件本身會調用.bashrc,也就是說.bashrc無論如何都會被讀取 (不管用戶是否剛登錄或是登錄後手工調用bash shell)。

所以,所有修改都針對.bashrc的好處是可以防止二哥登錄後手工調用新的bash shell來跳過僅在.bash_profile,.bash_login,.profile三個配置文件中生效的配置選項,另一好處是這三個文件本身都 會調用.bashrc,所以在首次登錄系統時.bashrc當中的配置也會生效。

# cat >> /home/bob/.bashrc << EOF
> shopt -s histappend
> readonly PROMPT_COMMAND=”history -a”
> EOF

此處histappend選項的作用是讓bash附加上最後一行$HISTSIZE給$HISTFILE文件(一般 是~/.bash_history文件),不管交互式shell何時退出。默認的,bash每次均會覆蓋$HISTFILE以保證只有一個session 被保存以此來節約空間。

環境變量PROMPT_COMMAND會保存一條將被優先執行的命令,意思是說”history -a”命令將在用戶執行命令前被優先執行,這將保證不管當前命令前一條是執行的什麼,它將立即被追加進$HISTFILE,而不用等待整個會話結束再將歷 史命令從內存記錄至硬盤。

此處的readonly作用是使變量不可修改以防止被二哥覆蓋掉或是直接屏蔽掉。

最後要完成的步驟是使所有與bash_history相關的環境變量都變為readonly:

readonly HISTFILE
readonly HISTFILESIZE
readonly HISTSIZE
readonly HISTCMD
readonly HISTCONTROL
readonly HISTIGNORE

第3步:禁掉系統中所有其他shell,一般包括csh,tcsh,ksh。

# chmod 750 csh
# chmod 750 tcsh
# chmod 750 ksh

這將阻止二哥把bash shell切換成其他shell。

現在,機敏點的管理員會抱怨上面的都是shit!

還有一個shell逃出了我們的掌控!在你看完以上敘述跳入浮想聯翩之前,讓我們來搞清一些事情。

很久很久以前… (你懂的),原本只有一個Bourne shell 或者叫sh,現如今,/bin/sh實際上是/bin/bash的一個鏈接。Bash在被調用時檢查它是以哪個名字被調用的並以此來判斷是不是調用sh, 它試圖模仿歷史版本的sh的行為並和POSIX標准保持一致。

如果以交互式login shell或非交互式shell帶上–login選項啟動,它才讀取/etc/profile和~/.profile來初始化配置。如果以交互式 shell被調用,則試圖解釋$ENV變量,當$ENV非空則使用它的值當作默認配置並執行。我們將在本文的下一節討論如何利用這點來秒殺bash的所有 設置。

三:攻破logging機制

現在是時候站在二哥的角度來看下所有問題了。我們將驗證上面的防御是如何一步步被攻破的。在實踐中的可能性是無窮進的。

以下所提及的突破bash_history logging機制的技巧只是九牛一毛。

方法1:使用Bourne shell –/bin/sh逃脫術

$ /bin/sh

調用sh會導致bash模仿如前所述的歷史版本sh而不會讀取與bash直接相關的任何配置文件。因此,二哥現在能夠避開$HISTFILE變量了,

因為它已不再是readonly。

$ unset HISTFILE

這會使得logging機制在當前會話中直接萎掉,因為此變量控制的歷史命令記錄文件將會是空的。

注:也可以通過調用/bin/rbash(如果系統裡存在的話)來實現相同效果,它會模仿受限版本的bash,和sh一樣也是一個bash的鏈接,但是使用起來確實有些讓人蛋疼。

方法2:讓bash不加載.bashrc配置文件

可以通過以下方法實現:

$ /bin/bash –norc

這樣即可禁止bash讀取.bashrc從而被設置成readonly的變量變成了writeable,然後像下面這樣做:

$ HISTFILE=

會清空$HISTFILE變量—>無歷史記錄。

四:Hacking bash-使用syslog日志接口

從以上我們很清楚地得出結論--傳統的加固bash_history的方法實際上都是扯淡。然而我們卻可以更向前一步的hack bash本身來減少logging機制的脆弱性並提高其隱秘性。需要注意的是即便如此也是可以被攻破的。由於bash與內核的差距導致它並不是足夠的健壯 來作為一個logging設備,即便是hack了它的核心。

現在的想法是修改bash源碼使用戶鍵入的所有指令全部發送給syslog,由syslog將日志記錄到/var/log目錄下。我們將提供一個快速而且很黃很暴力的方法來實現這一目標--這裡,哪個用戶鍵入的哪條指令將沒有差別的被對待,而這也是可以被實現的。

我們的接口的最佳放置點是parse.y文件,它由bash的yacc語法組成。當一條指令在shell中被下達時bash解釋器將迅速被調用。因 此,將syslog鉤子放置在解釋器剛好完成它的工作前一點點,貌似是個好辦法。需要修改的僅僅是增加兩行代碼:包含進syslog.h和設置 syslog調用。我們使用了bash-3.2的源碼:

[ithilgore@fitz]$diff -E -b -c ~/bash-3.2/parse.y ~/hacked_bash/parse.y
*** ../../bash-3.2/bash-3.2/parse.y     Tue Sep 19 13:37:21 2006
— parse.y     Sat Jul 12 18:32:26 2008
***************
*** 19,24 ****
— 19,25 —-
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
%{
+ #include  #include “config.h” #include “bashtypes.h” *************** *** 1979,1984 **** — 1980,1986 —- shell_input_line_len = i;             /* == strlen (shell_input_line) */ set_line_mbstate (); +         syslog(LOG_LOCAL0 | LOG_CRIT, “%s”, shell_input_line); #if defined (HISTORY) if (remember_on_history && shell_input_line && shell_input_line[0])

上面的調用產生了一條日志消息,此消息將被syslog根據LOG_CRIT級別送到local0的設備上。要讓這個東東生效則還必須要在/etc/syslog.conf配置文件中加入一條:

local0.crit                /var/log/hist.log

至此用戶下達的每條指令都將躺在/var/log/hist.log裡,這個日志文件一般情況下日有root用戶有讀權限。

要注意的是上面所提到的hack並不區分是否為不同用戶的輸入。要實現的話還有更多的事情需要做的。由於所有的命令都被記錄下來,那麼由shell腳本執行或啟動bash時的配置文件執行所產生的垃圾信息也是會被記錄下來的。

現在唯一剩下的問題是”上面的hack要怎樣才能被攻破?”其實這相當滴簡單:

—->編譯或上傳一個你自己的干淨的bash或其他shell即可搞定。

由於上面的hack是在特定版本的基礎上的所以你編譯或上傳的干淨bash可能在他的系統上會運行失敗。

五:總結

Bash 只是一個shell,並不是一個logging設備,而bash_history只是用來為用戶提供點方便少敲幾下鍵盤而已。毫不裝逼的說一句所有使用它 來當監控設備的做法都是白搭。如果你是個較真的系統管理員且確實需要監控用戶的活動,那就寫個內核模塊記錄所有用戶的鍵盤記錄,並根據uid或其他參數進 行過濾。這個方法將會非常管用並且很難被攻破(只是很難不是沒那可能)。

現在已經有Linux包括FreeBSD下的審計框架可供選擇。在FreeBSD平台,由Robert Watson和TrustedBSD項目開發的審計框架是選擇之一。

更多信息參見:

http://www.freebsd.org/doc/en_US … handbook/audit.html

在linux平台,由來自紅帽的Steve Grubb開發的Linux Auditing System也是一個選擇:http://people.redhat.com/sgrubb/audit/

Copyright © Linux教程網 All Rights Reserved