DDoS攻防補遺
去年在《淩雲》雜誌上寫過一篇關於DDoS攻防的文章,在線版本可以到官方網站https://storage.aliyun.com/aliyun_portal_storage/lingyun/lingyun-journal-2.pdf查看。當時因為篇幅的原因有些細節沒有展開,加上時間過去了大半年,出現了許多新的流行的攻擊方式,所以決定寫一篇補遺。
一、DRDoS攻擊
DRDoS(分布式反射攻擊)最早在2004年左右就出現了,安全焦點上還有一份國外的代碼,可以在https://www.xfocus.net/tools/200406/717.html下載查看。當時的DRDoS攻擊不具備放大流量的能力,某種意義上說類似拿衝鋒槍打牆,依靠反射回來的彈殼傷人,攻擊力不升反降,因而並沒有流行開來。
但是從2013年開始,DRDoS已經是互聯網上最流行、最吸引眼球的DDoS攻擊手段了,因為它附加流量放大屬性,通過史無前例的海量流量擊敗了如日中天的雲安全公司CloudFlare,引得大小黑客紛紛仿效。
DRDoS攻擊的原理是黑客偽造成受害者的IP地址,向互聯網上大量開放特定服務的主機發起請求,接收到請求的那些主機根據源IP地址將響應數據包返回給受害者。整個過程中,大量的無辜主機完全不知情,成為黑客攻擊的幫凶。一般來說,黑客會使用響應包遠大於請求包的服務來利用,這樣才可以以較小的流量換取交大的流量去攻擊,幾十倍的放大攻擊。能利用來做放大反射攻擊的服務,常見的有DNS服務、NTP服務、SNMP服務、Chargen服務等等,甚至某些online遊戲服務器也被利用來參與攻擊。
1.1. 基於UDP的反射攻擊
CloudFlare在2013年遭受的300Gbps的攻擊屬於DNS反射攻擊,當時導致他們全網故障。在2014年2月,它們遭受了前所未見的400Gbps的攻擊,黑客使用了NTP服務進行放大。
互聯網上有非常多的時間服務器,通過NTP協議提供對時服務。但是它缺乏身份認證手段,可以被任意使用。更重要的是,NTP協議有一個指令monlist可以列舉出最近同步過時間的600個主機列表,如下圖:
攻擊者發出的Monlist指令隻有1個數據包,耗費幾十個字節,而返回包多達幾十個,耗費2000-3000字節甚至更大,達到約50倍的放大。越是繁忙的NTP服務器,這個放大倍數越大。
攻擊者隻需要100Mbps的請求流量,可以換來5Gbps的攻擊流量,效率非常高。其它的DNS放大、SNMP放大、Chargen放大與NTP放大原理一致,隻是使用的協議有區別,不一一描述。
1.2. 基於TCP的反射攻擊
反射攻擊利用的協議,一般同時具有3種特征:容易偽造源IP地址、無身份認證、響應包遠大於請求包。因此,基於UDP的DNS協議、NTP協議、Chargen協議、SNMP協議成為首選。那麼,是不是隻有基於UDP的上層協議才能夠用來做放大反射攻擊,需要完成三次握手才能開始業務會話的基於TCP的上層協議就無法利用了?其實不是。
Chargen是一個常見的測試網絡連通性服務,同時工作在UDP協議和TCP協議上。對於它監聽的TCP端口,隻要有客戶端連上,就會源源不斷的向客戶端返回隨機字符串,永不停止。可以想象,如果這個東西可以利用起來做攻擊,無窮倍數的放大,是何等厲害。但是很遺憾,TCP不能偽造源IP地址,除非攻擊者能夠讓攻擊目標主動連接到Chargen的TCP端口去。
這種事情,恰好是代理協議做的事情!如果攻擊目標是HTTP Proxy或者Socks5 Proxy,攻擊者隻需要連接上目標的代理端口,然後去訪問Chargen服務並保持TCP連接不斷掉就行了。以HTTP代理為例,直接連接target的3128端口,然後發出類似https://chargen_server.com:19這樣的請求即可,socks5代理類似。
使用Chargen攻擊代理服務器效果雖好,但是畢竟應用範圍比較狹窄,一般的攻擊目標都是網站。黑客的創意在這兒展露無遺,他們也有各種新奇的手法,比如利用Google的某些服務或者Wordpress之類的博客來做DDoS攻擊。
Google有一個叫做FeedFetcher的爬蟲,為Google Feed API提供後端支持,會定期抓取RSS以及其它各種數據,如他們的電子表格服務spreadsheet中的鏈接。當電子表格服務中存在內容=image(“https://example.com/image.jpg”)時,Google就會“派出”FeedFetcher爬蟲去抓取這個圖片並保存到緩存中以將其顯示出來。
惡意攻擊者會找一個較大的文件,給文件名附加上隨機參數,使FeedFetcher多次抓取這個文件。也就是說,如果一個網站有一個10MB的文件,將以下列表輸入到Google spreadsheet中,那麼Google的爬蟲就會抓取該文件1000次,使網站產生大量出站流量。
=image(“https://targetname/file.pdf?r=0″)
=image(“https://targetname/file.pdf?r=1″)
=image(“https://targetname/file.pdf?r=2″)
=image(“https://targetname/file.pdf?r=3″)
…
=image(“https://targetname/file.pdf?r=1000″)
如果是帶寬比較小的站點,麵對這種攻擊時會非常痛苦。攔截會影響SEO效果,不攔截則需要付出更多的帶寬租賃費用。
基於類似的原理,Wordpress博客的pingback功能也可以用來做反射攻擊。PingBack是用來通知blog係統有文章被引用的一種手段。向
https://www.anywordpresssite.com/xmlrpc.php
提交POST請求, 數據格式如下:
<methodCall><methodName>pingback.ping</methodName><params><param><value><string>https://victim.com/post.php?id=1</string></value></param><param><value><string>https://www.anywordpresssite.com/pst?id=111</string></value></param></params></methodCall>, 則服務器www.anywordpresssite.com會向https://victim.com/post.php?id=1發起GET請求。如果攻擊者同時向大量的開啟了pingback的blog係統提交請求,則有大量的GET請求湧向攻擊目標,更多的更多細節可以參見https://drops.wooyun.org/news/1062。
但是就我看來,pingback這樣的反射攻擊意義不大,因為流量和請求次數都沒有被放大,如果單純是為了隱藏自己,可以選擇通過proxy的方式發起攻擊。更好的做法應該是向某個開啟了pingback的blog a發送大量的POST包(這裏的POST包通過代理發起),讓它去ping大量的blog,然後大量的http response會同攻擊者發起的POST包一起淹沒blog a,這才是優雅的反射放大攻擊——付出的代價是這種攻擊方式僅對有pingback功能的係統起作用。
1.3. DrDoS的防禦
TCP的反射攻擊有可能發生,但是危害程度遠不如UDP,而且發起難度較大,需要很多詭異的條件配合。因此,防禦上無需做過多考慮,將目光主要集中到基於UDP的反射放大攻擊。
首先,我們需要足夠大的帶寬,沒有帶寬一切都枉然。一般的,帶寬可以通過CDN的方式提供,將業務分散到不同地區的不同機房。
其次,從DRDos的本質知道,這種反射攻擊數據包的源端口一定是固定的,NTP放大攻擊源端口一定是UDP 123端口,DNS放大攻擊源端口一定是UDP 53端口。這其實是一個很好的特征,也是攻擊者不願意卻不得不留下的特征——有得到就有代價。在帶寬足夠的情況下,可以在網絡邊界部署ACL策略,禁止外網進來的源端口是UDP 123的報文,禁止外網進來的源端口是UDP 161的報文,禁止外網進來的源端口是UDP 19的報文,諸如此類。源端口是UDP 53的也可以過濾?也可以的,至少大部分IP地址可以無需請求外部的DNS服務。
這裏涉及到一條防禦準則,可以三層過濾的不要在四層做,可以在四層做的過濾不要到七層做。越往上,解析開銷越大。
二、高級SYN Flood攻防
1.4. SYN Cookie、SYN Proxy
最常見的SYN Flood防禦手段是SYN Cookie和SYN Proxy,它們原理簡單,而且效果也非常好。
在正常情況下,服務器端接收到客戶端發送的SYN包,會分配一個連接請求塊(即request_sock結構)用於保存連接信息,然後發送SYN+ACK包給客戶端,並將連接請求塊添加到半連接隊列中,沒收到最後一個ACK的話就輪詢重發SYN+ACK包。
對於啟用了SYN Cookie的服務器,不會這樣處理,它不維持任何連接信息, 而是將源IP、目的IP、源端口、目的端口、SYN序列號等信息進行hash運算,生成一個數字稱之為cookie。服務端將這個cookie作為SYN+ACK包的ACK確認號發送給客戶端,然後對這個IP發過來的後續ACK包的確認號進行驗算,與Cookie吻合的說明是正確的報文,正常建立連接,而攻擊的報文直接沒有了任何後續動作,也沒有額外開銷。
SYN Proxy則是管家式的防禦,它站在攻擊者和目標服務器之間,偽裝成目標服務器對所有的SYN報文進行應答,包括攻擊者在內。當三次握手正確的建立起來後,就偽裝成客戶端IP地址與後端的目標服務器建立三次握手,然後轉發數據,需要注意的是,TCP三次握手在這裏變成了6次握手,而且兩個握手內的ACK號肯定不一致,需要做一個修正。
SYN Cookie可以和SYN Proxy無縫集成,協同工作,提供更好的防禦服務,基本上100%無誤殺。那麼使用這種防禦手段,付出的代價是什麼?
我們可以看到,SYN Cookie和SYN Proxy對每一個SYN包都會進行答複,如果攻擊者發送1Gbps的報文過來,防禦方會發送1Gbps的報文回去。10Gbps就10Gbps,100Gbps就100Gbps。問題是,企業網絡禁得起這種折騰麼?基本上,攻擊流量達到一定程度,網絡不攻自潰。
1.5. 隨機丟包
對於過大的反彈流量的問題,安全廠商想出了許多新的辦法,那就是在答複之前做一些測試,能輕易過濾的流量就不反彈了。最主要的是隨機丟包策略,直接粗暴的丟棄SYN包,按照TCP協議正常的用戶會在3秒內重發這個SYN包,攻擊流量的源IP是偽造的,因此直接被丟棄了沒有任何後續。
這個方案看起來對SYN Cookie之類技術是一個很好的補充,但是也有一些問題。首先,正常用戶的體驗受到影響,訪問業務的速度變慢了。其次是某些高級攻擊者可以利用這個手段,繞過防禦,簡單的說,同樣的SYN包發兩次有可能被判定為正常訪問。一旦被防禦設備加入白名單,後續的報文就直接漏過了。
1.6. 反向探測
除了SYN Cookie、Proxy技術之外,還有一種反向探測的技術,也是頗為流行。防禦設備接收到SYN包時,回複一個ACK確認號錯誤的SYN+ACK報文。按照協議,客戶端會發一個RST報文過來重置連接。攻擊者一般是偽造源IP地址,沒有人會幫他做這個應答,SYN包被直接過濾掉。
這個方案,在實際環境中會遇到一些問題。某些防火牆設備,包括iptables,會過濾掉ACK號錯誤的SYN+ACK包,導致正常用戶的RST包發不過來而導致被誤殺。因此,考慮到穩定可靠,防禦設備回複的SYN+ACK包的ACK確認號需要滿足某些特征,比如小於或者等於SYN確認號。
對於攻擊者而言,他們可以通過tcp ping的方式掃描到真實存活的主機列表,然後使用這些IP地址作為源IP地址發起攻擊,可以有效繞過這種防禦手段。雖然一般的攻擊是要偽造不存在的源IP以達到更好的效果,但是這裏則要反其道而行之。
三、總結
總之,DDoS的防禦和攻擊都是一件非常精巧的事情。要優雅的攻擊,優雅的防禦。各種手法有符合常規的,也有要違背常規的。運用之妙,存乎一心。
四、後記
NTP攻擊的圖片來自網絡,更多細節可以參見:
基於Google的攻擊來自freebuf,參見:
https://www.freebuf.com/articles/web/28273.html。
最後更新:2017-04-03 12:56:11