Joe Orton wrote:
> On Thu, Nov 19, 2009 at 04:05:34PM +0100, Hartmut Keil wrote:
>> With the proposed change, we prevent request splitting attacks based 
>> on the TSL renegotiation flaw. From my point of view without 
>> drawbacks, since 'pipelining' clients must handle the closing of a 
>> connection after a complete response in any case.
> 
> Yes, I agree, this seems very sensible, I can't see any problem with 
> this.  
> 
> I would prefer to do it in a slightly more general way as below, which 
> would catch the case where any other module's connection filter had 
> buffered the data, and adds appropriate logging.
> 

Ok, I agree with your approach, giving more information what happens.
(maybe having a trace with info would be enough, since it can occurr under
normal circumstances)

> (more general but which required half a day tracking down an obscure bug 
> in the BIO/filters, also fixed below...)
yep, that fix is essential for the case here
> 
> Testing on this version very welcome!

If have successfully tested the change with the following setup
(the one described in my initial mail):

o for the location /cert/* SSLVerifyClient require is configured

o the MTIM attacker is injecting one complete request that causes the
   server to initiated the renegotiation.
   And a second incomplete one for request splitting

The proposed change is dropping the second incomplete request. The file
ssldump.patched in the attachment shows the output of ssldump with the
change, the file ssldump.injected without.


Regards
Hartmut



> 
> Index: ssl_engine_kernel.c
> ===================================================================
> --- ssl_engine_kernel.c       (revision 882089)
> +++ ssl_engine_kernel.c       (working copy)
> @@ -87,6 +87,29 @@
>      return APR_SUCCESS;
>  }
>  
> +/* Do a non-blocking read from the connection filters to see whether
> + * there is any pending data on the connection.  Return non-zero if
> + * there is, else zero. */
> +static int has_pending_data(request_rec *r) 
> +{
> +    apr_bucket_brigade *bb;
> +    apr_off_t len;
> +    apr_status_t rv;
> +    int result;
> +    
> +    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
> +    
> +    rv = ap_get_brigade(r->connection->input_filters, bb, 
> AP_MODE_SPECULATIVE,
> +                        APR_NONBLOCK_READ, 1); 
> +    result = rv == APR_SUCCESS
> +        && apr_brigade_length(bb, 1, &len) == APR_SUCCESS
> +        && len > 0;
> +    
> +    apr_brigade_destroy(bb);
> +    
> +    return result;
> +}
> +
>  /*
>   *  Post Read Request Handler
>   */
> @@ -724,6 +747,23 @@
>          else {
>              request_rec *id = r->main ? r->main : r;
>  
> +            /* Mitigation for CVE-2009-3555: At this point, before
> +             * renegotiating, an (entire) request has been read from
> +             * the connection.  An attacker may have sent further data
> +             * to "prefix" any subsequent request by the victim's
> +             * client after the renegotiation; this data may already
> +             * have been read and buffered.  Forcing a connection
> +             * closure after the first response ensures such data will
> +             * be discarded.  Legimately pipelined HTTP requests will
> +             * be retried anyway with this approach. */
> +            if (has_pending_data(r)) {
> +                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
> +                              "insecure SSL re-negotiation required, but "
> +                              "a pipelined request is present; keepalive "
> +                              "disabled");
> +                r->connection->keepalive = AP_CONN_CLOSE;
> +            }
> +
>              /* do a full renegotiation */
>              ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
>                            "Performing full renegotiation: "
> Index: ssl_engine_io.c
> ===================================================================
> --- ssl_engine_io.c   (revision 882089)
> +++ ssl_engine_io.c   (working copy)
> @@ -1344,9 +1344,17 @@
>      }
>      else {
>          /* We have no idea what you are talking about, so return an error. */
> -        return APR_ENOTIMPL;
> +        status = APR_ENOTIMPL;
>      }
>  
> +    /* It is possible for mod_ssl's BIO to be used outside of the
> +     * direct control of mod_ssl's input or output filter -- notably,
> +     * when mod_ssl initiates a renegotiation.  Switching the BIO mode
> +     * back to "blocking" here ensures such operations don't fail with
> +     * SSL_ERROR_WANT_READ. */
> +    inctx->block = APR_BLOCK_READ;
> +
> +    /* Handle custom errors. */
>      if (status != APR_SUCCESS) {
>          return ssl_io_filter_error(f, bb, status);
>      }
> 


