被入侵服務器的症狀
當服務器被沒有經驗攻擊者或者自動攻擊程序入侵了的話,他們往往會消耗 100% 的資源。他們可能消耗 CPU 資源來進行數字貨幣的采礦或者發送垃圾郵件,也可能消耗帶寬來發動 DoS 攻擊。
因此出現問題的第一個表現就是服務器 “變慢了”。這可能表現在網站的頁面打開的很慢,或者電子郵件要花很長時間才能發送出去。
那么你應該查看那些東西呢?
檢查 1 - 當前都有誰在登錄?
你首先要查看當前都有誰登錄在服務器上。發現攻擊者登錄到服務器上進行操作並不復雜。
其對應的命令是 w。運行 w 會輸出如下結果:
- 08:32:55 up 98 days, 5:43, 2 users, load average: 0.05, 0.03, 0.00
- USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
- root pts/0 113.174.161.1 08:26 0.00s 0.03s 0.02s ssh root@coopeaa12
- root pts/1 78.31.109.1 08:26 0.00s 0.01s 0.00s w
第一個 IP 是英國 IP,而第二個 IP 是越南 IP。這個不是個好兆頭。
停下來做個深呼吸, 不要恐慌之下只是干掉他們的 SSH 連接。除非你能夠防止他們再次進入服務器,否則他們會很快進來並踢掉你,以防你再次回去。
請參閱本文最后的“被入侵之后怎么辦”這一章節來看找到了被入侵的證據后應該怎么辦。
whois 命令可以接一個 IP 地址然后告訴你該 IP 所注冊的組織的所有信息,當然就包括所在國家的信息。
檢查 2 - 誰曾經登錄過?
Linux 服務器會記錄下哪些用戶,從哪個 IP,在什么時候登錄的以及登錄了多長時間這些信息。使用 last 命令可以查看這些信息。
輸出類似這樣:
- root pts/1 78.31.109.1 Thu Nov 30 08:26 still logged in
- root pts/0 113.174.161.1 Thu Nov 30 08:26 still logged in
- root pts/1 78.31.109.1 Thu Nov 30 08:24 - 08:26 (00:01)
- root pts/0 113.174.161.1 Wed Nov 29 12:34 - 12:52 (00:18)
- root pts/0 14.176.196.1 Mon Nov 27 13:32 - 13:53 (00:21)
這里可以看到英國 IP 和越南 IP 交替出現,而且最上面兩個 IP 現在還處於登錄狀態。如果你看到任何未經授權的 IP,那么請參閱最后章節。
登錄后的歷史記錄會記錄到二進制的 /var/log/wtmp 文件中(LCTT 譯注:這里作者應該寫錯了,根據實際情況修改),因此很容易被刪除。通常攻擊者會直接把這個文件刪掉,以掩蓋他們的攻擊行為。 因此, 若你運行了 last 命令卻只看得見你的當前登錄,那么這就是個不妙的信號。
如果沒有登錄歷史的話,請一定小心,繼續留意入侵的其他線索。
檢查 3 - 回顧命令歷史
這個層次的攻擊者通常不會注意掩蓋命令的歷史記錄,因此運行 history 命令會顯示出他們曾經做過的所有事情。 一定留意有沒有用 wget 或 curl 命令來下載類似垃圾郵件機器人或者挖礦程序之類的非常規軟件。
命令歷史存儲在 ~/.bash_history 文件中,因此有些攻擊者會刪除該文件以掩蓋他們的所作所為。跟登錄歷史一樣,若你運行 history 命令卻沒有輸出任何東西那就表示歷史文件被刪掉了。這也是個不妙的信號,你需要很小心地檢查一下服務器了。(LCTT 譯注,如果沒有命令歷史,也有可能是你的配置錯誤。)
檢查 4 - 哪些進程在消耗 CPU?
你常遇到的這類攻擊者通常不怎么會去掩蓋他們做的事情。他們會運行一些特別消耗 CPU 的進程。這就很容易發現這些進程了。只需要運行 top 然后看最前的那幾個進程就行了。
這也能顯示出那些未登錄進來的攻擊者。比如,可能有人在用未受保護的郵件腳本來發送垃圾郵件。
如果你最上面的進程對不了解,那么你可以 Google 一下進程名稱,或者通過 losf 和 strace 來看看它做的事情是什么。
使用這些工具,第一步從 top 中拷貝出進程的 PID,然后運行:
- strace -p PID
這會顯示出該進程調用的所有系統調用。它產生的內容會很多,但這些信息能告訴你這個進程在做什么。
- lsof -p PID
這個程序會列出該進程打開的文件。通過查看它訪問的文件可以很好的理解它在做的事情。
檢查 5 - 檢查所有的系統進程
消耗 CPU 不嚴重的未授權進程可能不會在 top 中顯露出來,不過它依然可以通過 ps 列出來。命令 ps auxf 就能顯示足夠清晰的信息了。
你需要檢查一下每個不認識的進程。經常運行 ps (這是個好習慣)能幫助你發現奇怪的進程。
檢查 6 - 檢查進程的網絡使用情況
iftop 的功能類似 top,它會排列顯示收發網絡數據的進程以及它們的源地址和目的地址。類似 DoS 攻擊或垃圾機器人這樣的進程很容易顯示在列表的最頂端。
檢查 7 - 哪些進程在監聽網絡連接?
通常攻擊者會安裝一個后門程序專門監聽網絡端口接受指令。該進程等待期間是不會消耗 CPU 和帶寬的,因此也就不容易通過 top 之類的命令發現。
lsof 和 netstat 命令都會列出所有的聯網進程。我通常會讓它們帶上下面這些參數:
- lsof -i
- netstat -plunt
你需要留意那些處於 LISTEN 和 ESTABLISHED 狀態的進程,這些進程要么正在等待連接(LISTEN),要么已經連接(ESTABLISHED)。如果遇到不認識的進程,使用 strace 和 lsof 來看看它們在做什么東西。
被入侵之后該怎么辦呢?
首先,不要緊張,尤其當攻擊者正處於登錄狀態時更不能緊張。你需要在攻擊者警覺到你已經發現他之前奪回機器的控制權。如果他發現你已經發覺到他了,那么他可能會鎖死你不讓你登陸服務器,然后開始毀屍滅跡。
如果你技術不太好那么就直接關機吧。你可以在服務器上運行 shutdown -h now 或者 systemctl poweroff 這兩條命令之一。也可以登錄主機提供商的控制面板中關閉服務器。關機后,你就可以開始配置防火牆或者咨詢一下供應商的意見。
如果你對自己頗有自信,而你的主機提供商也有提供上游防火牆,那么你只需要以此創建並啟用下面兩條規則就行了:
- 只允許從你的 IP 地址登錄 SSH。
- 封禁除此之外的任何東西,不僅僅是 SSH,還包括任何端口上的任何協議。
這樣會立即關閉攻擊者的 SSH 會話,而只留下你可以訪問服務器。
如果你無法訪問上游防火牆,那么你就需要在服務器本身創建並啟用這些防火牆策略,然后在防火牆規則起效后使用 kill 命令關閉攻擊者的 SSH 會話。(LCTT 譯注:本地防火牆規則 有可能不會阻止已經建立的 SSH 會話,所以保險起見,你需要手工殺死該會話。)
最后還有一種方法,如果支持的話,就是通過諸如串行控制台之類的帶外連接登錄服務器,然后通過 systemctl stop network.service 停止網絡功能。這會關閉所有服務器上的網絡連接,這樣你就可以慢慢的配置那些防火牆規則了。
重奪服務器的控制權后,也不要以為就萬事大吉了。
不要試着修復這台服務器,然后接着用。你永遠不知道攻擊者做過什么,因此你也永遠無法保證這台服務器還是安全的。
用戶登錄相關日志文件:
utmp、wtmp、btmp文件
Linux用戶登錄信息放在三個文件中:
1 /var/run/utmp:記錄當前正在登錄系統的用戶信息,默認由who和w記錄當前登錄用戶的信息,uptime記錄系統啟動時間;
2 /var/log/wtmp:記錄當前正在登錄和歷史登錄系統的用戶信息,默認由last命令查看;
3 /var/log/btmp:記錄失敗的登錄嘗試信息,默認由lastb命令查看。
這三個文件都是二進制數據文件,並且三個文件結構完全相同,是由/usr/include/bits/utmp.h文件定義了這三個文件的結構體。
默認情況下文件的日志信息會通過logrotate日志管理工具定期清理。logrotate的配置文件是/etc/logrotate.conf,此處是logrotate的缺省設置,通常不需要對它進行修改。日志文件的輪循壓縮等設置存放在獨立的配置文件中,它(們)放在/etc/logrotate.d/目錄下,它會覆蓋缺省設置。
如果不想記錄相關信息,則可以直接將相關文件刪除即可。如果系統不存在該文件,則需要在此路徑touch一個文件就可以繼續記錄相關信息了。
此外:
如果想禁用who命令,則只需要將utmp的可讀權限去掉就行,這樣非root用戶就不能用此命令了;如果是btmp文件,手工創建的話注意權限必須為600,否則不能正確寫入信息。
相關命令:
lastlog、last、lastb、ac、who、w、users、utmpdump。
其中last、lastb、who、utmpdump可以通過指定參數而查看三個中的任意一個文件。
2.1 lastlog:
列出所有用戶最近登錄的信息,或者指定用戶的最近登錄信息。lastlog引用的是/var/log/lastlog文件中的信息,包括login-name、port、last login time
lzx-clone1:/var/log # lastlog Username Port Latest root pts/1 Wed Oct 19 14:37:46 +0800 2016 bin **Never logged in** daemon **Never logged in** gdm **Never logged in** admin **Never logged in** lzx pts/3 Wed Oct 19 15:15:24 +0800 2016
2.2 last
列出當前和曾經登入系統的用戶信息,它默認讀取的是/var/log/wtmp文件的信息。輸出的內容包括:用戶名、終端位置、登錄源信息、開始時間、結束時間、持續時間。注意最后一行輸出的是wtmp文件起始記錄的時間。當然也可以通過last -f參數指定讀取文件,可以是/var/log/btmp、/var/run/utmp
[root@CLMUGR-APP-D-01 log]# last root pts/0 10.200.108.92 Tue Oct 18 15:04 still logged in root pts/1 10.200.108.92 Wed Oct 12 17:02 still logged in root pts/0 10.200.108.92 Wed Oct 12 09:20 - 16:58 (07:38) root pts/0 10.200.108.92 Sat Oct 8 10:40 - 14:45 (04:05) root pts/0 10.200.108.92 Wed Aug 31 10:52 - 08:44 (21:52) root pts/0 10.200.108.92 Fri Jul 8 13:08 - 09:41 (25+20:32) reboot system boot 2.6.32-431.el6.x Tue Jan 13 19:40 - 19:44 (00:04) wtmp begins Tue Jan 13 19:40:22 2015
2.3 lastb
列出失敗嘗試的登錄信息,和last命令功能完全相同,只不過它默認讀取的是/var/log/btmp文件的信息。當然也可以通過last -f參數指定讀取文件,可以是/var/log/btmp、/var/run/utmp
[root@CLMUGR-APP-D-01 log]# lastb root ssh:notty 10.200.108.92 Wed Oct 19 17:11 - 17:11 (00:00) root ssh:notty 10.200.108.92 Wed Oct 19 17:11 - 17:11 (00:00) root ssh:notty 10.200.108.92 Wed Oct 19 17:10 - 17:10 (00:00) root ssh:notty 10.200.108.92 Wed Oct 19 17:10 - 17:10 (00:00) btmp begins Wed Oct 19 17:10:12 2016
lzx-clone1:/var/log # lastb -F -f /var/log/wtmp root pts/0 10.200.108.92 Tue Mar 8 11:04:36 2016 - Tue Mar 8 11:04:36 2016 (00:00) wtmp begins Tue Mar 8 11:04:36 2016
2.4 ac
輸出所有用戶總的連接時間,默認單位是小時。由於ac是基於wtmp統計的,所以修改或者刪除wtmp文件都會使ac的結果受影響。(Suse默認沒有該命令)
[root@cloudexpress ~]# ac
total 7404.62
2.5 who
查看當前登入系統的用戶信息。其中who -m等效於who am i。
語法who [OPTION]... [ FILE | ARG1 ARG2 ]。
who命令強大的一點是,它既可以讀取utmp文件也可以讀取wtmp文件,默認沒有指定FILE參數時,who查詢的是utmp的內容。當然可以指定FILE參數,比如who -aH /var/log/wtmp,則此時查看的是wtmp文件。
查看當前運行級別
[root@CLMUGR-APP-D-01 log]# who -rH
名稱 線路 時間 空閑 進程號 備注
運行級別 5 2016-07-08 13:01
查看登錄用戶和用戶數≈users
lzx-clone1:/var/run # who -q
root root root root
# users=4
2.6 w
查看當前登入系統的用戶信息及用戶當前的進程(而who命令只能看用戶不能看進程)。該命令能查看的信息包括字系統當前時間,系統運行時間,登陸系統用戶總數及系統1、5、10分鍾內的平均負載信息。后面的信息是用戶,終端,登錄源,login time,idle time,JCPU,PCPU,當前執行的進程等。
w的信息來自兩個文件:用戶登錄信息來自/var/run/utmp,進程信息來自/proc/.
lzx-clone1:/var/log # w 15:26:40 up 12 days, 56 min, 4 users, load average: 0.14, 0.16, 0.20 USER TTY LOGIN@ IDLE JCPU PCPU WHAT root :0 10Oct16 ?xdm? 43:33 0.69s /usr/bin/gnome-session root pts/0 Wed14 40.00s 0.19s 0.00s w root pts/1 Wed14 23:01m 0.06s 0.06s -bash root pts/2 10Oct16 9days 0.01s 0.01s /bin/bash -l
2.7 users
顯示當前正在登入統的用戶名。語法是users [OPTION]... [FILE]。如果未指定FILE參數則默認讀取的是/var/run/utmp,當然也可以指定通用相關文件/var/log/wtmp,此時輸出的就不是當前用戶了。
[root@CLMUGR-APP-D-01 log]# users
root root
2.8 utmpdump
utmpdump用於轉儲二進制日志文件到文本格式的文件以便查看,同時也可以修改二進制文件!!包括/var/run/utmp、/var/log/wtmp、/var/log/btmp。語法為:utmpdump [options] [filename]。修改文件實際就可以抹除系統記錄,所以一定要設置好權限,防止非法入侵。
例子:修改utmp或wtmp。由於這些都是二進制日志文件,你不能像編輯文件一樣來編輯它們。取而代之是,你可以將其內容輸出成為文本格式,並修改文本輸出內容,然后將修改后的內容導入回二進制日志中。如下:
utmpdump /var/log/utmp > tmp_output.txt #導出文件信息 #<使用文本編輯器修改 tmp_output.txt> utmpdump -r tmp_output.txt > /var/log/utmp #導入到源文件中