中新網(wǎng)安安全實(shí)驗(yàn)室|HTTP請(qǐng)求走私漏洞及靶場(chǎng)復(fù)現(xiàn)
2019年8月,hackerone提交了關(guān)于PayPal HTTP請(qǐng)求走私+存儲(chǔ)性XSS (鏈接:https://hackerone.com/reports/510152) 攻擊可以直接對(duì)PayPal登陸頁面進(jìn)行控制,并且能獲取所有用戶密碼,危害極大。這是什么漏洞,我們今天來揭開它的面紗:HTTP請(qǐng)求走私(HTTP Request Smuggling) 
圖片來源: https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn 我們先了解下今年black hat上共享的Paypal漏洞實(shí)例(引用:https://i.blackhat.com/eu-19/Wednesday/eu-19-Kettle-HTTP-Desync-Attacks-Request-Smuggling-Reborn.pdf )代碼如下:首先使用請(qǐng)求走私污染PayPal登錄的JS文件。 由于PayPal登錄頁面有一個(gè)CSP規(guī)則腳本-SRC,阻止了這個(gè)重定向后來,作者登錄頁面在動(dòng)態(tài)生成的iframe中將c.payal.com上的子頁面加載了。此子頁面未使用CSP,還使用了由作者的JS文件!可以控制iframe頁面,但是由于同源策略,無法讀取父頁面的數(shù)據(jù)。然后,在paypal.com/us/gifts上發(fā)現(xiàn)了一個(gè)不使用CSP的頁面,并且還導(dǎo)入了污染JS文件。通過使用自己的JS將c.paypal.com iframe重定向到該URL(并第三次觸發(fā)自己的JS導(dǎo)入),他終于可以訪問父級(jí)并從使用Safari或IE PayPal登錄的每個(gè)人那里竊取純文本的PayPal密碼。看著是挺繞的,但是慢慢想一下很簡單,PayPal主站是有同源策略,旁站存在HTTP請(qǐng)求走私直接加載自己的JS,PayPal.com/us/gifts可以繞過主站可以加載自己的JS,然后成功竊取每個(gè)登陸PayPal賬號(hào)密碼。好,我們來了解下什么是HTTP走私。首先我們要了解下HTTP簡介和概念。
HTTP請(qǐng)求走私是一種干擾網(wǎng)站處理從一個(gè)或多個(gè)用戶接收的HTTP請(qǐng)求序列的方式的技術(shù),它可以繞過安全控制,未經(jīng)授權(quán)訪問敏感數(shù)據(jù)并且直接危害其他應(yīng)用程序用戶。
我們知道HTTP協(xié)議是Hyper Text Transfer Protocol(超文本傳輸協(xié)議)的縮寫,是用于從萬維網(wǎng)(WWW:World Wide Web)服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議,HTTP是一個(gè)基于TCP/IP通信協(xié)議來傳遞數(shù)據(jù)。
自HTTP/1.1開始,支持通過單個(gè)基礎(chǔ)TCP或者SSL/TLS套接字發(fā)送多個(gè)HTTP請(qǐng)求,該協(xié)議將HTTP請(qǐng)求背靠背放置,服務(wù)器解析標(biāo)頭以計(jì)算出每個(gè)結(jié)束的位置及下個(gè)開始位置。1. Persistent Connection(持久連接)HTTP運(yùn)行在TCP連接之上,存在TCP三次握手,慢啟動(dòng)等特點(diǎn),為了盡可能提高HTTP的性能,引用了長連接的概念,目的解決HTTP傳輸,多次建立連接信息的情況,通過Connection: keep-alive 頭部來實(shí)現(xiàn),服務(wù)器和客戶端使用它告訴對(duì)方在發(fā)送完數(shù)據(jù)之后不斷開TCP連接,那么問題來了,我們?cè)撊绾闻袛嘈畔⑹欠駛鬏斖瓿赡亍榱私鉀Q這個(gè)問題,于是引入下面的請(qǐng)求頭Content-length。2. Content-length(實(shí)體長度)Content-Length實(shí)體標(biāo)頭字段發(fā)送給接收方的實(shí)體的大小(以OCTET的十進(jìn)制數(shù)為單位)通過判斷Content-lenget長度相等,服務(wù)器便知道這個(gè)時(shí)候可以斷開連接,如果Content-length和實(shí)體的實(shí)際長度短會(huì)造成內(nèi)容截?cái)啵绻葘?shí)際內(nèi)容長,會(huì)為缺少的內(nèi)容進(jìn)行自動(dòng)填充,看似完美了,但是服務(wù)器為了計(jì)算信息內(nèi)容,將所有內(nèi)容緩存下載,并沒有解決web應(yīng)用優(yōu)化。3. Transfer-Encoding: chunked(分塊編碼)為了解決Web優(yōu)化,引入一個(gè)新的請(qǐng)求頭Transfer-Encoding: chunked 也就是分塊編碼,加入請(qǐng)求頭后,報(bào)文會(huì)使用分塊的形式進(jìn)行傳輸,不在需要緩存所有實(shí)例內(nèi)容,只需要緩存分塊即可,分塊要求,每塊必須包含16進(jìn)制的長度和數(shù)據(jù),長度值獨(dú)立占據(jù)一行,不包括CRLF(\r\n),也不包括結(jié)尾的CRLF,當(dāng)分塊的長度為0,且沒有數(shù)據(jù),連接結(jié)束大多數(shù)網(wǎng)站為了提高瀏覽速度,用戶體驗(yàn),減少服務(wù)器負(fù)擔(dān),使用CDN加速服務(wù),原理就是在源站前面加入具有緩存功能的反向代理,當(dāng)用戶請(qǐng)求靜態(tài)資源,可以直接到代理服務(wù)器中獲取,不在從源站服務(wù)器獲取,反向代理與后端源站服務(wù)器之間,會(huì)重用TCP鏈接,因?yàn)椴煌挠脩粽?qǐng)求將通過代理服務(wù)器與源站服務(wù)器連接,代理服務(wù)器與后端的源站服務(wù)器的IP是相對(duì)固定。但是由于兩者服務(wù)器的實(shí)現(xiàn)方法不同,如果用戶提供模糊的請(qǐng)求可能代理服務(wù)器認(rèn)為是一個(gè)HTTP請(qǐng)求,然后轉(zhuǎn)發(fā)給后端源站服務(wù)器,源站服務(wù)器經(jīng)過解析處理后,只認(rèn)為其中一部分請(qǐng)求,剩下的另外一部分就是走私請(qǐng)求,形成這個(gè)原因,是由于HTTP規(guī)范提供了兩種不同方式來指定請(qǐng)求的結(jié)束位置,它們是Content-Length標(biāo)頭和Transfer-Encoding標(biāo)頭。
我這里用的是https://portswigger.net演示環(huán)境,工具:burp suite,首先關(guān)閉Update content-length。
(1) CL.TE漏洞CT-TE: 前端使用Content-length,后端使用Transfer-Encoding前端服務(wù)器使用Content-Length頭,而后端服務(wù)器使用Transfer-Encoding頭。https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te第二次請(qǐng)求,惡意請(qǐng)求被執(zhí)行:前端服務(wù)器處理Content-Length標(biāo)頭,并確定請(qǐng)求正文的長度為9個(gè)字節(jié),直到的結(jié)尾test該請(qǐng)求被轉(zhuǎn)發(fā)到后端服務(wù)器。后端服務(wù)器處理Transfer-Encoding標(biāo)頭,因此將消息正文視為使用分塊編碼。它處理第一個(gè)塊,該塊被聲明為零長度,因此被視為終止請(qǐng)求。接下來的字節(jié)test保留未處理,后端服務(wù)器會(huì)將其視為序列中下一個(gè)請(qǐng)求的開始。(2) TE.CL漏洞前端服務(wù)器使用Transfer-Encoding頭,而后端服務(wù)器使用Content-Length頭。https://portswigger.net/web-security/request-smuggling/exploiting/lab-bypass-front-end-controls-te-cl,當(dāng)我們直接訪問/admin直接顯示403,無法訪問。該怎么辦呢,如果我們使用下面請(qǐng)求是不是就繞過了呢?  是的,但是提示必須host是localhost才能訪問,那我們直接加入HOST: localhost 可見加入HOST:localhost 發(fā)送請(qǐng)求,直接進(jìn)入管理頁面。