-- 
AdNovum Informatik AG
Hartmut Keil, Senior Software Engineer
Dipl. Physiker

Roentgenstrasse 22, CH-8005 Zurich
mailto:hartmut.k...@adnovum.ch
phone: +41 44 272 6111, fax: +41 44 272 6312
http://www.adnovum.ch

AdNovum Locations: Bern, Budapest, San Mateo, Zurich (HQ)

New TCP connection #1: adnws121.zh.adnovum.ch(33856) <-> 
adnpool01.zh.adnovum.ch(44300)
1 1  0.0015 (0.0015)  C>S SSLv2 compatible client hello
  Version 3.1 
  cipher suites
  TLS_RSA_WITH_RC4_128_SHA  
  TLS_RSA_WITH_RC4_128_MD5  
  SSL2_CK_RC4  
1 2  0.0062 (0.0047)  S>C  Handshake
      ServerHello
        Version 3.1 
        session_id[0]=

        cipherSuite         TLS_RSA_WITH_RC4_128_MD5
        compressionMethod                   NULL
1 3  0.0063 (0.0000)  S>C  Handshake
      Certificate
1 4  0.0063 (0.0000)  S>C  Handshake
      ServerHelloDone
1 5  0.0074 (0.0011)  C>S  Handshake
      ClientKeyExchange
1 6  0.0078 (0.0003)  C>S  ChangeCipherSpec
1 7  0.1052 (0.0974)  C>S  Handshake
      Finished
1 8  0.1062 (0.0010)  S>C  ChangeCipherSpec
1 9  0.1062 (0.0000)  S>C  Handshake
      Finished
1 10 0.1069 (0.0006)  C>S  application_data
    ---------------------------------------------------------------
    GET /cert/hacked-initiated.html HTTP/1.1
    Host: adnpool01.zh.adnovum.ch
    
    GET /hacked/payload.html HTTP/1.1
    Host: adnpool01.zh.adnovum.ch
    X-Ignore: ---------------------------------------------------------------
1 11 0.1101 (0.0032)  S>C  Handshake
      HelloRequest
1 12 0.1101 (0.0000)  C>S  Handshake
      ClientHello
        Version 3.1 
        cipher suites
        Unknown value 0x39
        Unknown value 0x38
        Unknown value 0x37
        Unknown value 0x36
        Unknown value 0x35
        Unknown value 0x33
        Unknown value 0x32
        Unknown value 0x31
        Unknown value 0x30
        Unknown value 0x2f
        TLS_RSA_WITH_RC4_128_SHA
        TLS_RSA_WITH_RC4_128_MD5
        TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
        TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
        TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_RSA_WITH_3DES_EDE_CBC_SHA
        compression methods
                  NULL
1 13 0.1127 (0.0025)  S>C  Handshake
      ServerHello
        Version 3.1 
        session_id[0]=

        cipherSuite         TLS_RSA_WITH_RC4_128_MD5
        compressionMethod                   NULL
1 14 0.1128 (0.0000)  S>C  Handshake
      Certificate
1 15 0.1128 (0.0000)  S>C  Handshake
      CertificateRequest
        certificate_types                   rsa_sign
        certificate_types                   dss_sign
        certificate_types                 unknown value
        certificate_authority
          30 81 9b 31 0b 30 09 06 03 55 04 06 13 02 43 48 
          31 15 30 13 06 03 55 04 07 13 0c 38 30 30 35 20 
          5a 75 65 72 69 63 68 31 1e 30 1c 06 03 55 04 0a 
          13 15 41 64 4e 6f 76 75 6d 20 49 6e 66 6f 72 6d 
          61 74 69 6b 20 41 47 31 20 30 1e 06 03 55 04 0b 
          13 17 49 6e 74 65 72 6e 65 74 20 41 64 6d 69 6e 
          69 73 74 72 61 74 69 6f 6e 31 1e 30 1c 06 03 55 
          04 03 13 15 41 64 4e 6f 76 75 6d 20 49 6e 66 6f 
          72 6d 61 74 69 6b 20 41 47 31 13 30 11 06 09 2a 
          86 48 86 f7 0d 01 09 01 16 04 74 68 69 73 
      ServerHelloDone
