作者:
囧思九千
·
2013/10/16 18:41
0x00 背景
大家好,我們是OpenCDN團隊,專注於CDN技術的開發和研究。
首先,為了對CDN進行攻擊,我們必須清楚CDN的工作原理,這裡我們再來簡單介紹一下CDN的工作模型。
CDN的全稱是Content Delivery Network(內容分發網路),透過在網路各處的加速節點伺服器來為網站抵擋惡意流量,把正常流量進行轉發。用簡單點的話來說,CDN一般有三個作用
1. 跨運營商加速:我們自己的網站常常只屬於一個運營商(比如:電信),而加速節點遍佈每家運營商,於是和網站不同運營商(比如:聯通)的使用者訪問起來就不會那麼慢了。
2. 快取加速:很多的靜態資源以及一部分頁面更新都是比較慢的(比如首頁),這個時候CDN就會根據瀏覽器的max-age和last-modified值以及管理員的預設值來進行快取,於是很多流量CDN節點就不會每次都來向網站請求,CDN節點可以直接自作主張地將命中的快取內容返回。
3. 惡意流量過濾:這是CDN非常重要的一個作用,也是很多網站會用CDN的原因,因為CDN能為我們抵擋攻擊大流量攻擊、普通的攻擊(比如注入等),只有正常流量才會轉發給網站。
這裡還要說明幾個名詞:
源站:我們自己的那個網站就被稱為是源站。
反向代理:CDN節點向源站請求資料的方式就叫反向代理,也就是上文所說的轉發。
回源:CDN節點向源站請求資料的行為就叫做回源。
0x01 探究之旅
我們在做OpenCDN測試的時候,遇到了一些小問題。發現一個沒有人訪問的網站居然會有流量,並且有著驚人的訪問次數。
我們的OpenCDN有2分鐘一次的反向代理檢測,但是這次數加起來也就區區的720次,而這400萬的訪問次數是哪裡冒出來的?然後我們檢視了日誌,發現單個域名的日誌到達了58G之多,而將其開啟之後發現X-Forwarded-For欄位中(X-Forwarded-For機制是透過一層代理後記錄一個IP,讓源站在使用CDN後能夠獲得真實的訪客IP而不是CDN節點IP)充斥著大量有的IP,而且都是本伺服器IP。我們瞬間明白了什麼,然後去管理端上驗證了一下,果不其然地,我們一不小心把源站IP設成了CDN節點的IP,不過當時我們並沒有發現。於是這麼大的流量也好解釋了,由於2分鐘一次的檢測觸發CDN節點的回源,而這個站點的源站是CDN節點本身,於是CDN就開始不斷自身反向代理死迴圈,這樣一個請求就被無限地放大了。當超時或者HEADER太大(就是X-Forwarded-For欄位導致HEADER溢位)的時候,請求會被丟棄。
把站點的源站IP設為CDN節點本身,能夠讓CDN節點進行自我的反向代理死迴圈,然後放大流量。
貌似有點意思,小夥伴們於是馬上就行動起來了,進行了實驗。
我們在安全寶上成功地將源站IP設定成了某個為我們加速的CDN節點IP,然後在美帝的一臺小vps上開webbench用2000個執行緒去打這個這個站點(無論是哪個CDN節點收到請求,請求最終都會匯聚到那個無辜的被設源站的CDN節點),不過實驗結果並不理想,節點沒有當機,透過IP反查詢到一臺和我們公用一個CDN節點的網站,透過這個CDN節點反向代理訪問那個網站,出現了卡頓和打不開情況,僅此而已。由於沒法採集到安全寶的這個節點的效能資料,我們也沒法對我們的攻擊做出評估。而且我們這個實驗缺少了一個對照組,到底是因為死迴圈把流量放大導致CDN節點卡頓,還是這個2000執行緒本身就能把CDN節點打卡。
於是我們總結了一下,猜想這種節點反向代理自身的攻擊手法可能可以適用於這樣的場景
你想要攻擊某個CDN節點,但是如果打404頁面消耗不了太多,而如果打CDN中的某個站點,因為流量會穿透過去,可能還沒有把CDN節點打掉,背後的站點早被穿透死了。這個時候,如果讓節點進行自身反向代理死迴圈,他就會把所有的流量給吃進去,並且沒法吐出來,這個時候可以產生一定量的流量槓桿效應,可以使得CDN節點出現異常。
不過話說回來,這種攻擊的防禦方式也異常簡單,只要在設定源站IP的時候,不讓設定CDN節點IP就行了,只要在網站前端互動輸入的時候加點驗證就行了。
我們考慮到我們沒法對不是我們的CDN節點的頻寬上限,效能上限有個很好的評估,黑盒式的摸索可能帶來不了什麼,於是我們拿我們自己的CDN節點開刀。
同時我們繼續對這個思路進行探索。我們發現,既然一個節點能死迴圈,那兩個節點怎麼樣?結果是肯定的,並且產生了質的變化。我們假設了這樣的一個場景
我們的opencdn.cc在甲CDN服務商註冊服務,並且在乙CDN服務商註冊服務,然後我們得到甲CDN服務商的一個CDN加速節點1.1.1.1,然後又得到乙CDN服務商的一個CDN加速節點2.2.2.2。 然後聰明的你一定已經猜到了。我們把在甲CDN服務商設定源站為乙的加速節點2.2.2.2,在乙CDN服務商設定源站為甲的加速節點1.1.1.1,然後甲會問乙去索取源站,乙又來問甲索取源站,於是1.1.1.1和2.2.2.2就很開心地並且不停地交流了起來~
於是我們也進行了實驗。這次我們採用POST包進行測試。
用POST包的原因有兩個
1.CDN節點是會有快取機制的,剛剛你請求的地址命中快取,那麼就直接返回,不會成為死迴圈了,而POST包則有一個很好的特性,絕對回源,一點也不含糊。
2.POST包可以擴大體積,在同等連線數的情況下讓效應更加明顯。
我們本次測試傳送500個POST包,每個體積大概為10k左右。然後總共傳送的流量為5M。
然後讓我們來看下兩個節點的反應
不過似乎到了頻寬上限。因為我們手中的機器畢竟也不是很給力。
然後讓我們來看下這500個POST包產生的效果
58.215.139.124
RX bytes:5473847154 (5.0 GiB) TX bytes:17106340685 (15.9 GiB)
RX bytes:6014294496 (5.6 GiB) TX bytes:17717990777 (16.5 GiB)
流入 540447342(515MB) 流出 611650092(583MB)
112.65.231.233
RX bytes:5583125549 (5.1 GiB) TX bytes:5022744608 (4.6 GiB)
RX bytes:6133578284 (5.7 GiB) TX bytes:5649798353 (5.2 GiB)
流入 550452735(524MB) 流出 627053745(598MB)
我們拿最小的進行測算吧,大概把流量擴大了100倍左右,然後如果把流入流出加起來就是擴大了200倍左右。
這一種攻擊方式和前一種相比有兩個優點
1.CDN服務商不能把源站IP做限制來防禦,因為他無法知道別家的CDN節點IP。
2.能借刀殺人,可以用一家CDN服務商的CDN節點來打另外一家CDN服務商。
然後我們還進行了一些聯想,一個站點可以把兩個節點陷入死迴圈,如果把更多的節點來進來呢?
我們可以這樣。讓多個CDN節點和一個CDN節點死迴圈,把中間的CDN節點頻寬耗盡。
我們還可以這樣。讓三個CDN節點死迴圈,如果有做流量上的流入流出探測限制,這樣能保證流入流出不為一個IP。
畢竟在CDN服務商新增一個域名的代價是很小的(免費),我們可以用一個一個域名將節點串起來,然後啪一下開始流量死迴圈震盪。
好了,讓我們用四個字總結一下這次的漏洞的特點:借力打力。
0x02 防禦方法
那麼如何來防禦這種以及可能演化出來的攻擊呢?
1. 禁止把源站IP設為CDN節點本身(這是必須的)。
2. 限制每個站點的頻寬。
3. 對請求超時的源站做一定限制。
4. 透過X-Forwarded-For來進行限制,超過多少層自動丟棄。
以及CDN節點已經存在的一系列的軟硬防都可以讓一部分的攻擊流量無法成型,自然也無法形成死迴圈震盪。
本文僅為一種CDN流量放大攻擊的思路,只是做過一些小規模的實驗,也歡迎大牛們進行驗證。如有不足之處或者邏輯上的錯誤還請提出,謝謝您的閱讀。
by OpenCDN成員 囧思八千 Twwy.net
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!