By Fyodor ()
backend
摘要
本文主要討論如何通過探測遠程主機的TCP/IP堆棧來收集寶貴的主機系統。首先講述幾種沒有包括堆棧探測技術的“傳統”的主機操作系統掃描方法。接著是現在較為常見的堆棧特征掃描工具的基本原理。然后討論一些能使遠程主機“在不知不覺間”泄露其信息的技術。最后主要是nmap掃描工具的一些實現細節。
動機
我想誰都已經非常清楚知道遠程主機操作系統有多么重要,因此這里只是作一簡單敘述。首先最有用的一點在于絕大多數安全漏洞都是針對特定操作系統的。例如你在作端口掃描時發現端口53打開了,而且其守護服務器是有安全漏洞的BIND版本,這時你只要找到相應的漏洞攻擊程序就可輕而易舉地使守護進程崩潰。依靠優秀的TCP/IP特征探測器,你可以很快知道主機是運行Solaris 2.5.1還是Linux 2.0.35,然后使用相應的漏洞程序和shellcode代碼。
這個工具也可能被不正當地使用。有些人喜歡一次對多臺機器(例如50000臺)進行操作系統和端口掃描,例如如果Sun comsat守護服務器的一個安全漏洞被公布了,他們就會特意地去尋找‘Solaris 2.6操作系統和UDP/512端口,然后不厭其煩地去攻擊這些機器。我們通常將這種人稱為"SCRIPT KIDDIE"(注:就象是只會抄襲別人的小孩)。這種人并沒有什么技術,也不能說明他能夠發現漏洞或修補漏洞。而對于那些即使自己發現了漏洞,但卻只會通過攻擊他人網頁來企圖證明自己如何出色而系統管理員如何愚蠢的人,人們更會嗤之以鼻。
我們稱之為“社交工程(social engineering)”也是另一種可能的不正當用途。例如當駭客掃描到目標公司網絡時nmap報告發現了一臺Datavoice TxPORT PRISM 3000 T1 CSU/DSU 6.22/2.06‘,他就會以“Datavoice技術支持”的身份給這間公司打電話:“我們正準備公布一個安全漏洞,但我們希望在此之前為我們的客戶安裝補丁程序。這個補丁程序我剛剛給您寄出去?!蹦承┨煺娴墓芾韱T會真的以為只有真正來自Datavoice公司的技術工程師才知道那么多關于他們的CSU/DSU設備的資料,從而……
另一個可能的用途是評價你準備有合作的公司。當在選擇一個新的ISP時,掃描一下該網絡看看在使用設備。如果是一大堆的低檔路由器和用Windows機器提供PPP服務,那即使是"¥99/年"的價格你也會覺得不值。:)
傳統技術
利用堆棧特征探測操作系統是一種獨特的方法。我想它會滿足大多數的要求,雖然目前也還流行有其它方法。不過下面這種方法可能仍然是迄今為止最有效的:
playground~> telnet hpux.u-aizu.ac.jp
Trying 163.143.103.12...
Connected to hpux.u-aizu.ac.jp.
Escape character is ^].
HP-UX hpux B.10.01 A 9000/715 (ttyp2)
login:
如此公開地宣布本機運行的是什么系統根本就是一種商業炒作!現在的大多數系統都還帶有這種banner,而管理員們也沒有意識到應該去掉它們。雖然是存在許多探測主機操作系統的方法,但這絕對不能成為為公開主機操作系統這種愚蠢行為辯護的理由。
隨著這個問題的嚴重性被廣泛意識到,越來越多的人已經開始將banner去掉,許多系統的banner也不再泄露重要的信息,這種通過查找banner獲得操作系統類型和版本的方法會遇到許多困難,變得不那么可行了。但是,至少目前版本的昂貴商業掃描器(如ISS)仍然只使用這種古老的方法來試圖獲取主機操作系統類型和版本。相比之下,下載nmap和queso會節約你大量的金錢。:)
即使關閉了banner,許多應用程序卻仍然樂于向訪問者提供這類信息。例如,當登錄到某臺FTP服務器時:
payfonez> telnet 21
Trying 207.200.74.26...
Connected to .
Escape character is ^].
220 ftp29 FTP server (UNIX(r) System V Release 4.0) ready.
SYST
215 UNIX Type: L8 Version: SUNOS
首先,它在缺省的banner里告訴你系統的信息。然后當輸入SYST命令時,它會更樂意地向你提供更多的信息。
如果支持匿名FTP,我們可以下載/bin/ls或其它二進制文件來(至少)確定主機的硬件平臺。
其它許多應用程序也能提供類似信息。例如WEB服務器:
playground> echo GET / HTTP/1.0n | nc hotbot.com 80 | egrep ^Server:
Server: Microsoft-IIS/4.0
playground>
嗯。?!,F在我們知道這臺機器運行的是什么破操作系統了。:)
其它“傳統”的技術還包括DNS主機記錄(INFO)、社交工程(social engineering)和SNMP等。這里就不再多說了。
幾個操作系統特征探測程序
Nmap不是第一個使用TCP/IP堆棧特征探測操作系統類型的程序。Johan編寫的IRC欺騙器sirc從第三版(或更早)就已經包含了很基本的特征探測技術。這個程序使用了一些簡單的TCP標記位測試來區分"Linux"、"4.4BSD"、"Win95"或"Unknown"操作系統主機。
另一個類似的程序是checkos,由Shok編寫并于1998年1月在"Confidence Remains High Issue #7"上發表。它采用了與sirc完全相同的技術,甚至某些代碼也完全一致。其實checkos在公開發表前就已在私底下流傳了很久,因此我不知道是哪個程序抄襲了另一個程序。在傳播過程中,checkos增加了telnet banner檢查功能(雖然這是一項很老的技術)。據Shok說,checkos從來就沒打算公開,因此他并沒有考慮過版權問題。
Su1d也寫了一個操作系統檢測程序。程序名為SS,版本3.11能夠檢測12種不同操作系統類型。我這個程序使用了nmap的某些網絡代碼。
然后是queso。這個很新的程序比起以前的其它程序有了很大的飛躍。它不但增加了不少新的測試,還是第一個(我所知道的)將操作系統特征與代碼分離的程序。其它掃描程序的代碼與下面相似:
/* from ss */
if ((flagsfour & TH_RST) && (flagsfour & TH_ACK) && (winfour == 0) && (flagsthree & TH_ACK))
reportos(argv[2],argv[3],"Livingston Portmaster ComOS");
而queso將這些操作系統特征都單獨存放到一個配置文件中,這樣只需將新的操作系統特征添加到配置文件中即可,從而極大地增強了程序的可擴展性。
Queso由Apostols.org的Savage編寫。
以上談到的所有程序都存在一個問題,那就是仍然局限于依靠為數不多的測試和響應來確定系統類型。我們不但希望僅僅知道“這臺機器運行的是OpenBSD、FreeBSD或者NetBSD?!?,還想知道如具體版本和其它更多的信息。例如,Solaris 2.6比Solaris包含有更多的信息。為了能達到這種更高的探測要求,在nmap中使用了更多的操作系統特征技術。下面就讓我們一起討論吧。
特征探測方法
目前有許多的網絡堆棧特征探測技術。最簡單的就是尋找各種操作系統間的不同并寫出探測程序。當使用了足夠的不同特征時,操作系統的探測精度就有了很大保證。例如nmap能夠可靠地區分出Solaris 2.4、Solaris 2.5-2.5.1和Solaris 2.6,也能區分2.0.30、2.0.31-34或2.0.35版本的Linux內核。以下是一些這方面的技術:
FIN探測 -- 通過發送一個FIN數據包(或任何未設置ACK或SYN標記位的數據包)
到一個打開的端口,并等待回應。RFC793定義的標準行為是“不”響
應,但諸如MS Windows、BSDi、CISCO、HP/UX、MVS和IRIX等操作系
統會回應一個RESET包。大多數的探測器都使用了這項技術。
BOGUS(偽造)標記位探測 -- 據我所知,Queso是第一個使用這種更聰明技術的
探測器。它原理是在一個SYN數據包TCP頭中設置未定義的TCP“標記”
(64或128)。低于2.0.35版本的Linux內核會在回應包中保持這個
標記,而其它操作系統好象都沒有這個問題。不過,有些操作系統
當接收到一個SYN+BOGUS數據包時會復位連接。所以這種方法能夠比
較有效地識別出操作系統。
TCP ISN 取樣 -- 其原理是通過在操作系統對連接請求的回應中尋找TCP連接初
始化序列號的特征。目前可以區分的類別有傳統的64K(舊UNIX系統
使用)、隨機增加(新版本的Solaris、IRIX、FreeBSD、Digital
UNIX、Cray和其它許多系統使用)、真正“隨機”(Linux 2.0.*及更
高版本、OpenVMS和新版本的AIX等操作系統使用)等。Windows平臺
(還有其它一些平臺)使用“基于時間”方式產生的ISN會隨著時間的
變化而有著相對固定的增長。不必說,最容易受到攻擊的當然是老
式的64K方式。而最受我們喜愛的當然是“固定”ISN!確實有些機器
總是使用相同的ISN,如某些3Com集線器(使用0x83)和Apple
LaserWriter打印機(使用0xC7001)。
根據計算ISN的變化、最大公約數和其它一些有跡可循的規律,還可
以將這些類別分得更細、更準確。
“無碎片”標記位 -- 許多操作系統逐漸開始在它們發送的數據包中設置IP“不分
片(無碎片)”位。這對于提高傳輸性能有好處(雖然有時它很討厭
-- 這也是為什么nmap不對Solaris系統進行碎片探測的原因)。但
并不是所有操作系統都有這個設置,或許并不并總是使用這個設置,
因此通過留意這個標記位的設置可以收集到關于目標主機操作系統
的更多有用信息。
TCP 初始化“窗口” -- 就是檢查返回數據包的“窗口”大小。以前的探測器僅僅通
過RST數據包的非零“窗口”值來標識為“起源于BSD 4.4”。而象queso
和nmap這些新的探測器會記錄確切的窗口值,因為該窗口隨操作系
統類型有較為穩定的數值。這種探測能夠提供許多有用的信息,因
為某些系統總是使用比較特殊的窗口值(例如,據我所知AIX是唯一
使用0x3F25窗口值的操作系統)。而在聲稱“完全重寫”的NT5的TCP
堆棧中,Microsoft使用的窗口值總是0x402E。更有趣的是,這個數
值同時也被OpenBSD和FreeBSD使用。
ACK值 -- 也許你認為ACK值總是很標準的,但事實上操作系統在ACK域值的實
現也有所不同。例如,假設向一個關閉的TCP端口發送一個FIN|PSH|
URG包,許多操作系統會將ACK值設置為ISN值,但Windows和某些愚
蠢的打印機會設置為seq+1。如果向打開的端口發送SYN|FIN|URG|
PSH包,Windows的返回值就會非常不確定。有時是seq序列號值,有
時是S++,而有時回送的是一個似乎很隨機性的數值。我們很懷疑為
什么MS總是能寫出這種莫名其妙的代碼。
ICMP錯誤信息查詢 -- 有些(聰明的)操作系統根據RFC 1812的建議對某些類型
的錯誤信息發送頻率作了限制。例如,Linux內核(在net/ipv4/
icmp.h)限制發送“目標不可到達”信息次數為每4秒80次,如果超過
這個限制則會再減少1/4秒。一種測試方法是向高端隨機UDP端口發
送成批的數據包,并計算接收到的“目標不可到達”數據包的數量。
在nmap中只有UDP端口掃描使用了這個技術。這種探測操作系統方法
需要稍微長的時間,因為需要發送大量的數據包并等待它們的返回。
這種數據包處理方式也會對網絡性能造成某種程度的影響。
ICMP信息引用 -- RFC定義了一些ICMP錯誤信息格式。如對于一個端口不可到達
信息,幾乎所有操作系統都只回送IP請求頭+8字節長度的包,但
Solaris返回的包會稍微長一點,Linux則返回更長的包。這樣即使
操作系統沒有任何監聽任何端口,nmap仍然有可能確定Linux和
Solaris操作系統的主機。
ICMP錯誤信息回顯完整性 -- 我們在前面已談到,機器必須根據接收到的數據
包返回“端口不可到達”(如果確實是這樣)數據包。有些操作系統
會在初始化處理過程中弄亂了請求頭,這樣當你接收到這種數據包
時會出現不正常。例如,AIX和BSDI返回的IP包中的“總長度”域會
被設置為20字節(太長了)。某些BSDI、FreeBSD、OpenBSD、
ULTRIX和VAX操作系統甚至會修改請求頭中的IP ID值。另外,由于
TTL值的改變導致校驗和需要修改時,某些系統(如AIX、FreeBSD
等)返回數據包的檢驗和會不正確或為0。有時這種情況也出現在
UDP包檢驗和??偟恼f來,nmap使用了九種不同的ICMP錯誤信息探
測技術來區分不同的操作系統。
服務類型(TOS) -- 對于ICMP的“端口不可到達”信息,經過對返回包的服務類
型(TOS)值的檢查,幾乎所有的操作系統使用的是ICMP錯誤類型
0,而Linux使用的值是0xC0。
片段(碎片)處理 -- 不同操作系統在處理IP片段重疊時采用了不同的方式。
有些用新的內容覆蓋舊的內容,而又有些是以舊的內容為優先。有
很多探測方法能確定這些包是被如何重組的,從而能幫助確定操作
系統類型。
TCP選項 -- 這是收集信息的最有效方法之一。其原因是:
1)它們通常真的是“可選的”,因此并不是所有的操作系統都使用
它們。
2)向目標主機發送帶有可選項標記的數據包時,如果操作系統支
持這些選項,會在返回包中也設置這些標記。
3)可以一次在數據包中設置多個可選項,從而增加了探測的準確
度。
Nmap在幾乎每一個探測數據包中都設置了如下選項:
Window Scale=10; NOP; Max Segment Size = 265; Timestamp; End of Ops;
當接收到返回包時,檢查返回了哪些選項,它們就是目標操作系統
支持的選項。有些操作系統(如較新版本的FreeBSD)支持以上所
有選項,而有些(如Linux 2.0.x)則幾乎都不支持。Linux 2.1.x
內核支持以上所有選項。
如果有幾個操作系統支持相同的選項,可以通過選項的值來進行區
分。例如,如果向Linux機器發送一個很小的MSS值,它一般會將此
MSS值返回,而其它系統則會返回不同數值。
如果支持相同的選項,返回值也相同,又怎么辦呢?仍然可以通過
返回選項的順序進行區分。如Solaris系統返回‘NNTNWME’,代表:
而如果是Linux 2.1.122系統,相同的選項,相同的返回值,但順
序卻有所不同:MENNTNW。
目前還沒有其它操作系統探測工具利用TCP選項,但它確實非常有效!
另外還有其它一些選項也可用于進行探測,如T/TCP支持等。
譯者注:還有至少兩種頗具攻擊性的探測方法。由于它們能導致拒絕服務攻擊,而這也是在nmap中沒有實現這些方法的主要原因。
NMAP探測細節和結果
上面我們討論了操作系統類型探測的多種技術(除了某些攻擊性方法外)。這些技術都在nmap掃描器中實現。Nmap掃描器收集了眾多操作系統端口打開和關閉時的特征,支持目前流行的Linux、*BSD和Solaris 2.5.1/2.6多種操作系統。
目前版本的nmap掃描器從一個文件中讀取操作系統特征模板。下面是一個實例:
FingerPrint IRIX 6.2 - 6.4 # Thanks to Lamont Granquist
TSeq(Class=i800)
T1(DF=N%W=C000|EF2A%ACK=S++%Flags=AS%Ops=MNWNNT)
T2(Resp=Y%DF=N%W=0%ACK=S%Flags=AR%Ops=)
T3(Resp=Y%DF=N%W=C000|EF2A%ACK=O%Flags=A%Ops=NNT)
T4(DF=N%W=0%ACK=O%Flags=R%Ops=)
T5(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
T6(DF=N%W=0%ACK=O%Flags=R%Ops=)
T7(DF=N%W=0%ACK=S%Flags=AR%Ops=)
PU(DF=N%TOS=0%IPLEN=38%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)
讓我們來看一下每一行的含義:
> FingerPrint IRIX 6.2 - 6.3 # Thanks to Lamont Granquist
它說明這是一個IRIX 6.2 - 6.3操作系統特征,注釋指出該特征由Lamont Granquist提供。
> TSeq(Class=i800)
它說明ISN特征是"i800 class",即每一個新序列號比上一個序列號大800的整數倍。
> T1(DF=N%W=C000|EF2A%ACK=S++%Flags=AS%Ops=MNWNNT)
T1代表test1。這個測試是向打開的端口發送帶有多個TCP選項的SYN數據包。DF=N說明返回包的
"Don fragment"位必須沒有設置。W=C000|EF2A說明返回包的窗口值必須為0xC000或0xEF2A。ACK=S++說明返回包的ACK值必須為初始化序列號加1。Flags=AS說明返回包的ACK和SYN標記位必須被設置。Ops=MNWNNT說明返回包的TCP選項及其順序必須為:
> T2(Resp=Y%DF=N%W=0%ACK=S%Flags=AR%Ops=)
Test 2(第二個測試)向打開端口發送帶有相同TCP選項的NULL(空)數據包。Resp=Y說明必須接收到返回包。Ops= 說明返回包中的所有TCP選項必須都沒有被設置?!?Ops=’匹配任意TCP選項。
> T3(Resp=Y%DF=N%W=400%ACK=S++%Flags=AS%Ops=M)
Test 3(第三個測試)向打開端口發送帶有TCP選項的SYN|FIN|URG|PSH數據包。
> T4(DF=N%W=0%ACK=O%Flags=R%Ops=)
這是向打開端口發送ACK數據包。注意這里沒有Resp=字符串。說明返回包不是必須的(例如數據包被丟棄或有防火墻)。
> T5(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
> T6(DF=N%W=0%ACK=O%Flags=R%Ops=)
> T7(DF=N%W=0%ACK=S%Flags=AR%Ops=)
以上測試是針對關閉端口的SYN、ACK和FIN|PSH|URG數據包測試,并設置了相同的TCP選項。
> PU(DF=N%TOS=0%IPLEN=38%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)
這個是對“端口不可到達”信息的測試。DF=N前面已經介紹過了。TOS=0說明IP服務類型域應為0。接著的兩個是IP包頭總長度和返回IP包總長度(16進制值)。RID=E說明期望返回包RID值與發送的UDP包的值相同。RIPCK=E說明校驗和應該正常(如果不正常則RIPCK=F)。UCK說明UDP包校驗和也應該正常。ULEN=134是UDP包長度為0x134。DAT=E說明正確返回UDP數據,這個是大多數情況下的缺省設置。
一些較為著名站點的掃描結果
注:這些都是以前的掃描結果,僅供參考。不保證它現在仍然有效或準確。
# "Hacker" sites or (in a couple cases) sites that think they are
=> OpenBSD 2.2 - 2.4
=> Linux 2.0.31-34
=> Windows 95/NT # No comment:)
=> Linux 2.0.31-34
=> FreeBSD 2.2.6 - 3.0
=> OpenBSD 2.2 - 2.4
=> Linux 2.0.31-34 # Free Kevin!
=> FreeBSD 2.2.6 - 3.0 Beta
=> FreeBSD 2.2.6 - 3.0 Beta
=> Linux 2.0.35 # Changed to OpenBSD after
# they got owned.
# Security vendors, consultants, etc.
=> Linux 2.0.35
=> Linux 2.0.31-34
=> Solaris 2.5 - 2.51
=> Win95/NT
# Vendor loyalty to their OS
=> Linux 2.0.35 # Linux International
=> Linux 2.0.31-34 # I wonder what distribution:)
=> Linux 2.0.35
=> Linux 2.1.122 - 2.1.126
=> IRIX 6.2 - 6.4
=> NetBSD 1.3X
=> Solaris 2.6 # Ahem:)
=> FreeBSD 2.2.6-3.0 Beta
# Ivy league
=> Solaris 2.6
=> Solaris 2.5 - 2.51
=> SunOS 4.1.2-4.1.4 # Hello! This is the 90s:)
=> Solaris 2.6
=> Solaris 2.5 - 2.51 # Coincidence that so many good
# schools seem to like Sun?
# Perhaps it is the 40%
# .edu discount:)
=> UNIX OSF1 V 4.0,4.0B,4.0D
=> Linux 2.0.33-34 # Rock on!
# Lamer sites
=> IRIX 6.2 - 6.4 # No wonder they are so insecure:)
=> OpenBSD 2.2-2.4 # Sick of being owned, Carolyn?
# Even the most secure OS is
# useless in the hands of an
# incompetent admin.
# Misc
=> Linux 2.0.31-34 # This Linux news site rocks!
=> Linux 2.1.122 - 2.1.126
=> IRIX 5.3
sunsite.unc.edu => Solaris 2.6