CDN流量放大攻擊思路
首先,為了對CDN進(jìn)行攻擊,我們必須清楚CDN的工作原理,這里我們再來簡單介紹一下CDN的工作模型。

CDN的全稱是Content Delivery Network(內(nèi)容分發(fā)網(wǎng)絡(luò)),通過在網(wǎng)絡(luò)各處的加速節(jié)點服務(wù)器來為網(wǎng)站抵擋惡意流量,把正常流量進(jìn)行轉(zhuǎn)發(fā)。用簡單點的話來說,CDN一般有三個作用
1. 跨運營商加速:我們自己的網(wǎng)站常常只屬于一個運營商(比如:電信),而加速節(jié)點遍布每家運營商,于是和網(wǎng)站不同運營商(比如:聯(lián)通)的用戶訪問起來就不會那么慢了。
2. 緩存加速:很多的靜態(tài)資源以及一部分頁面更新都是比較慢的(比如首頁),這個時候CDN就會根據(jù)瀏覽器的max-age和last-modified值以及管理員的預(yù)設(shè)值來進(jìn)行緩存,于是很多流量CDN節(jié)點就不會每次都來向網(wǎng)站請求,CDN節(jié)點可以直接自作主張地將命中的緩存內(nèi)容返回。
3. 惡意流量過濾:這是CDN非常重要的一個作用,也是很多網(wǎng)站會用CDN的原因,因為CDN能為我們抵擋攻擊大流量攻擊、普通的攻擊(比如注入等),只有正常流量才會轉(zhuǎn)發(fā)給網(wǎng)站。
這里還要說明幾個名詞:
源站:我們自己的那個網(wǎng)站就被稱為是源站。
反向代理:CDN節(jié)點向源站請求數(shù)據(jù)的方式就叫反向代理,也就是上文所說的轉(zhuǎn)發(fā)。
回源:CDN節(jié)點向源站請求數(shù)據(jù)的行為就叫做回源。
下面開始我們的探究之旅。
我們在做OpenCDN測試的時候,遇到了一些小問題。發(fā)現(xiàn)一個沒有人訪問的網(wǎng)站居然會有流量,并且有著驚人的訪問次數(shù)。

我們的OpenCDN有2分鐘一次的反向代理檢測,但是這次數(shù)加起來也就區(qū)區(qū)的720次,而這400萬的訪問次數(shù)是哪里冒出來的?然后我們查看了日志,發(fā)現(xiàn)單個域名的日志到達(dá)了58G之多,而將其打開之后發(fā)現(xiàn)X-Forwarded-For字段中(X-Forwarded-For機制是通過一層代理后記錄一個IP,讓源站在使用CDN后能夠獲得真實的訪客IP而不是CDN節(jié)點IP)充斥著大量有的IP,而且都是本服務(wù)器IP。我們瞬間明白了什么,然后去管理端上驗證了一下,果不其然地,我們一不小心把源站IP設(shè)成了CDN節(jié)點的IP,不過當(dāng)時我們并沒有發(fā)現(xiàn)。于是這么大的流量也好解釋了,由于2分鐘一次的檢測觸發(fā)CDN節(jié)點的回源,而這個站點的源站是CDN節(jié)點本身,于是CDN就開始不斷自身反向代理死循環(huán),這樣一個請求就被無限地放大了。當(dāng)超時或者HEADER太大(就是X-Forwarded-For字段導(dǎo)致HEADER溢出)的時候,請求會被丟棄。
把站點的源站IP設(shè)為CDN節(jié)點本身,能夠讓CDN節(jié)點進(jìn)行自我的反向代理死循環(huán),然后放大流量。
貌似有點意思,小伙伴們于是馬上就行動起來了,進(jìn)行了實驗。
我們在安全寶上成功地將源站IP設(shè)置成了某個為我們加速的CDN節(jié)點IP,然后在美帝的一臺小vps上開webbench用2000個線程去打這個這個站點(無論是哪個CDN節(jié)點收到請求,請求最終都會匯聚到那個無辜的被設(shè)源站的CDN節(jié)點),不過實驗結(jié)果并不理想,節(jié)點沒有宕機,通過IP反查找到一臺和我們公用一個CDN節(jié)點的網(wǎng)站,通過這個CDN節(jié)點反向代理訪問那個網(wǎng)站,出現(xiàn)了卡頓和打不開情況,僅此而已。由于沒法采集到安全寶的這個節(jié)點的性能數(shù)據(jù),我們也沒法對我們的攻擊做出評估。而且我們這個實驗缺少了一個對照組,到底是因為死循環(huán)把流量放大導(dǎo)致CDN節(jié)點卡頓,還是這個2000線程本身就能把CDN節(jié)點打卡。
于是我們總結(jié)了一下,猜想這種節(jié)點反向代理自身的攻擊手法可能可以適用于這樣的場景
你想要攻擊某個CDN節(jié)點,但是如果打404頁面消耗不了太多,而如果打CDN中的某個站點,因為流量會穿透過去,可能還沒有把CDN節(jié)點打掉,背后的站點早被穿透死了。這個時候,如果讓節(jié)點進(jìn)行自身反向代理死循環(huán),他就會把所有的流量給吃進(jìn)去,并且沒法吐出來,這個時候可以產(chǎn)生一定量的流量杠桿效應(yīng),可以使得CDN節(jié)點出現(xiàn)異常。
不過話說回來,這種攻擊的防御方式也異常簡單,只要在設(shè)置源站IP的時候,不讓設(shè)置CDN節(jié)點IP就行了,只要在網(wǎng)站前端交互輸入的時候加點驗證就行了。
我們考慮到我們沒法對不是我們的CDN節(jié)點的帶寬上限,性能上限有個很好的評估,黑盒式的摸索可能帶來不了什么,于是我們拿我們自己的CDN節(jié)點開刀。
同時我們繼續(xù)對這個思路進(jìn)行探索。我們發(fā)現(xiàn),既然一個節(jié)點能死循環(huán),那兩個節(jié)點怎么樣?結(jié)果是肯定的,并且產(chǎn)生了質(zhì)的變化。我們假設(shè)了這樣的一個場景
我們的opencdn.cc在甲CDN服務(wù)商注冊服務(wù),并且在乙CDN服務(wù)商注冊服務(wù),然后我們得到甲CDN服務(wù)商的一個CDN加速節(jié)點1.1.1.1,然后又得到乙CDN服務(wù)商的一個CDN加速節(jié)點2.2.2.2。 然后聰明的你一定已經(jīng)猜到了。我們把在甲CDN服務(wù)商設(shè)置源站為乙的加速節(jié)點2.2.2.2,在乙CDN服務(wù)商設(shè)置源站為甲的加速節(jié)點1.1.1.1,然后甲會問乙去索取源站,乙又來問甲索取源站,于是1.1.1.1和2.2.2.2就很開心地并且不停地交流了起來~