因?yàn)榍岸朔?wù)器處理Transfer-Encoding標(biāo)頭,使用分塊編碼。一直讀到為0,認(rèn)為讀取完畢,此時(shí)這個(gè)請(qǐng)求對(duì)代理服務(wù)器來說是一個(gè)完整的請(qǐng)求,然后轉(zhuǎn)發(fā)給后端服務(wù)器,后端服務(wù)器對(duì)Content-Length標(biāo)頭進(jìn)行處理,當(dāng)它讀完71后認(rèn)為請(qǐng)求結(jié)束,后面的數(shù)據(jù)就認(rèn)為另一個(gè)請(qǐng)求,也就是成功執(zhí)行。71是文件字節(jié)數(shù)十六進(jìn)制轉(zhuǎn)換出來的十進(jìn)制數(shù)。 文件字節(jié)數(shù)為十六進(jìn)制數(shù):113轉(zhuǎn)換為十進(jìn)制數(shù):71 TE-TE行為很容易理解,當(dāng)前端服務(wù)器和后端服務(wù)器都支持Transfer-Encoding標(biāo)頭,我們可以通過某種方式混淆標(biāo)頭來誘導(dǎo)其中一臺(tái)服務(wù)器不對(duì)其進(jìn)行處理。可以說還是CL-TE TE-CL。 https://portswigger.net/web-security/request-smuggling/exploiting/lab-bypass-front-end-controls-te-cl使用下面數(shù)據(jù)包進(jìn)行發(fā)送:當(dāng)我們第一請(qǐng)求直接返回正常頁面 : 當(dāng)我們第二次發(fā)包,直接執(zhí)行后面的GPOST:
1.不要重復(fù)使用后端連接,HTTP走私依賴多個(gè)后端多路復(fù)用,后端服務(wù)器將走私數(shù)據(jù)包與合法數(shù)據(jù)包一起處理,產(chǎn)生危害行為。如果每個(gè)請(qǐng)求單獨(dú)聯(lián)系發(fā)送,惡意的走私請(qǐng)求不在有效。
2.使用HTTP / 2進(jìn)行后端連接,因?yàn)榇藚f(xié)議禁止使用分塊傳輸編碼。3.前端服務(wù)器和后端服務(wù)器確保使用完全相同的Web服務(wù)器軟件,以便它們就請(qǐng)求之間的界限達(dá)成一致。https://portswigger.net/research/http-desync-attacks-request-smuggling-rebornhttps://portswigger.net/web-security/request-smuggling
|