應急響應有一半是非技術的內容,制定一個合理的響應策略是至關重要的!
記住:現在開始對受害系統的每一步操作都可能改變已存在的證據或是導致敏感信息的丟失!
{{初始響應}}
目標:在進行司法鑒定復制之前獲得系統中的易失數據,初步確定突發事件概況。
==============
創建響應工具包
==============
我們調查系統,必須以高度可信賴的程序執行命令,再加上備份與修復,創建一個工具包是很有必要的。
即使在非UNIX/LINUX系統上,創建工具包也應該作為響應的第一步。
首先,我們需要在對應體系結構的系統上編譯響應期間需要的工具,且編譯程序需要考慮系統兼容的問題。
通常我們需要如下的工具:
ls dd des file pkginfo
find icat lsof md5sum nc
netstat pcat perl ps strace
strings truss df vi
cat kstat ifconfig chkrootkit
more gzip last w rm
script bash modinfo lsmod
讀者可根據自己的需要自行添加,但是一個工具包通常只能用來完成對某一特定平台的工作,
把對多個平台編譯的工具放進同一個工具包反而會顯得紊亂。
在Linux上創建響應工具包時,可以用gcc的–static參數編譯源代碼,或者用ldd檢查動態連接庫,
在響應工具包存儲介質上建立庫文件目錄,並拷貝所有工具需要的動態連接庫的副本,最後設置環境變量。
這個過程有點類似於創建一個Linux的優盤啟動盤。
============
獲取易失數據
============
易失的數據包括:當前打開的套接字,進程列表,RAM內容,非鏈接文件的位置。
*unix特性: unix允許進程正在執行時將其刪除!
非鏈接文件是訪問該文件的進程中止時被標記為刪除的文件。當系統關閉時(正常關機或突然斷電非正常關機),
標記為刪除的文件都將消失。因此在找到被標記為刪除的文件之前不能關機!
=================
執行可信賴的shell
=================
使用我們自己准備的響應工具包,裝載該介質的文件系統,
mount –t auto /dev/sda1 /mnt/usb 或
mount –t iso9660 /dev/cdrom /mnt/cdrom
按下Ctrl+Alt+F1~F6,從控制台以root身份登陸。
請一定要區分原環境變量中的命令和當前響應工具包的相同名字的命令集,防止潛在的二進制特洛伊木馬攻擊。
==================
查看登陸系統的用戶
==================
[root@ay4z3ro foo]# w
19:50:48 up 43 min, 2 users, load average: 0.00, 0.00, 0.00
USER TTY LOGIN@ IDLE JCPU PCPU WHAT
root :0 19:08 ?xdm? 11.10s 0.43s gnome-session
root pts/0 19:08 1.00s 0.21s 0.01s w
輸出標題行顯示了當前系統時間,該系統已運行的時間,當前登陸用戶數,最近1分鐘,5分鐘和15分鐘內的平均系統負載。
USER字段顯示當前登陸的用戶名。TTY字段顯示了會話的控制終端,tty表示從控制台登陸,pts/typ則可以表示通過一個網絡連接,
因為X是個C/S模式的應用程序,所以我在GNOME下開的shell窗口顯示為pts。如果不從本地登陸,輸出中還有FROM字段,
表示建立會話的源地址的域名或IP。LOGIN@顯示該連接的本地開始時間。IDLE字段顯示了自上一個進程運行以來的時間長度。
JCPU顯示與tty或pts關聯的全部進程所使用的時間。PCPU字段顯示了WHAT列中當前進程所使用的CPU時間。WHAT列顯示用戶當前運行的進程。
================
查看系統進程列表
================
Solaris中使用ps –eaf,而在FreeBSD和Linux中則使用ps –aux.
[root@ay4z3ro foo]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.2 1356 496 ? S 19:07 0:04 init
root 2 0.0 0.0 0 0 ? SW 19:07 0:00 [keventd]
root 3 0.0 0.0 0 0 ? SWN 19:07 0:00 [ksoftirqd_CPU0]
root 4 0.0 0.0 0 0 ? SW 19:07 0:00 [kswapd]
root 5 0.0 0.0 0 0 ? SW 19:07 0:00 [bdflush]
root 6 0.0 0.0 0 0 ? SW 19:07 0:00 [kupdated]
root 7 0.0 0.0 0 0 ? SW< 19:07 0:00 [mdrecoveryd]
root 11 0.0 0.0 0 0 ? SW 19:07 0:00 [kjournald]
root 114 0.0 0.5 2108 1304 ? S 19:07 0:00 devfsd /dev
root 209 0.0 0.0 0 0 ? SW 19:07 0:00 [khubd]
root 338 0.0 0.0 0 0 ? SW 19:07 0:00 [kjournald]
rpc 620 0.0 0.2 1496 520 ? S 19:07 0:00 [portmap]
root 636 0.0 0.2 1452 624 ? S 19:07 0:00 syslogd -m 0
…………………(以下省略)
Ps命令輸出中的START字段顯示了程序開始運行的時間,對於查出攻擊時間很有幫助。有時僅通過時間就能識別可疑進程。
Linux下還可以通過strings –f /proc/[0-9]*/cmdline來查看系統中運行進程的完整命令行參數,但是這個並不完全可信。
因為攻擊者甚至不需要插入內核模塊,而只在應用層的編碼中加入語句就能欺騙我們。
===============
檢測LKM Rootkit
===============
內核模塊後門,還有什麼比這個更臭屁的呢?Solaris,Linux和幾乎所有的UNIX都支持LKM(Loadable Kernel Modules),
用普通的方法無法檢測其存在,這給應急響應帶來了極大的挑戰性。對於我們來說,解決的辦法是找到那些lkm rootkit,
並熟悉,解剖他們。有時lkm rootkit雖然被成功裝載,但在系統的某些細節上會出現“異常”,甚至可能使系統在運行一段時間後徹底崩潰。
還有,lkm雖然活動在ring0核心態,但是攻擊者往往會在系統的某處留下痕跡,比如攻擊者為了讓系統每次關閉或重啟後能自動裝入他安置的
kstat/ksec是檢測lkm非常方便的工具,前者用於Linux,後者用於*BSD.
[root@ay4z3ro kstat]# ./kstat
Usage: ./kstat [-i iff] [-P] [-p pid] [-M] [-m addr] [-s]
-i iff may be specified as 'all' or as name (e.g. eth0)
displays info about the queried interface
-P displays all processes
-p pid is the process id of the queried task
-M displays the kernel's LKMs' linked list
-m addr is the hex address of the queried module
displays info about the module to be found at addr
-s displays info about the system calls' table
其中-s參數最有用,它顯示了系統調用入口的信息,能檢測市面上最流行的knark和adore這兩個內核後門,
但理論上他並不能檢測出所有的lkm rootkit.
其實熟悉內核攻擊的人都知道Kstat單純檢查sys_call_table[]的方式如今已經
被攻擊的一方完全超越,e4gle很早也寫過這類文章。
有興趣可以看看2002焦點峰會jbtzhm的《內核後門實現及其檢測》
現在linuxforum安全版版主madsys在Phrack61上有篇文章:
Finding hidden kernel modules (the extrem way)--鏈接:
======================
檢測開放端口和關聯進程
======================
[root@ay4z3ro foo]# netstat –anp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 620/
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN 908/X
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 880/sshd
udp 0 0 0.0.0.0:111 0.0.0.0:* 620/
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node PID/Program name Path
unix 2 [ ACC ] STREAM LISTENING 2753 756/ /tmp/.font-unix/fs-1
……(以下省略)
在Solaris,HP-UX,AIX,FreeBSD,Linux上可以使用lsof工具列舉所有運行進程及其所打開的文件描述符,其中包括常規文件,
庫文件,目錄,UNIX流,套接字等。如果只想顯示網絡套接字的進程:
[root@ay4z3ro foo]# lsof –i
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
portmap 620 rpc 3u IPv4 2598 UDP *:sunrpc
portmap 620 rpc 4u IPv4 2609 TCP *:sunrpc (LISTEN)
sshd 880 root 3u IPv4 2885 TCP *:ssh (LISTEN)
X 908 root 1u IPv4 2945 TCP *11 (LISTEN)
其中特別需要注意的是奇怪的進程和已打開的原始套接字。
================================
尋找系統中是否運行一個非法嗅探器
================================
為了達到這個目的,我們需要檢查網卡是否處於混雜(promiscuous)模式:
[root@ay4z3ro foo]# ifconfig –i eth0 | grep PROMISC
PROMISC標志並不會在所有的*NIX上出現,通過lsof+ps命令可以判斷系統是否正運行一個嗅探器。或者通過第三方的工具,比如AntiSniff。
=================
檢查/proc文件系統
=================
在/proc/$PID/目錄下對於調查比較有意義的是:exe鏈接,fd子目錄,cmdline文件。
[root@ay4z3ro 880]# ls -al
total 0
dr-xr-xr-x 3 root root 0 Sep 20 19:53 ./
dr-xr-xr-x 62 root root 0 Sep 20 15:07 ../
-r--r--r-- 1 root root 0 Sep 20 19:54 binfmt
-r--r--r-- 1 root root 0 Sep 20 19:54 cmdline
lrwxrwxrwx 1 root root 0 Sep 20 19:54 cwd ->; //
-r-------- 1 root root 0 Sep 20 19:54 environ
lrwxrwxrwx 1 root root 0 Sep 20 19:54 exe ->; /usr/sbin/sshd*
dr-x------ 2 root root 0 Sep 20 19:54 fd/
-r--r--r-- 1 root root 0 Sep 20 19:54 maps
-rw------- 1 root root 0 Sep 20 19:54 mem
-r--r--r-- 1 root root 0 Sep 20 19:54 mounts
lrwxrwxrwx 1 root root 0 Sep 20 19:54 root ->; //
-r--r--r-- 1 root root 0 Sep 20 19:54 stat
-r--r--r-- 1 root root 0 Sep 20 19:54 statm
-r--r--r-- 1 root root 0 Sep 20 19:54 status
Exe鏈接允許我們恢復被刪除的文件,只要這些文件仍然運行。為獲得“已刪除”可執行文件的備份,只需要使用cp命令在該文件系統上
創建一個拷貝就行。通過檢查fd子目錄,可以識別該進程打開的所有文件。如果對unix環境下的編程有所了解的話,很容易就能發現
是在讀寫一個文件還是打開一個網絡連接。cmdline文件的內容是該進程的完整命令行。以下語句是攻擊者的欺騙手段,
strcpy(argv[0],”any_string”);
這樣該文件就顯示了一種假象,即使如此,我們仍有必要檢查此文件。
==================================
獲取所有文件的創建,修改和訪問時間
==================================
ls –alRu >; /mnt/usb/access
ls –alRc >; /mnt/usb/modification
ls –alR >; /mnt/usb/creation
============
獲取系統日志
============
大多數UNIX的日志在/var/log和/var/adm目錄下,各種UNIX派生系統日志的具體位置有所不同。
在此之前,有必要了解針對特定系統的日志存貯位置。
比較重要的二進制日志文件:
utmp,用w工具訪問;
wtmp,用last工具訪問;
lastlog,用lastlog工具訪問;
進程記賬日志,用astcomm工具訪問
常見的ASCII文本日志文件:
apache日志--/var/log/httpd/access_log;
ftp日志—xferlog;
命令歷史記錄文件;
/var/log/messages;
================
獲取重要配置文件
================
檢查各配置文件查找後門位置,未授權的信任關系和未授權的用戶ID。
/etc/passwd,查找未授權的用戶帳號和權限。初級的入侵者會添加uid=0的用戶,
有人也會把系統中一個不起眼的原本沒有shell的普通賬戶改成可登陸獲得shell執行命令,
然後他可以通過一個suid位的ksh或其他的安置在本地的後門馬上得到rootshell.
/etc/shadow,確保每個用戶都有密碼認證;當然攻擊者給自己的賬戶加一個md5 hash其實也是非常簡單的事。
/etc/groups,查找權限的升級和訪問范圍的擴大。
/etc/hosts,列出本地DNS條目。
/etc/hosts.equiv,檢查信任關系。
~/.rhosts,檢查基於用戶的信任關系,”++”這種很濫的後門相信大家都知道。
/etc/hosts.allow && /etc/hosts.deny 檢查tcpwrapper的規則。
/etc/rc*,檢查啟動文件。
Crontab文件,列出計劃事件。
===========
轉儲系統RAM
===========
主要是從系統轉移/proc/kmem或/proc/kcore文件,該文件以非連續方式包含系統RAM的內容。
{{深入調查}}
============
檢查系統日志
============
UNIX有很多日志,這些為應急響應提供重要的線索。日志文件大多位於公用目錄,通常是/var/log,或/usr/adm,/var/adm,
有些日志位於禁止訪問的/etc目錄。具體請參考當前操作體系統文檔。
facility字段表示產生該日志文件的子系統;priority字段表明事件的嚴重級別;
action字段表明如何記錄日志,它提供了遠程網絡記錄的能力。
TCP wrapper日志也利用syslog記錄,其中可能會有telnet,ssh,ftp等遠程登錄的信息。這些日志中有很多有價值的條目:
嘗試登陸的時間日期,主機名稱,訪問的服務類型,以及源IP地址。
其他的網絡日志比如,web,ftp,sql通常自身都提供了較為詳細的信息。Apache默認日志在/usr/local/apache/logs,
最有用的日志是access_log,還有ssl_request_log,ssl_engine_log也能提供有價值的信息。其中可能包含攻擊前的掃描記錄。
Su命令日志,記錄了每一次執行su命令的動作:時間日期,成功與否,終端設備,用戶ID.有些UNIX具有單獨的su日志,
有些則保存在syslog中。
登陸用戶日志:utmp或wtmp文件保存了有關當前登陸到系統的用戶的信息。此文件根據各UNIX版本的不同,
名稱及存儲位置有所差異。保存的基本信息是用戶名,用於登陸的終端以及登陸的時間。文件以二進制格式存儲。
查詢utmp,wtmp文件應使用適當的客戶端,如w,who,finger,last.檢索成功,失敗與用戶名未知的登陸條目。
Cron日志記錄了定時作業的內容,通常在/var/log/cron或默認日志目錄中一個稱為cron的文件裡。
進程記賬,如果系統存在acct或pacct日志文件,則可使用lastcomm或acctcom命令查看。該日志為二進制文件。
Shell歷史記錄:
[root@ay4z3ro foo]# less ~/.bash_history
如果.bash_history被鏈接到/dev/null文件,或者環境變量中的$HISTFILE,$HISTFILESIZE兩個變量值為0,那麼肯定有人非法活動過了。
大多數入侵者都會修改或刪除日志,雖然理論上能夠做到除種植lkm rootkit之外幾乎不留任何痕跡,但在實際入侵中,
善後工作實際上是個不小的工程,不僅依賴入侵者對系統的熟知程度,而且當處理過多繁瑣的內容時,疏忽很容易出現。比如:剛得到
rootshell時unset HISTFILESIZE,退出時忘了復原,留下一條痕跡。諸如此類的例子還有很多,日志清除工具是死的,它只會清除預定義的
項目,雖然你也能修改源碼,但那樣還是不能隨機應變。最保險的方法就是手工勞動,這樣就加大了入侵者的負擔。出於懶惰,
對系統掌握程度不夠或是各種各樣的原因往往還是會留下一些對我們有價值的東西。所以,檢查日志對應急響應來說非常重要。
==============
執行關鍵字搜索
==============
無論是對何種操作系統進行應急響應,關鍵字搜索都是該過程的一部分。針對某個具體事件,可能會有一些ID,phrase與此事件密切相關,
執行關鍵字搜索可以找到更多的信息。關鍵字可以是很長的ASCII字符串,包括攻擊者後門密碼,用戶名,MAC地址或IP.
例:搜索整個文件系統中包含”ay4z3ro”字符串大小寫形式的所有文件:
[root@ay4z3ro foo]# grep –r –i ay4z3ro /
strings命令用於顯示文件中的可打印字符,例如:srings /bin/login用於顯示login後門中的密碼(未加密的明文,編碼或加密後的散列)。
Find命令用於尋找匹配常規表達式的任何文件名。例:
在整個文件系統中搜索名為”…”的文件或目錄:
[root@ay4z3ro foo]# find / -name “\.\.\.” –print
此外find命令可以匹配的特征還包括:修改訪問時間,文件所有者,文件內的字符串,文件名的字符串等。
Find命令的-exec選項與grep,strings結合使用體現了unix的天才氣質,那樣干起活來非常方便。
================
確定突發事件時間
================
*如果有IDS,確保IDS系統時間與受害系統時間一致。
*檢索系統中突發事件前後創建和被改動的文件,可能會有驚喜地發現。
======================
恢復被刪除的文件和數據
======================
這個過程需要操作者對unix/linux文件系統的體系結構有所了解,這裡並不打算去介紹文件系統的數據結構及其代碼的實現,
而是簡單的說明一下,刪除一個文件其實只是將inode節點的部分數據和指針置0,在下次數據覆蓋以前並沒有將節點指向的
數據塊的內容刪除。要想恢復刪除的文件,需要使用inode節點的信息重建文件大小和數據塊列表。
找到文件節點信息:
[root@ay4z3ro foo]# ls –i /tmp/x.d
82241 /tmp/x.d
表明/tmp/x.d位於82241節點。
TCT(The Coroner’s Toolkit)是一個非常有用的工具包,其中的icat可以查看指定節點上文件的全部內容。
[root@ay4z3ro TCT]# ./icat /dev/hda5 82241
如果程序還在運行,可以使用lsof命令引用NODE欄查找節點信息。
恢復一個文件只需要:
[root@ay4z3ro TCT]# ./icat /dev/hda5 NODE >; some.recovery
TCT中還有很多有用的工具,例:
[root@ay4z3ro TCT]# ./ils –A /dev/hda5 | grep “|501|”
以上命令行找出與UID=501用戶有關的所有被刪除的文件。
============
檢查特殊文件
============
SUID和SGID文件:
---------------
[root@ay4z3ro /]# find / -type f ( -perm -04000 -o -perm -02000 ) -exec ls -lg {}
從中查找那些原本不含有S位的,不尋常的或是被放在一個奇怪地方的S位程序。把/bin/ksh改名後放在/tmp(777)目錄下就是一種後門。
不常用的和隱藏的文件及目錄:
---------------------------
UNIX系統中以”.”開頭的文件都是隱藏的,如果ls不加”-a”參數就不會出現在文件列表裡,攻擊者經常利用的還有:”…”。
用隱藏字符對目錄進行重命名是一種黑客技巧,比如有的文件名是這樣的:”..^T”,”… “(注意三個點後面有個空格)……
這可以欺騙很多系統管理員。
怎麼辦呢?如下:
[root@ay4z3ro foo]# ls –al “| cat –tve”
cat命令的參數讓其顯示非打印字符,顯示制表符並在每個結尾放置一個$,所以以上目錄會顯示為:”..^T$”,”… $”。
要進入前一個目錄在T之前按下CTRL+V,而不是用^符號,進入後一個目錄則是:[root@ay4z3ro foo]# cd “… “
配置文件:
---------
一個攻擊者如果擁有相當熟練的系統管理技能,偷梁換柱,在配置文件中做點手腳是很輕而易舉的事。
添加一句偽造ingreslock服務把/bin/sh綁定在1524端口。水平差的攻擊者通常不會注意這個問題。
啟動文件:
----------
該目錄中的文件以用戶帳號命名,並且其中的任務以該用戶特權運行。此目錄下的root文件應該是我們關注的。
有人喜歡在半夜啟動木馬運行一個bindshell,然後過幾個小時又把開放的端口關閉。
/etc/rc*是開機自動運行腳本,也經常被攻擊者利用。
的事件中就曾被利用過。
/tmp目錄:
-------------
/tmp目錄的權限默認是777,這是攻擊者經常利用的地方,很多黑客工具也利用此目錄存儲中間文件,如果攻擊者不小心,
就會在此留下尾巴。
================
檢查用戶帳號和組
================
有些賬號是為系統而設,本來沒有shell,也不能登陸,攻擊者可能會利用這點。剛學習UNIX入侵沒多久的人可能會這樣:
echo “aya:0:0:intruder!!:/:/bin/sh”>;>;/etc/passwd,更有可憐的家伙因為少了一個”>;”而破壞了passwd文件,
弄得自己都無法登陸?,真見過這樣的家伙,說實話我自己也干過,不過是發生在自己的Linux上,所以沒有鑄成大錯。
老練的不會這樣做,他們可能會從一堆用戶中挑出一個不起眼的,然後占為己有,遠程合法登錄取得shell後本地再升級為root.
我相信這個問題對我們來說很好解決。
============
識別非法進程
============
但是那個進程的二進制文件可能是被替換過的,所以先要確保正在運行的不是rootkit(lrk4,lrk5……)
[root@ay4z3ro tool]# ./chkrootkit
chkrootkit是一個用於檢查完整性的工具,如果之前用過tripwire,則可以用tripwire校驗。
或者用rpm自身的MD5校驗和功能。
============
勘查系統弱點
============
檢查各服務,應用程序,內核及補丁的版本,對照bugtraq上已知的漏洞列表,查找系統弱點,從正面挖掘潛在的和可能被忽略漏洞。
這要求響應人員具有一個職業入侵者的相關技能!試圖扮演一個入侵者也能從中發掘對方是如何進入系統的。
============
分析信任關系
============
首先UNIX中的信任關系一度成為被攻擊的弱點。其次,如果該關系被利用,那麼受害范圍將擴大,
此時受信任的系統也被認為是不安全的,並將其同時列入響應對象的范圍。
============
分析黑客工具
============
如果很有幸的,入侵者留下了或者是我們用某種聰明的辦法恢復了入侵者在活動過程中使用的工具,代碼,就可以對其進一步分析。
如果是源代碼,直接拿過來就能讀(當然是LKM RootKit的源碼最好,呵呵)。不熟練的家伙甚至把原來的工具比如sniffit名字都不
改就運行了,這樣的就比較好對付。
如果我們得到的是一個正在運行進程的二進制文件的副本,可以使用gdb等調試器反匯編,跟蹤調試。
但是如果一個極具水准的攻擊者這樣編譯他的程序:
[root@ay4z3ro evil]# gcc –O4 evil.c –o evil
用-O4參數優化編譯後會減少指令,然後用strip去掉二進制文件中的符號信息:
[root@ay4z3ro evil]# strip ./evil
這樣我們的工作就會變得非常困難。
File命令可以顯示文件的類型信息,是否被strip過等。
Strings命令可以用來顯示可執行文件中的ASCII字符串,比如一個本地緩沖區溢出exploit中由printf()語句控制的行,出錯處理的消息,
默認的-h參數的返回信息等。此外還有可能得到函數,變量名,編譯之前所用的文件名,創建該文件的編譯器版本等,通過這些關鍵字進行
在線搜索就有可能找到該工具的源碼。
同樣我們可以對二進制文件進行動態分析,用strace工具跟蹤系統調用。strace顯示了文件執行時所產生的文件訪問,網絡訪問,
內存訪問和許多其它的系統調用信息。通常通過觀察關鍵的系統調用我們大致能確定該程序作了什麼。由此重構該文件的運行情景也是可能
的。strace給我們提供了極大的方便,在整個響應過程中,我們還可以利用它做很多事情。
{{後話}}
應急響應並不需要完全遵循固定的模式,思路新穎可以適度發揮,如果遇到的對手是水平極高的攻擊者,應該適當改變策略,
為了安全起見,最後重裝系統或許也是必要的。
寫給廣大“搞機器一族”的話:
縱使有人覺得自己入侵技巧高明,但事實上防御的一方總是或多或少的有些出乎你意料之外的對策,一點小馬虎可能就會使你很難堪。
即使你認為已經清除了目標系統上所有的日志,但是前端路由器或IDS,Firewall上可能有你無法“處理”甚至你未曾察覺到的跟蹤記錄,
為了自身的安全,找一條快速的線路,用多重跳板來發動一次真正的攻擊是很有必要的。從“開始”到“結束”都不能暴露自己!