1 16 3.3352 (3.2224)  C>S  Handshake
      Certificate
1 17 3.3352 (0.0000)  C>S  Handshake
      ClientKeyExchange
1 18 3.3352 (0.0000)  C>S  Handshake
      CertificateVerify
        Signature[128]=
          c0 8d 0c fc 57 e9 e1 c5 1a 32 07 7f 4b a3 6e 8e 
          05 6d b5 50 57 30 32 22 6d 6f cd b9 95 f6 2e ac 
          71 5f db 29 91 1f da 88 b8 76 fc f9 60 f8 9f d1 
          62 fa 9e ee 9b cd 8d f7 e2 c5 49 98 ba 4b 23 ed 
          6c 34 38 85 56 f7 ea 4e ec ed a6 40 41 e2 9e fd 
          fc 11 a4 b8 d3 68 9d 35 c2 47 72 81 e7 5e 11 7d 
          62 62 6b ba 53 0b 29 52 b2 34 97 fc 15 a6 c8 ec 
          43 4a c9 57 86 b0 bb 32 aa ba a2 65 18 46 ce b1 
1 19 3.3352 (0.0000)  C>S  ChangeCipherSpec
1 20 3.3352 (0.0000)  C>S  Handshake
      Finished
1 21 3.3773 (0.0420)  S>C  ChangeCipherSpec
1 22 3.3773 (0.0000)  S>C  Handshake
      Finished
1 23 3.3802 (0.0028)  S>C  application_data
    ---------------------------------------------------------------
    HTTP/1.1 200 OK
    Date: Fri, 20 Nov 2009 12:15:03 GMT
    Server: Apache
    Last-Modified: Mon, 16 Nov 2009 19:22:11 GMT
    ETag: "2d01bc-11d-47881ed266339"
    Accept-Ranges: bytes
    Content-Length: 285
    Content-Type: text/html
    
    ---------------------------------------------------------------
1 24 3.3802 (0.0000)  S>C  application_data
    ---------------------------------------------------------------
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" 
"http://www.w3.org/TR/REC-html40/loose.dtd";>
    <HTML>
    <HEAD>
    <TITLE>Welcome with a cert HACKED!!!!</TITLE>
    <BODY BGCOLOR="#FFFFFF">
    <CENTER><H2>
    Welcome to the Nevisweb Reverse Proxy  HACKED!!!
    </H2></CENTER>
    </BODY></HTML> 
    ---------------------------------------------------------------
1 25 3.4752 (0.0950)  C>S  application_data
    ---------------------------------------------------------------
    GET /victim HTTP/1.1
    User-Agent: Opera/9.64 (X11; Linux i686; U; en) Presto/2.1.1
    Host: adnpool01.zh.adnovum.ch:44300
    Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, 
image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
    Accept-Language: en
    Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
    Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
    If-Modified-Since: Mon, 16 Nov 2009 19:22:11 GMT
    If-None-Match: "2d01bc-11d-47881ed266339"
    Cookie: 
Navajo=RBBJKBGXeEs5//O88j0aYDWMmqZxh6bi4/BR4nJuRd4R2KrsXsUp2/qeHljJdPDYSQ8TWUO3VAk-;
 IW4Login=login
    Cookie2: $Version=1
    Connection: Keep-Alive, TE
    TE: deflate, gzip, chunked, identity, trailers
    
    ---------------------------------------------------------------
1 26 3.4827 (0.0074)  S>C  application_data
    ---------------------------------------------------------------
    HTTP/1.1 200 OK
    Date: Fri, 20 Nov 2009 12:15:06 GMT
    Server: Apache
    Last-Modified: Mon, 16 Nov 2009 19:21:58 GMT
    ETag: "2d01bd-11f-47881ec64adc9"
    Accept-Ranges: bytes
    Content-Length: 287
    Keep-Alive: timeout=5, max=9
    Connection: Keep-Alive
    Content-Type: text/html
    
    ---------------------------------------------------------------