于是我們也進(jìn)行了實驗。這次我們采用POST包進(jìn)行測試。

用POST包的原因有兩個
1.CDN節(jié)點是會有緩存機制的,剛剛你請求的地址命中緩存,那么就直接返回,不會成為死循環(huán)了,而POST包則有一個很好的特性,絕對回源,一點也不含糊。
2.POST包可以擴大體積,在同等連接數(shù)的情況下讓效應(yīng)更加明顯。
我們本次測試發(fā)送500個POST包,每個體積大概為10k左右。然后總共發(fā)送的流量為5M。
然后讓我們來看下兩個節(jié)點的反應(yīng)

不過似乎到了帶寬上限。因為我們手中的機器畢竟也不是很給力。
然后讓我們來看下這500個POST包產(chǎn)生的效果
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)
我們拿最小的進(jìn)行測算吧,大概把流量擴大了100倍左右,然后如果把流入流出加起來就是擴大了200倍左右。
這一種攻擊方式和前一種相比有兩個優(yōu)點
1.CDN服務(wù)商不能把源站IP做限制來防御,因為他無法知道別家的CDN節(jié)點IP。
2.能借刀殺人,可以用一家CDN服務(wù)商的CDN節(jié)點來打另外一家CDN服務(wù)商。
然后我們還進(jìn)行了一些聯(lián)想,一個站點可以把兩個節(jié)點陷入死循環(huán),如果把更多的節(jié)點來進(jìn)來呢?
我們可以這樣。讓多個CDN節(jié)點和一個CDN節(jié)點死循環(huán),把中間的CDN節(jié)點帶寬耗盡。

我們還可以這樣。讓三個CDN節(jié)點死循環(huán),如果有做流量上的流入流出探測限制,這樣能保證流入流出不為一個IP。

畢竟在CDN服務(wù)商添加一個域名的代價是很小的(免費),我們可以用一個一個域名將節(jié)點串起來,然后啪一下開始流量死循環(huán)震蕩。
好了,讓我們用四個字總結(jié)一下這次的漏洞的特點:借力打力。
那么如何來防御這種以及可能演化出來的攻擊呢?
1. 禁止把源站IP設(shè)為CDN節(jié)點本身(這是必須的)。
2. 限制每個站點的帶寬。
3. 對請求超時的源站做一定限制。
4. 通過X-Forwarded-For來進(jìn)行限制,超過多少層自動丟棄。
以及CDN節(jié)點已經(jīng)存在的一系列的軟硬防都可以讓一部分的攻擊流量無法成型,自然也無法形成死循環(huán)震蕩。
本文僅為一種CDN流量放大攻擊的思路,只是做過一些小規(guī)模的實驗,也歡迎大牛們進(jìn)行驗證。如有不足之處或者邏輯上的錯誤還請?zhí)岢?,謝謝您的閱讀。