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

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

加固bash_history bash

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

由於全部用戶都是使用bash做爲默認shell,你開始着手修改bash的配置文件: app

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

二哥所作的第一件事應該是創建history到/dev/null的連接。 ui

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

這能夠經過修改歷史記錄文件爲只能被追加來進行阻止,執行如下命令來改變其屬性: 日誌

# chattr +a /home/bob/.bash_history

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

# 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項目開發的審計框架是選擇之一。

相關文章
相關標籤/搜索