本文发表在 rolia.net 枫下论坛用假IP欺騙對方的原理
IP欺騙的技術比較複雜,不是簡單地照貓畫老虎就能掌握,但作爲常規攻擊手段,有必要理解其原理,至少有利於自己的安全防範,易守難攻嘛。
假設B上的客戶運行rlogin與A上的rlogind通信:
1. B發送帶有SYN標誌的資料段通知A需要建立TCP連接。並將TCP報頭中的sequence number設置成自己本次連接的初始值ISN。
2. A回傳給B一個帶有SYS+ACK標誌的資料段,告之自己的ISN,並確認B發送來的第一個資料段,將acknowledge number設置成B的ISN+1。
3. B確認收到的A的資料段,將acknowledge number設置成A的ISN+1。
B ---- SYN ----> A
B <---- SYN+ACK ---- A
B ---- ACK ----> A
TCP使用的sequence number是一個32位的計數器,從0-4294967295。 TCP爲每一個連接選擇一個初始序號ISN,爲了防止因爲延遲、重傳等擾亂三次握手,ISN不能隨便選取,不同系統有不同演算法。理解TCP如何分配ISN以及ISN隨時間變化的規律,對於成功地進行IP欺騙攻擊很重要。
基於遠端程序呼叫RPC的命令,比如rlogin、rcp、rsh等等,根據/etc/hosts.equiv以及$HOME/.rhosts文件進行安全校驗,其實質是僅僅根據信源IP地址進行用戶身份確認,以便允許或拒絕用戶RPC。關於上述兩個文件請man,不喜歡看英文就去Unix版看看我以前灌過的一瓢水。
IP欺騙攻擊的描述:
1. 假設Z企圖攻擊A,而A信任B,所謂信任指/etc/hosts.equiv和$HOME/.rhosts中有相關設置。注意,如何才能知道A信任B呢?沒有什麽確切的辦法。我的建議就是平時注意搜集蛛絲馬迹,厚積薄發。一次成功的攻擊其實主要不是因爲技術上的高明,而是因爲資訊搜集的廣泛翔實。動用了自以爲很有成就感的技術,卻不比人家酒桌上的巧妙提問,攻擊只以成功爲終極目標,不在乎手段。
2. 假設Z已經知道了被信任的B,應該想辦法使B的網路功能暫時癱瘓,以免對攻擊造成干擾。著名的SYN flood常常是一次IP欺騙攻擊的前奏。請看一個並發伺服器的框架:
int initsockid, newsockid;
if ((initsockid = socket(...)) < 0) {
error("can't create socket";
}
if (bind(initsockid, ...) < 0) {
error("bind error";
}
if (listen(initsockid, 5) < 0) {
error("listen error";
}
for (; {
newsockid = accept(initsockid, ...); /* 阻塞 */
if (newsockid < 0) {
error("accept error";
}
if (fork() == 0) { /* 子進程 */
close(initsockid);
do(newsockid); /* 處理客戶方請求 */
exit(0);
}
close(newsockid);
}
listen函數中第二個參數是5,意思是在initsockid上允許的最大連接請求數目。如果某個時刻initsockid上的連接請求數目已經達到5,後續到達initsockid的連接請求將被TCP丟棄。注意一旦連接通過三次握手建立完成,accept調用已經處理這個連接,則TCP連接請求佇列空出一個位置。所以這個5不是指initsockid上只能接受5個連接請求。SYN flood正是一種 Denial of Service,導致B的網路功能暫時中斷
Z向B發送多個帶有SYN標誌的資料段請求連接,注意將信源IP 位址換成一個不存在的主機X;B向子虛烏有的X發送SYN+ACK資料段,但沒有任何來自X的ACK出現。B的IP層會報告B的TCP層,X不可達,但B的TCP層對此不予理睬,認爲只是暫時的。於是B在這個initsockid上再也不能接收正常的連接請求。
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
......
X <---- SYN+ACK ---- B
X <---- SYN+ACK ---- B
X <---- SYN+ACK ---- B
X <---- SYN+ACK ---- B
X <---- SYN+ACK ---- B
......
作者認爲這樣就使得B網路功能暫時癱瘓,可我覺得好象不對頭。
因爲B雖然在initsockid上無法接收TCP連接請求,但可以在another initsockid上接收,這種SYN flood應該只對特定的服務(埠),不應該影響到全局。當然如果不斷地發送連接請求,就和用ping發洪水包一個道理,使得B的TCP/IP忙於處理負載增大。至於SYN flood,回頭有機會我單獨灌一瓢有關DoS的。如何使B的網路功能暫 碧被居 很多辦法,根據具體情況而定,不再贅述。
3. Z必須確定A當前的ISN。首先連向25埠(SMTP是沒有安全校驗機制的),與1中類似,不過這次需要記錄A的ISN,以及Z到A的大致的RTT(round trip time)。這個步驟要重復多次以便求出RTT的平均值。現在Z知道了A的ISN基值和增加規律(比如每秒增 加128000,每次連接增加64000),也知道了從Z到A需要RTT/2 的時間。必須立即進入攻擊,否則在這之間有其他主機與A連接, ISN將比預料的多出64000。
4. Z向A發送帶有SYN標誌的資料段請求連接,只是信源IP改成了B,注意是針對TCP513埠(rlogin)。A向B回送SYN+ACK資料段,B已經無法回應(憑什麽?按照作者在2中所說,估計還達不到這個效果,因爲Z必然要模仿B發起connect調用,connect調用會完成全相關,自動指定本地socket地址和埠,可事實上B很可能並沒有這樣一個埠等待接收資料。除非Z模仿B發起連接請求時打破常規,主動在用戶端調用bind函數,明確完成全相關,這樣必然知道A會向B的某個埠回送,在2中也針對這個埠攻擊B。可是如果這樣,完全不用攻擊B,bind的時候指定一個B上根本不存在的埠即可。我也是想了又想,還沒來得及看看老外的源代碼,不妥之處有待商榷。總之,覺得作者好象在蒙我們,他自己也沒有實踐成功過吧。),B的TCP層只是簡單地丟棄A的回送資料段。
5. Z暫停一小會兒,讓A有足夠時間發送SYN+ACK,因爲Z看不到這個包。然後Z再次僞裝成B向A發送ACK,此時發送的資料段帶有Z預測的A的ISN+1。如果預測準確,連接建立,資料傳送開始。問題在於即使連接建立,A仍然會向B發送資料,而不是Z,Z 仍然無法看到A發往B的資料段,Z必須蒙著頭按照rlogin協定標準假冒B向A發送類似 "cat + + >> ~/.rhosts" 這樣的命令,於是攻擊完成。如果預測不準確,A將發送一個帶有RST標誌的資料段異常終止連接,Z只有從頭再來。
Z(B) ---- SYN ----> A
B <---- SYN+ACK ---- A
Z(B) ---- ACK ----> A
Z(B) ---- PSH ----> A
......
6. IP欺騙攻擊利用了RPC伺服器僅僅依賴於信源IP位址進行安全校驗的特性,建議閱讀rlogind的源代碼。攻擊最困難的地方在於預測A的ISN。作者認爲攻擊難度雖然大,但成功的可能性也很大,不是很理解,似乎有點矛盾。考慮這種情況,入侵者控制了一台由A到B之間的路由器,假設Z就是這台路由器,那麽A回送到B的資料段,現在Z是可以看到的,顯然攻擊難度驟然下降了許多。否則Z必須精確地預見可能從A發往B的資訊,以及A期待來自B的什麽應答資訊,這要求攻擊者對協定本身相當熟悉。同時需要明白,這種攻擊根本不可能在交互狀態下完成,必須寫程式完成。當然在準備階段可以用netxray之類的工具進行協定分析。
7. 如果Z不是路由器,能否考慮組合使用ICMP重定向以及ARP欺騙等技術?沒有仔細分析過,只是隨便猜測而已。並且與A、B、
Z之間具體的網路拓撲有密切關係,在某些情況下顯然大幅度降低了攻擊難度。注意IP欺騙攻擊理論上是從廣域網上發起的,不局限於局域網,這也正是這種攻擊的魅力所在。利用IP欺騙攻擊得到一個A上的shell,對於許多高級入侵者,得到目標主機的shell,離root許可權就不遠了,最容易想到的當然是接下來進行buffer overflow攻擊。
8. 也許有人要問,爲什麽Z不能直接把自己的IP設置成B的?這個問題很不好回答,要具體分析網路拓撲,當然也存在ARP衝突、出不了閘道等問題。那麽在IP欺騙攻擊過程中是否存在ARP衝突問題。回想我前面貼過的ARP欺騙攻擊,如果B的ARP Cache沒有受到影響,就不會出現ARP衝突。如果Z向A發送資料段時,企圖解析A的MAC地址或者路由器的MAC地址,必然會發送ARP請求包,但這個ARP請求包中源IP以及源MAC都是Z的,自然不會引起ARP衝突。而ARP Cache只會被ARP包改變,不受IP包的影響,所以可以肯定地說,IP欺騙攻擊過程中不存在ARP衝突。相反,如果Z修改了自己的IP,這種ARP衝突就有可能出現,示具體情況而言。攻擊中連帶B一起攻擊了,其目的無非是防止B干擾了攻擊過程, 如果B本身已經down掉,那是再好不過(是嗎?)。
9. fakeip曾經沸沸揚揚了一下,我對之進行埠掃描,發現其tcp埠113是接收入連接的。和IP欺騙等沒有直接聯繫,和安全校驗是有關係的。當然,這個東西並不如其名所暗示,對IP層沒有任何動作。
10. 關於預測ISN,我想到另一個問題。就是如何以第三方身份切斷 A與B之間的TCP連接,實際上也是預測sequence number的問題。嘗試過,也很困難。如果Z是A與B之間的路由器,就不用說了; 或者Z動用了別的技術可以監聽到A與B之間的通信,也容易些; 否則預測太難。作者在3中提到連接A的25埠,可我想不明白的 是513埠的ISN和25埠有什麽關係?看來需要看看TCP/IP內部實現的源代碼。
未雨綢繆
雖然IP欺騙攻擊有著相當難度,但我們應該清醒地意識到,這種攻擊非常廣泛,入侵往往由這裏開始。預防這種攻擊還是比較容易的, 比如刪除所有的/etc/hosts.equiv、$HOME/.rhosts文件,修改/etc/ inetd.conf文件,使得RPC機制無法運做,還可以殺掉portmapper等等。設置路由器,過濾來自外部而信源地址卻是內部IP的報文。cisio公司的産品就有這種功能。不過路由器只防得了外部入侵,內部入侵呢?
TCP的ISN選擇不是隨機的,增加也不是隨機的,這使攻擊者有規可循,可以修改與ISN相關的代碼,選擇好的演算法,使得攻擊者難以找到規律。估計Linux下容易做到,那solaris、irix、hp-unix還有aix呢?sigh
雖然作者紙上談兵,但總算讓我們瞭解了一下IP欺騙攻擊,我實驗過預測sequence number,不是ISN,企圖切斷一個TCP連接,感覺難度很大。作者建議要找到規律,不要盲目預測,這需要時間和耐心。現在越發明白什麽是那種鍥而不捨永遠追求的精神,我們所向往的傳奇故事背後有著如此沈默的艱辛和毅力,但願我們學會的是這個,而不是浮華與喧囂。一個現成的bug足以讓你取得root許可權,可你在做什麽,你是否明白?我們太膚淺了......更多精彩文章及讨论,请光临枫下论坛 rolia.net
IP欺騙的技術比較複雜,不是簡單地照貓畫老虎就能掌握,但作爲常規攻擊手段,有必要理解其原理,至少有利於自己的安全防範,易守難攻嘛。
假設B上的客戶運行rlogin與A上的rlogind通信:
1. B發送帶有SYN標誌的資料段通知A需要建立TCP連接。並將TCP報頭中的sequence number設置成自己本次連接的初始值ISN。
2. A回傳給B一個帶有SYS+ACK標誌的資料段,告之自己的ISN,並確認B發送來的第一個資料段,將acknowledge number設置成B的ISN+1。
3. B確認收到的A的資料段,將acknowledge number設置成A的ISN+1。
B ---- SYN ----> A
B <---- SYN+ACK ---- A
B ---- ACK ----> A
TCP使用的sequence number是一個32位的計數器,從0-4294967295。 TCP爲每一個連接選擇一個初始序號ISN,爲了防止因爲延遲、重傳等擾亂三次握手,ISN不能隨便選取,不同系統有不同演算法。理解TCP如何分配ISN以及ISN隨時間變化的規律,對於成功地進行IP欺騙攻擊很重要。
基於遠端程序呼叫RPC的命令,比如rlogin、rcp、rsh等等,根據/etc/hosts.equiv以及$HOME/.rhosts文件進行安全校驗,其實質是僅僅根據信源IP地址進行用戶身份確認,以便允許或拒絕用戶RPC。關於上述兩個文件請man,不喜歡看英文就去Unix版看看我以前灌過的一瓢水。
IP欺騙攻擊的描述:
1. 假設Z企圖攻擊A,而A信任B,所謂信任指/etc/hosts.equiv和$HOME/.rhosts中有相關設置。注意,如何才能知道A信任B呢?沒有什麽確切的辦法。我的建議就是平時注意搜集蛛絲馬迹,厚積薄發。一次成功的攻擊其實主要不是因爲技術上的高明,而是因爲資訊搜集的廣泛翔實。動用了自以爲很有成就感的技術,卻不比人家酒桌上的巧妙提問,攻擊只以成功爲終極目標,不在乎手段。
2. 假設Z已經知道了被信任的B,應該想辦法使B的網路功能暫時癱瘓,以免對攻擊造成干擾。著名的SYN flood常常是一次IP欺騙攻擊的前奏。請看一個並發伺服器的框架:
int initsockid, newsockid;
if ((initsockid = socket(...)) < 0) {
error("can't create socket";
}
if (bind(initsockid, ...) < 0) {
error("bind error";
}
if (listen(initsockid, 5) < 0) {
error("listen error";
}
for (; {
newsockid = accept(initsockid, ...); /* 阻塞 */
if (newsockid < 0) {
error("accept error";
}
if (fork() == 0) { /* 子進程 */
close(initsockid);
do(newsockid); /* 處理客戶方請求 */
exit(0);
}
close(newsockid);
}
listen函數中第二個參數是5,意思是在initsockid上允許的最大連接請求數目。如果某個時刻initsockid上的連接請求數目已經達到5,後續到達initsockid的連接請求將被TCP丟棄。注意一旦連接通過三次握手建立完成,accept調用已經處理這個連接,則TCP連接請求佇列空出一個位置。所以這個5不是指initsockid上只能接受5個連接請求。SYN flood正是一種 Denial of Service,導致B的網路功能暫時中斷
Z向B發送多個帶有SYN標誌的資料段請求連接,注意將信源IP 位址換成一個不存在的主機X;B向子虛烏有的X發送SYN+ACK資料段,但沒有任何來自X的ACK出現。B的IP層會報告B的TCP層,X不可達,但B的TCP層對此不予理睬,認爲只是暫時的。於是B在這個initsockid上再也不能接收正常的連接請求。
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
Z(X) ---- SYN ----> B
......
X <---- SYN+ACK ---- B
X <---- SYN+ACK ---- B
X <---- SYN+ACK ---- B
X <---- SYN+ACK ---- B
X <---- SYN+ACK ---- B
......
作者認爲這樣就使得B網路功能暫時癱瘓,可我覺得好象不對頭。
因爲B雖然在initsockid上無法接收TCP連接請求,但可以在another initsockid上接收,這種SYN flood應該只對特定的服務(埠),不應該影響到全局。當然如果不斷地發送連接請求,就和用ping發洪水包一個道理,使得B的TCP/IP忙於處理負載增大。至於SYN flood,回頭有機會我單獨灌一瓢有關DoS的。如何使B的網路功能暫 碧被居 很多辦法,根據具體情況而定,不再贅述。
3. Z必須確定A當前的ISN。首先連向25埠(SMTP是沒有安全校驗機制的),與1中類似,不過這次需要記錄A的ISN,以及Z到A的大致的RTT(round trip time)。這個步驟要重復多次以便求出RTT的平均值。現在Z知道了A的ISN基值和增加規律(比如每秒增 加128000,每次連接增加64000),也知道了從Z到A需要RTT/2 的時間。必須立即進入攻擊,否則在這之間有其他主機與A連接, ISN將比預料的多出64000。
4. Z向A發送帶有SYN標誌的資料段請求連接,只是信源IP改成了B,注意是針對TCP513埠(rlogin)。A向B回送SYN+ACK資料段,B已經無法回應(憑什麽?按照作者在2中所說,估計還達不到這個效果,因爲Z必然要模仿B發起connect調用,connect調用會完成全相關,自動指定本地socket地址和埠,可事實上B很可能並沒有這樣一個埠等待接收資料。除非Z模仿B發起連接請求時打破常規,主動在用戶端調用bind函數,明確完成全相關,這樣必然知道A會向B的某個埠回送,在2中也針對這個埠攻擊B。可是如果這樣,完全不用攻擊B,bind的時候指定一個B上根本不存在的埠即可。我也是想了又想,還沒來得及看看老外的源代碼,不妥之處有待商榷。總之,覺得作者好象在蒙我們,他自己也沒有實踐成功過吧。),B的TCP層只是簡單地丟棄A的回送資料段。
5. Z暫停一小會兒,讓A有足夠時間發送SYN+ACK,因爲Z看不到這個包。然後Z再次僞裝成B向A發送ACK,此時發送的資料段帶有Z預測的A的ISN+1。如果預測準確,連接建立,資料傳送開始。問題在於即使連接建立,A仍然會向B發送資料,而不是Z,Z 仍然無法看到A發往B的資料段,Z必須蒙著頭按照rlogin協定標準假冒B向A發送類似 "cat + + >> ~/.rhosts" 這樣的命令,於是攻擊完成。如果預測不準確,A將發送一個帶有RST標誌的資料段異常終止連接,Z只有從頭再來。
Z(B) ---- SYN ----> A
B <---- SYN+ACK ---- A
Z(B) ---- ACK ----> A
Z(B) ---- PSH ----> A
......
6. IP欺騙攻擊利用了RPC伺服器僅僅依賴於信源IP位址進行安全校驗的特性,建議閱讀rlogind的源代碼。攻擊最困難的地方在於預測A的ISN。作者認爲攻擊難度雖然大,但成功的可能性也很大,不是很理解,似乎有點矛盾。考慮這種情況,入侵者控制了一台由A到B之間的路由器,假設Z就是這台路由器,那麽A回送到B的資料段,現在Z是可以看到的,顯然攻擊難度驟然下降了許多。否則Z必須精確地預見可能從A發往B的資訊,以及A期待來自B的什麽應答資訊,這要求攻擊者對協定本身相當熟悉。同時需要明白,這種攻擊根本不可能在交互狀態下完成,必須寫程式完成。當然在準備階段可以用netxray之類的工具進行協定分析。
7. 如果Z不是路由器,能否考慮組合使用ICMP重定向以及ARP欺騙等技術?沒有仔細分析過,只是隨便猜測而已。並且與A、B、
Z之間具體的網路拓撲有密切關係,在某些情況下顯然大幅度降低了攻擊難度。注意IP欺騙攻擊理論上是從廣域網上發起的,不局限於局域網,這也正是這種攻擊的魅力所在。利用IP欺騙攻擊得到一個A上的shell,對於許多高級入侵者,得到目標主機的shell,離root許可權就不遠了,最容易想到的當然是接下來進行buffer overflow攻擊。
8. 也許有人要問,爲什麽Z不能直接把自己的IP設置成B的?這個問題很不好回答,要具體分析網路拓撲,當然也存在ARP衝突、出不了閘道等問題。那麽在IP欺騙攻擊過程中是否存在ARP衝突問題。回想我前面貼過的ARP欺騙攻擊,如果B的ARP Cache沒有受到影響,就不會出現ARP衝突。如果Z向A發送資料段時,企圖解析A的MAC地址或者路由器的MAC地址,必然會發送ARP請求包,但這個ARP請求包中源IP以及源MAC都是Z的,自然不會引起ARP衝突。而ARP Cache只會被ARP包改變,不受IP包的影響,所以可以肯定地說,IP欺騙攻擊過程中不存在ARP衝突。相反,如果Z修改了自己的IP,這種ARP衝突就有可能出現,示具體情況而言。攻擊中連帶B一起攻擊了,其目的無非是防止B干擾了攻擊過程, 如果B本身已經down掉,那是再好不過(是嗎?)。
9. fakeip曾經沸沸揚揚了一下,我對之進行埠掃描,發現其tcp埠113是接收入連接的。和IP欺騙等沒有直接聯繫,和安全校驗是有關係的。當然,這個東西並不如其名所暗示,對IP層沒有任何動作。
10. 關於預測ISN,我想到另一個問題。就是如何以第三方身份切斷 A與B之間的TCP連接,實際上也是預測sequence number的問題。嘗試過,也很困難。如果Z是A與B之間的路由器,就不用說了; 或者Z動用了別的技術可以監聽到A與B之間的通信,也容易些; 否則預測太難。作者在3中提到連接A的25埠,可我想不明白的 是513埠的ISN和25埠有什麽關係?看來需要看看TCP/IP內部實現的源代碼。
未雨綢繆
雖然IP欺騙攻擊有著相當難度,但我們應該清醒地意識到,這種攻擊非常廣泛,入侵往往由這裏開始。預防這種攻擊還是比較容易的, 比如刪除所有的/etc/hosts.equiv、$HOME/.rhosts文件,修改/etc/ inetd.conf文件,使得RPC機制無法運做,還可以殺掉portmapper等等。設置路由器,過濾來自外部而信源地址卻是內部IP的報文。cisio公司的産品就有這種功能。不過路由器只防得了外部入侵,內部入侵呢?
TCP的ISN選擇不是隨機的,增加也不是隨機的,這使攻擊者有規可循,可以修改與ISN相關的代碼,選擇好的演算法,使得攻擊者難以找到規律。估計Linux下容易做到,那solaris、irix、hp-unix還有aix呢?sigh
雖然作者紙上談兵,但總算讓我們瞭解了一下IP欺騙攻擊,我實驗過預測sequence number,不是ISN,企圖切斷一個TCP連接,感覺難度很大。作者建議要找到規律,不要盲目預測,這需要時間和耐心。現在越發明白什麽是那種鍥而不捨永遠追求的精神,我們所向往的傳奇故事背後有著如此沈默的艱辛和毅力,但願我們學會的是這個,而不是浮華與喧囂。一個現成的bug足以讓你取得root許可權,可你在做什麽,你是否明白?我們太膚淺了......更多精彩文章及讨论,请光临枫下论坛 rolia.net