根據IP獲取對方機器的作業系統方案
阿新 • • 發佈:2019-02-02
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包檢驗和。總的說來,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't 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資料包
到一個開啟的埠,並等待迴應。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包檢驗和。總的說來,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't 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資料包