在日常繁瑣的運維工作中,對linux伺服器進行安全檢查是一個非常重要的環節。今天,分享一下如何檢查linux系統是否遭受了入侵?
一、是否入侵檢查
1)檢查系統日誌
檢查系統錯誤登陸日誌,統計IP重試次數(last命令是檢視系統登陸日誌,比如系統被reboot或登陸情況) [root@bastion-IDC ~]# last
2)檢查系統使用者
檢視是否有異常的系統使用者 [root@bastion-IDC ~]# cat /etc/passwd 檢視是否產生了新使用者,UID和GID為0的使用者 [root@bastion-IDC ~]# grep "0" /etc/passwd 檢視passwd的修改時間,判斷是否在不知的情況下新增使用者 [root@bastion-IDC ~]# ls -l /etc/passwd 檢視是否存在特權使用者 [root@bastion-IDC ~]# awk -F: '$3==0 {print $1}' /etc/passwd 檢視是否存在空口令帳戶 [root@bastion-IDC ~]# awk -F: 'length($2)==0 {print $1}' /etc/shadow
3)檢查異常程式
注意UID為0的程式 使用ps -ef命令檢視程式 察看該程式所開啟的埠和檔案 [root@bastion-IDC ~]# lsof -p pid命令檢視 檢查隱藏程式 [root@bastion-IDC ~]# ps -ef | awk '{print }' | sort -n | uniq >1 [root@bastion-IDC ~]# ls /porc |sort -n|uniq >2 [root@bastion-IDC ~]# diff 1 2
4)檢查異常系統檔案
[root@bastion-IDC ~]# find / -uid 0 –perm -4000 –print [root@bastion-IDC ~]# find / -size +10000k –print [root@bastion-IDC ~]# find / -name "…" –print [root@bastion-IDC ~]# find / -name ".." –print [root@bastion-IDC ~]# find / -name "." –print [root@bastion-IDC ~]# find / -name " " –print
5)檢查系統檔案完整性
[root@bastion-IDC ~]# rpm –qf /bin/ls [root@bastion-IDC ~]# rpm -qf /bin/login [root@bastion-IDC ~]# md5sum –b 檔名 [root@bastion-IDC ~]# md5sum –t 檔名
6)檢查RPM的完整性
[root@bastion-IDC ~]# rpm -Va #注意相關的/sbin,/bin,/usr/sbin,/usr/bin 輸出格式說明: S – File size differs M – Mode differs (permissions) 5 – MD5 sum differs D – Device number mismatch L – readLink path mismatch U – user ownership differs G – group ownership differs T – modification time differs
7)檢查網路
[root@bastion-IDC ~]# ip link | grep PROMISC(正常網路卡不該在promisc模式,可能存在sniffer) [root@bastion-IDC ~]# lsof –i [root@bastion-IDC ~]# netstat –nap(察看不正常開啟的TCP/UDP埠) [root@bastion-IDC ~]# arp –a
8)檢查系統計劃任務
[root@bastion-IDC ~]# crontab –u root –l [root@bastion-IDC ~]# cat /etc/crontab [root@bastion-IDC ~]# ls /etc/cron.*
9)檢查系統後門
[root@bastion-IDC ~]# cat /etc/crontab [root@bastion-IDC ~]# ls /var/spool/cron/ [root@bastion-IDC ~]# cat /etc/rc.d/rc.local [root@bastion-IDC ~]# ls /etc/rc.d [root@bastion-IDC ~]# ls /etc/rc3.d
10)檢查系統服務
[root@bastion-IDC ~]# chkconfig —list [root@bastion-IDC ~]# rpcinfo -p(檢視RPC服務)
11)檢查rootkit
[root@bastion-IDC ~]# rkhunter -c [root@bastion-IDC ~]# chkrootkit -q
二、linux系統被入侵/中毒的表象
比較常見的中毒表現在以下三個方面: 1)伺服器出去的頻寬會跑高這個是中毒的一個特徵。 因為伺服器中毒之後被別人拿去利用,常見的就是拿去當肉雞攻擊別人;再者就是拿你的資料之類的。 所以伺服器頻寬方面需要特別注意下,如果伺服器出去的頻寬跑很高,那肯定有些異常,需要及時檢查一下! 2)系統裡會產生多餘的不明的使用者 中毒或者被入侵之後會導致系統裡產生一些不明使用者或者登陸日誌,所以這方面的檢查也是可以看出一些異常的。 3)開機是否啟動一些不明服務和crond任務裡是否有一些來歷不明的任務? 因為中毒會隨系統的啟動而啟動的,所以一般會開機啟動,檢查一下啟動的服務或者檔案是否有異常,一般會在/etc/rc.local和crondtab -l 顯示出來。
三、順便說下一次Linux系統被入侵/中毒的解決過程
在工作中碰到系統經常卡,而且有時候遠端連線不上,從本地以及遠端檢查一下這個系統,發現有不明的系統程式。 初步判斷就是可能中毒了!!! 解決過程: 1)在監控裡檢查一下這臺伺服器的頻寬,發現伺服器出去的頻寬跑很高,所以才會導致遠端連線卡甚至連線不上,這是一個原因。 為什麼伺服器出去的頻寬這麼高且超出了開通的頻寬值?這個原因只能進入伺服器系統裡檢查了。 2)遠端進入系統裡檢查了下, ps -aux查到不明程式 ,立刻關閉它。 3)檢查一下開機啟動項: #chkconfig --list | grep 3:on 伺服器啟動級別是3的,我檢查一下了開機啟動項,沒有特別明顯的服務。 然後檢查了一下開機啟動的一個檔案 #more /etc/rc.local 看到這個檔案裡被新增了很多未知項,註釋了它。 4)然後在遠端連線這臺伺服器的時候,還是有些卡。 檢查了一下系統的計劃任務crond,使用crondtab -l 命令進行檢視,看到很多註釋行。 這些註釋行與/etc/rc.local的內容差不多。最後備份下/var/spool/cron/root檔案(也就是root下的crontab計劃任務內容),就刪除了crontab內容,然後停止crond任務,並chkconfig crond off 禁用它開機啟動。 5)為了徹底清除危害,我檢查了一下系統的登陸日誌(last命令檢視),看到除了root使用者之外還有其它的使用者登陸過。 檢查了一下/etc/passwd ,看到有不明的使用者,立刻用usermod -L XXX 禁用這些使用者。 然後更新了下系統的複雜密碼。
==============================================================
禁用/鎖定使用者登入系統的方法 1. usermod -L username 鎖定使用者 usermod -U username 解鎖 2. passwd -l username 鎖定使用者 passwd -u username 解鎖 3.修改使用者的shell型別為/sbin/nologin(/etc/passwd檔案裡修改) 4.在/etc/下建立空檔案nologin,這樣就鎖定了除root之外的全部使用者
四、怎樣確保linux系統安全
1)從以往碰到的例項來分析,密碼太簡單是一個錯 使用者名稱預設,密碼太簡單是最容易被入侵的物件,所以切忌不要使用太過於簡單的密碼,先前碰到的那位客戶就是使用了太簡單的且規則的密碼 1q2w3e4r5t, 這種密碼在掃描的軟體裡是通用的,所以很容易被別人掃描出來的。 2)不要使用預設的遠端埠,避免被掃描到 掃描的人都是根據埠掃描,然後再進行密碼掃描,預設的埠往往就是掃描器的物件,他們掃描一個大的IP 段,哪些開放22埠且認為是ssh服務的linux系統,所以才會猜這機器的密碼。更改遠端埠也是安全的一個措施! 3)使用一些安全策略進行保護系統開放的埠 使用iptables或者配置/etc/hosts.deny 和/etc/hosts.allow進行白名單設定 可以對/etc/passwd、/etc/group、/etc/sudoers、/etc/shadow等使用者資訊檔案進行鎖定(chattr +ai) 4)禁ping設定 # echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
====================================================
發現一次伺服器被getshell滲透的解決辦法:
1)使用top命令發現一個python程式佔用了95%的cpu 2)使用ps -ef|grep python發現下面程式: python -c import pty;pty.spamn("/bin/sh") 這個程式命令表示通過webshell反彈shell回來之後獲取真正的ttyshell進行滲透到伺服器裡。kill掉這個程式! 3)發現在/var/spool/cron下面設定了一個nobody的定時執行上面獲取getshell的滲透命令!果斷刪除這個任務! 4)ss -a發現一個可疑ip以及它的程式,果斷在iptables裡禁止這個ip的所有請求: -I INPUT -s 180.125.131.192 -j DROP
比如: 在一臺伺服器上,已經啟動了80埠的nginx程式,但是執行“lsof -i:80”或者"ps -ef"命令後,沒有任何資訊輸出!這是為什麼?
懷疑機器上的ps命令被人黑了!執行:
[root@locahost ~]# which ps /bin/ps [root@locahost ~]# ls -l /bin/ps -rwxr-xr-x. 1 root root 85304 5月 11 2016 /bin/ps [root@locahost ~]# stat /bin/ps File: "/bin/ps" Size: 85304 Blocks: 168 IO Block: 4096 普通檔案 Device: fc02h/64514d Inode: 13549 Links: 1 Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2017-05-07 17:14:37.862999884 +0800 Modify: 2016-05-11 07:23:09.000000000 +0800 Change: 2017-05-07 17:14:37.146999967 +0800 發現ps命令的二進位制檔案果然在近期被改動過。 解決辦法:可以拷貝別的機器上的/bin/ps二進位制檔案覆蓋本機的這個檔案。
=======================記一次Linux作業系統被入侵的排查過程=======================
某天突然發現IDC機房一臺測試伺服器的流量異常,幾乎佔滿了機房的總頻寬,導致其他伺服器程式執行業務受阻! 意識到了這臺測試機被人種了木馬,於是開始了緊張的排查過程: 1)執行ps和top命令 發現了兩個陌生名稱的程式(比如mei34hu)佔用了大部分CPU資源,顯然這是別人植入的程式! 果斷嘗試kill掉這兩個程式,kill後,測試機流量明顯降下去。然而不幸的是,不一會兒又恢復了之前的狀態。 2)將IDC這臺測試機的外閘道器閉。遠端通過跳板機內網登陸這臺機器。 3)檢視這些陌生程式所在路徑 查詢程式路徑: ls /proc/程式號/exe,然後再次kill掉程式,又會生成一個新的程式名,發現路徑也是隨機在PATH變數的路徑中變換,有時在/bin目錄,有時在/sbin,有時在/usr/bin目錄中。 看來還有後臺主控程式在作怪,繼續查詢。 4)嘗試查詢跟蹤程式 檢視/bin,/sbin,/usr/bin等目錄下是否存在以.開頭的檔名,發現不少,而且部分程式移除後會自動生成。 [root@localhost ~]# ls /usr/bin/. //按Tab鍵補全 ./ ../ .ssh.hmac 這說明還沒找到主控程式。 5)接著用strace命令跟蹤這些陌生程式: [root@localhost ~]# strace /bin/mei34hu 結果發現在跟蹤了這個程式後,它居然自殺了(把自己程式檔案幹掉了)!然後想用netstat看下網路連線情況,結果居然查不到任何對外的網路連線,於是開始懷疑命令被修改過了。 使用stat 檢視系統命令ps、ls 、netstat、pstree等等: [root@localhost ~]# which ps /usr/bin/ps [root@localhost ~]# which ls alias ls='ls --color=auto' /usr/bin/ls [root@localhost ~]# which netstat /usr/bin/netstat [root@localhost ~]# stat /usr/bin/netstat [root@localhost ~]# stat /usr/bin/ps [root@localhost ~]# stat /usr/bin/ls ...... 發現修改時間都是在最近的3天內,這讓我猛然想起傳說中的rootkit使用者態級病毒!! 有可能是這臺測試機剛安裝好系統後,設定了root密碼為123456,之後又把它放到過公網上被人入侵了。 接著查一下它在相關路徑中還放了哪些程式: [root@localhost ~]# find /bin -mtime -3 -type f | xargs rm -f [root@localhost ~]# find /usr/bin -mtime -3 -type f | xargs rm -f [root@localhost ~]# find /use/sbin -mtime -3 -type f | xargs rm -f [root@localhost ~]# find /sbin -mtime -3 -type f | xargs rm -f 將上面查詢出的3天前的程式統統都刪掉,並強制斷電,重啟伺服器!然而可恨的是這些程式在機器重啟後又好端端的執行以來! 很明顯,這些程式都被設定了開機自啟動 6)檢視系統啟動項 [root@localhost ~]# find /etc/rc.d/ -mtime -3 ! -type d 果然這些程式都被設定了開機自啟動。於是,就再來一次刪除,然後暴力重啟伺服器。 [root@localhost ~]# find /bin -mtime -3 -type f | xargs rm -f [root@localhost ~]# find /usr/bin -mtime -3 -type f | xargs rm -f [root@localhost ~]# find /use/sbin -mtime -3 -type f | xargs rm -f [root@localhost ~]# find /sbin -mtime -3 -type f | xargs rm -f [root@localhost ~]# find /etc/rc.d/ -mtime -3 ! -type d | xargs rm -f 重啟完伺服器後,用top命令檢視,系統CPU使用率也不高了。居然這樣就被幹掉了。 7)顧慮到系統常用命令中(如ls,ps等)可能會隱藏啟動程式,這樣一旦執行又會拉起木馬程式。於是再檢視下系統中是否建立了除root以外的管理員賬號: [root@localhost ~]# awk -F":" '{if($3 == 0) print $1}' /etc/passwd root 結果發現只輸入了root這一個使用者,說明系統使用者是正常的。 其實,當系統被感染rootkit後,系統已經變得不可靠了,唯一的辦法就是重灌系統了。 8)對於一些常用命令程式的修復思路:找出常用命令所在的rpm包,然後強制刪除,最後在通過yum安裝(由於外網已拿掉,可以通過squid代理上網的yum下載) [root@localhost ~]# rpm -qf /bin/ps [root@localhost ~]# rpm -qf /bin/ls [root@localhost ~]# rpm -qf /bin/netstat [root@localhost ~]# rpm -qf /usr/bin/pstree 然後將上面命令查詢出來的rpm包強制解除安裝 [root@localhost ~]# rpm -e --nodeps ...... [root@localhost ~]# rpm -e --nodeps ...... [root@localhost ~]# rpm -e --nodeps ...... [root@localhost ~]# rpm -e --nodeps ...... 接著再重新安裝 [root@localhost ~]# yum install -y procps coreutils net-tools psmisc 最後重啟下系統即可。除了上面這次排查之外,還可以: 1)結合伺服器的系統日誌/var/log/messages、/var/log/secure進行仔細檢查。 2)將可疑檔案設為不可執行,用chattr +ai將幾個重要目錄改為不可新增和修改,再將程式殺了,再重啟 3)chkrootkit之類的工具查一下 對於以上這些梳理的木馬排查的思路要清楚,排查手段要熟練。遇到問題不要慌,靜下心,細查系統日誌,根據上面的排查思路來一步步處理,這樣Hacker就基本"投降"了~~~
=====================針對一些linux應用漏洞, 做出的必要修改 (應用版本資訊隱藏等)===================
1) 關閉Apache伺服器的TRACE請求, 或是禁止遠端WWW服務支援TRACE請求
TRACE_Method是HTTP(超文字傳輸)協議定義的一種協議除錯方法,該方法會使伺服器原樣返回任意客戶端請求的任何內容。 TRACE和TRACK是用來除錯web伺服器連線的HTTP方式。支援該方式的伺服器存在跨站指令碼漏洞,通常在描述各種瀏覽器缺陷的時候,把"Cross-Site-Tracing"簡稱 為XST。攻擊者可以利用此漏洞欺騙合法使用者並得到他們的私人資訊。 1) 虛擬主機使用者可以在.htaccess檔案中新增如下程式碼過濾TRACE請求: RewriteEngine on RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) RewriteRule .* - [F] 2) 伺服器使用者在httpd.conf尾部新增如下指令後重啟apache即可: TraceEnable off
2) 隱藏apache的版本(banner資訊). 一些應用的banner資訊,容易讓黑客更快的匹配到漏洞資訊,所以隱藏起來可以提升一定的安全性。
在apache的http.conf中新增或修改成如下二條程式碼即可: ServerSignature Off ServerTokens Prod 經過以上修改,可以隱藏一些 banner. 但是用wget -S和curl -I還是可以看到apache字樣! 徹底偽裝的話需要修改原始檔: [root@localhost include]# pwd /usr/local/src/httpd-2.4.37/include [root@localhost include]# ll ap_release.h -rw-r--r-- 1 root dip 3144 Oct 18 22:33 ap_release.h 編輯ap_release.h文 件,修改 #define AP_SERVER_BASEPRODUCT "Apache" 為 #define AP_SERVER_BASEPRODUCT "Microsoft-IIS/5.0" [root@localhost httpd-2.4.37]# pwd /usr/local/src/httpd-2.4.37 [root@localhost httpd-2.4.37]# ll ./os/unix/os.h -rw-r--r-- 1 root dip 1668 Sep 24 2011 ./os/unix/os.h 編輯os/unix/os.h文 件修改 #define PLATFORM "Unix" 為 #define PLATFORM "Win64" 最後再重新編譯apache
3) 隱藏php的版本
在php的php.ini中新增或修改成如下一條程式碼即可: expose_php = Off
4) 隱藏openssh版本
[root@localhost ~]# telnet 172.16.60.207 22 Trying 172.16.60.207... Connected to 172.16.60.207. Escape character is '^]'. SSH-2.0-OpenSSH_7.6 如上, 可以看到openssh版本洩露了. 下面介紹下隱藏openssh版本的方法: 找到openssh的解壓目錄 [root@localhost ~]# cd /usr/local/src/openssh-7.6p1 [root@localhost openssh-7.6p1]# cat version.h /* $OpenBSD: version.h,v 1.80 2017/09/30 22:26:33 djm Exp $ */ #define SSH_VERSION "OpenSSH_7.6" #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE 修改 #define SSH_VERSION "OpenSSH_7.6" 這一行, 比如修改為"#define SSH_VERSION "OpenSSH"" 接著進行編譯安裝即可
5) 隱藏ssh版本
修改SSH登入時的Banner資訊 首先建立一個檔案, 用於ssh登入後的banner資訊提示, 提示內容可以自行定義 [root@localhost ~]# touch /etc/ssh_banner_change [root@localhost ~]# echo "welcome to login this server:172.16.60.207" > /etc/ssh_banner_change [root@localhost ~]# cat /etc/ssh_banner_change welcome to login this server:172.16.60.207 接著修改SSH配置檔案中的banner檔案路徑 [root@localhost ~]# vim /etc/ssh/sshd_config #Banner none Banner /etc/ssh_banner_change 然後重啟ssh服務 [root@localhost ~]# /etc/init.d/sshd restart Stopping sshd: [ OK ] Starting sshd: [ OK ] 這樣, 在遠端登入這臺機器, 就會看到定義的banner資訊了
6) 隱藏Proftpd版本資訊
修改proftpd的配置檔案: 1) 偽裝登入歡迎資訊 修改 ServerIdent on "Serv-U FTP Server v5.0 for WinSock ready...\" 或 ServerIdent off 如上配置後, telnet proftpd埠後會顯示: 220 ::ffff:192.168.2.3 FTP server ready 2) 偽裝banner資訊 DisplayLogin [msgfile] DisplayConnect [msgfile]
7) 隱藏vsftpd版本資訊
配置檔案:vsftpd.conf 修改 ftpd_banner=welcome to this FTP server
8) 隱藏Nginx版本資訊
在nginx.conf 的 http區域裡頭加入 server_tokens 的引數 server_tokens off; 如果想要徹底屏敝, 則需要修改原始碼 [root@uatclient-node01 core]# pwd /data/software/nginx-1.12.2/src/core [root@uatclient-node01 core]# ll nginx.h -rw-r--r-- 1 ambari-qa 1001 476 Oct 17 2017 nginx.h 找到 #define nginx_version 1012002 #define NGINX_VERSION "1.12.2" #define NGINX_VER "nginx/" NGINX_VERSION 把上面三行內容 偽裝成其他資訊, 如下 #define nginx_version 1111111 #define NGINX_VERSION "0.0000" #define NGINX_VER "nginx/" NGINX_VERSION 然後再次編輯即可
9) TTL
用以下命令修改Linux的TTL基數為128(預設為64) [root@uatclient-node01 core]# cat /proc/sys/net/ipv4/ip_default_ttl 64 [root@uatclient-node01 core]# echo "128" > /proc/sys/net/ipv4/ip_default_ttl [root@uatclient-node01 core]# cat /proc/sys/net/ipv4/ip_default_ttl 128 還可以在核心引數裡修改 [root@uatclient-node01 core]# vim /etc/sysctl.conf net.ipv4.ip_default_ttl = 128 [root@uatclient-node01 core]# sysctl -p