導讀
HTTP 的 Slow Attack 有著悠久歷史的 HTTP DOS 攻擊方式,最早大約追溯到 5 年前,按理說早該修復了,但是 Apache 的默認配置中仍然沒有添加相關配置,或者他們認為這是 feture 不是 bug,所以至今默認安裝的 Apache 中還存在著 Slow Attack 的威脅。
1、Slow Attack 大致可分為以下幾種:
-
Slow Header (slowloris):每個 HTTP 請求都是以空行結尾,即以兩個 (\r\n)結 尾 。 若將空行去掉 ,即以 一個 (\r\n) 結尾,則服務器會一直等待直到超時。在等待過程中占用線程(連接數),服務器線程數量達到極限,則無法處理新的合法的 HTTP請求,達到DOS目的。
-
Slow Read:向 Web 服務器發送正常合法的 read 請求,請求一個很大的文件,并將 TCP 滑動窗口 size 設置很小如 1 或 2,服務器就會以非常緩慢的速度發送文件,文件將長期滯留在服務器內存中,消耗資源,造成DOS。
-
Slow Post:攻擊者向服務器發送 POST 請求,告訴服務器它將要 POST 的數據為 n,服務器將分配長度為 n 的空間來等待接收數據。當 n 足夠大, POST 的請求足夠多的時候,這種攻擊會占用服務器的大量內存,從而降低服務器性能,甚至導致癱瘓。
-
以及多年前的 Apache Range Attack(現已修復):在 HTTP 請求的 RANGE HEADER 中包含大量字段,使得服務器在服務端將一個很小的文件分割成大量的更小的片段再壓縮。分段壓縮過程消耗大量的服務器資源,導致 DOS。
2、漏洞證明:
測試環境
Debian7 x86_64 & Apache 2.2.22
Debian8 x86_64 & Apache 2.4.10
配置和測試工具
(1) 在 Debian 中通過 apt 安裝默認的 Apache
apt-get -y install apache2
(2) 在默認的 DocumentRoot 目錄里面放一個測試文件,serverlist.txt
(3) 更換監聽端口為 8889(程序 GG 們是不是有似曾相識的感覺)
(4) 用 slowhttptest 工具對 debian7 測試上面四種攻擊方法,工具 wiki
結果如下:
slow header
slowhttptest -c 65500 -H -i 10 -r 200 -s 8192 -t SLOWHEADER -u http://debian7:8889
給 Apache 發送的請求如下(Header 少了一個換行,表示 Header 一直沒發完):
Apache 中充斥著這樣的連接,導致 DOS
slow read
slowhttptest -c 65500 -X -r 1000 -w 10 -y 20 -t SLOWREAD -n 5 -z 32 -u http://debian7:8889
給 Apache 發送的是合法的請求(但是窗口很小)
最終導致占滿了連接,依然 DOS
slow post
slowhttptest -c 65500 -B -i 10 -r 200 -s 8192 -t SLOWBODY -u http://debian7:8889
給 Apache 發送的請求如下(以很慢的速度來發送 message body)
同樣也導致 DOS
Apache Range Attack
已失效的攻擊方法,可以看一下它給 Apache 發送的請求是什么樣的
slowhttptest -c 65000 -R -u http://debian7:8889 -t HEAD -a 5 -b 300000 -r 500
要求服務器將文件分成很多很多的小段,用來消耗服務器資源,理論上 CPU 和 Memory 會增加
3、漏洞修復方法
(1) 根據作者的文章:[How to Protect Against Slow HTTP Attacks]
對于 Apache 可以做以下優化:
-
設置合適的 timeout 時間(Apache 已默認啟用了 reqtimeout 模塊),規定了 Header 發送的時間以及頻率和 Body 發送的時間以及頻率
-
增大 MaxClients(MaxRequestWorkers):增加最大的連接數。根據官方文檔,兩個參數是一回事,版本不同,
MaxRequestWorkers was called MaxClients before version 2.3.13. The old name is still supported.
-
默認安裝的 Apache 存在 Slow Attack 的威脅,原因就是雖然設置的 timeoute,但是最大連接數不夠,如果攻擊的請求頻率足夠大,仍然會占滿 Apache 的所有連接
(2) 根據這篇文章:[How To Mitigate Slow HTTP DoS Attacks in Apache HTTP Server]
可以使用 Apache 的模塊來緩解 Http Slow Attack
-
mod_reqtimeout:默認已啟用。設置 header 和 body 的發送時間及頻率
<IfModule reqtimeout_module>RequestReadTimeout header=20-40,minrate=500RequestReadTimeout body=10,minrate=500</IfModule>
-
mod_qos:開源模塊,需額外安裝。可設置多個參數來控制客戶端的連接,如最大 IP 數、每個 IP 最大連接數等
<IfModule mod_qos.c> # handle connections from up to 100000 different IPs QS_ClientEntries 100000 # allow only 50 connections per IP QS_SrvMaxConnPerIP 50 # limit maximum number of active TCP connections limited to 256 MaxClients 256 # disables keep-alive when 180 (70%) TCP connections are occupied QS_SrvMaxConnClose 180 # minimum request/response speed (deny slow clients blocking the server, keeping connections open without requesting anything QS_SrvMinDataRate 150 1200</IfModule>
-
mod_security:開源模塊,需額外安裝。性能較好,可以為 Web 應用提供一個外部安全層來檢測和抵御攻擊
SecRule RESPONSE_STATUS "@streq 408" "phase:5,t:none,nolog,pass,
setvar:ip.slow_dos_counter=+1, expirevar:ip.slow_dos_counter=60, id:'1234123456'"SecRule IP:SLOW_DOS_COUNTER "@gt 5" "phase:1,t:none,log,drop,
msg:'Client Connection Dropped due to high number of slow DoS alerts', id:'1234123457'"
根據上面的配置, mod_security 記錄每個 IP 讓 Apache 返回 408(request timeout) 的次數,當一分鐘內超過 5 次時,那個 IP 的請求會在 5 分鐘內全部被丟棄。 當然也可以根據實際情況配置其他的安全策略。
(3) serverlist 使用場景下最簡單的修復方法
剛剛的使用場景僅僅是從 Apache 獲取 serverlist,每個 IP 只需要一個短鏈接就可以滿足需求,所以直接在 iptables 中限制每個 IP 的連接數可以解決以上絕大部分問題,除非攻擊者擁有眾多肉雞,否則單 IP 的攻擊將失去效果。
iptables -A INPUT -p tcp --syn --dport 8889 -m connlimit --connlimit-above 20 -j REJECT --reject-with tcp-reset
用 iptables 設置了每個 IP 的最大連接數后,測試結果顯示 Attacker 只能建立 20 個連接,所有攻擊方法失效。
后記
-
默認安裝的 Apache 還是比較坑的,一不小心就被 DDOS 了,大家在安裝部署服務的時候還是要根據實際情況謹慎配置服務。
-
關于 Slow Attack 對其他 Web 服務器的影響,可以參見作者的文章:Testing Web Servers for Slow HTTP Attacks
文章列表