1 27 3.4827 (0.0000)  S>C  application_data
    ---------------------------------------------------------------
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" 
"http://www.w3.org/TR/REC-html40/loose.dtd";>
    <HTML>
    <HEAD>
    <TITLE>Welcome with a cert INJECTED!!</TITLE>
    <BODY BGCOLOR="#FFFFFF">
    <CENTER><H2>
    Welcome to the Nevisweb Reverse Proxy INJECTED!!!!
    </H2></CENTER>
    </BODY></HTML> 
    ---------------------------------------------------------------
1    3.5833 (0.1005)  C>S  TCP FIN
1 28 3.5839 (0.0006)  S>C  Alert
    level           warning
    value           close_notify
New TCP connection #1: adnws121.zh.adnovum.ch(39573) <-> 
adnpool01.zh.adnovum.ch(44300)
1 1  0.0015 (0.0015)  C>S SSLv2 compatible client hello
  Version 3.1 
  cipher suites
  TLS_RSA_WITH_RC4_128_SHA  
  TLS_RSA_WITH_RC4_128_MD5  
  SSL2_CK_RC4  
1 2  0.0043 (0.0027)  S>C  Handshake
      ServerHello
        Version 3.1 
        session_id[0]=

        cipherSuite         TLS_RSA_WITH_RC4_128_MD5
        compressionMethod                   NULL
1 3  0.0043 (0.0000)  S>C  Handshake
      Certificate
1 4  0.0043 (0.0000)  S>C  Handshake
      ServerHelloDone
1 5  0.0055 (0.0011)  C>S  Handshake
      ClientKeyExchange
1 6  0.0058 (0.0003)  C>S  ChangeCipherSpec
1 7  0.1004 (0.0946)  C>S  Handshake
      Finished
1 8  0.1019 (0.0014)  S>C  ChangeCipherSpec
1 9  0.1019 (0.0000)  S>C  Handshake
      Finished
1 10 0.1025 (0.0006)  C>S  application_data
    ---------------------------------------------------------------
    GET /cert/hacked-initiated.html HTTP/1.1
    Host: adnpool01.zh.adnovum.ch
    
    GET /hacked/payload.html HTTP/1.1
    Host: adnpool01.zh.adnovum.ch
    X-Ignore: ---------------------------------------------------------------
1 11 0.1118 (0.0093)  S>C  Handshake
      HelloRequest
1 12 0.1119 (0.0000)  C>S  Handshake
      ClientHello
        Version 3.1 
        cipher suites
        Unknown value 0x39
        Unknown value 0x38
        Unknown value 0x37
        Unknown value 0x36
        Unknown value 0x35
        Unknown value 0x33
        Unknown value 0x32
        Unknown value 0x31
        Unknown value 0x30
        Unknown value 0x2f
        TLS_RSA_WITH_RC4_128_SHA
        TLS_RSA_WITH_RC4_128_MD5
        TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
        TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
        TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_RSA_WITH_3DES_EDE_CBC_SHA
        compression methods
                  NULL
1 13 0.1146 (0.0027)  S>C  Handshake
      ServerHello
        Version 3.1 
        session_id[0]=

        cipherSuite         TLS_RSA_WITH_RC4_128_MD5
        compressionMethod                   NULL
1 14 0.1146 (0.0000)  S>C  Handshake
      Certificate
1 15 0.1146 (0.0000)  S>C  Handshake
      CertificateRequest
        certificate_types                   rsa_sign
        certificate_types                   dss_sign
        certificate_types                 unknown value
        certificate_authority
          30 81 9b 31 0b 30 09 06 03 55 04 06 13 02 43 48 
          31 15 30 13 06 03 55 04 07 13 0c 38 30 30 35 20 
          5a 75 65 72 69 63 68 31 1e 30 1c 06 03 55 04 0a 
          13 15 41 64 4e 6f 76 75 6d 20 49 6e 66 6f 72 6d 
          61 74 69 6b 20 41 47 31 20 30 1e 06 03 55 04 0b 
          13 17 49 6e 74 65 72 6e 65 74 20 41 64 6d 69 6e 
          69 73 74 72 61 74 69 6f 6e 31 1e 30 1c 06 03 55 
          04 03 13 15 41 64 4e 6f 76 75 6d 20 49 6e 66 6f 
          72 6d 61 74 69 6b 20 41 47 31 13 30 11 06 09 2a 
          86 48 86 f7 0d 01 09 01 16 04 74 68 69 73 
      ServerHelloDone
1 16 10.3004 (10.1857)  C>S  Handshake
      Certificate
1 17 10.3004 (0.0000)  C>S  Handshake
      ClientKeyExchange
1 18 10.3004 (0.0000)  C>S  Handshake
      CertificateVerify
        Signature[128]=
          d1 2a df f5 9c d6 ae 12 d8 84 08 31 28 b4 c3 01 
          0d 6d d2 be c1 84 7a 84 64 80 47 bd f7 2f df 72 
          34 15 9c 20 59 3a cd 49 97 ef 7f f3 e4 2e 1d 26 
          3f 73 80 29 35 3b e3 00 3f 65 3b 61 58 d7 66 d5 
          38 43 d0 11 f1 7f ef a6 ad 52 77 05 42 21 13 22 
          01 52 a9 b0 69 b6 e2 88 ca 43 7b 4d 55 3e 29 24 
          c6 e3 14 8f 90 5d fc 94 d6 db fb f4 12 9e 32 86 
          b8 97 5f a5 2c 99 d8 f7 35 ef 18 48 f3 08 3a 6f 
1 19 10.3004 (0.0000)  C>S  ChangeCipherSpec
1 20 10.3004 (0.0000)  C>S  Handshake
      Finished
1 21 10.3398 (0.0393)  S>C  ChangeCipherSpec
1 22 10.3398 (0.0000)  S>C  Handshake
      Finished
1 23 10.3425 (0.0027)  S>C  application_data
    ---------------------------------------------------------------
    HTTP/1.1 200 OK
    Date: Fri, 20 Nov 2009 12:13:31 GMT
    Server: Apache
    Last-Modified: Mon, 16 Nov 2009 19:22:11 GMT
    ETag: "2d01bc-11d-47881ed266339"
    Accept-Ranges: bytes
    Content-Length: 285
    Connection: close
    Content-Type: text/html
    
    ---------------------------------------------------------------
1 24 10.3425 (0.0000)  S>C  application_data
    ---------------------------------------------------------------
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" 
"http://www.w3.org/TR/REC-html40/loose.dtd";>
    <HTML>
    <HEAD>
    <TITLE>Welcome with a cert HACKED!!!!</TITLE>
    <BODY BGCOLOR="#FFFFFF">
    <CENTER><H2>
    Welcome to the Nevisweb Reverse Proxy  HACKED!!!
    </H2></CENTER>
    </BODY></HTML> 
    ---------------------------------------------------------------
1 25 10.3429 (0.0003)  S>C  Alert
    level           warning
    value           close_notify
1 26 10.3429 (0.0000)  C>S  application_data
    ---------------------------------------------------------------
    GET /victim HTTP/1.1
    User-Agent: Opera/9.64 (X11; Linux i686; U; en) Presto/2.1.1
    Host: adnpool01.zh.adnovum.ch:44300
    Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, 
image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
    Accept-Language: en
    Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
    Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
    If-Modified-Since: Mon, 16 Nov 2009 19:22:11 GMT
    If-None-Match: "2d01bc-11d-47881ed266339"
    Cookie: 
Navajo=RBBJKBGXeEs5//O88j0aYDWMmqZxh6bi4/BR4nJuRd4R2KrsXsUp2/qeHljJdPDYSQ8TWUO3VAk-;
 IW4Login=login
    Cookie2: $Version=1
    Connection: Keep-Alive, TE
    TE: deflate, gzip, chunked, identity, trailers
    
    ---------------------------------------------------------------
1    10.3431 (0.0001)  C>S  TCP FIN
1    10.3434 (0.0002)  S>C  TCP FIN

Reply via email to