Vissza a www.andrews.hu-ra

    [guru-merlin] [aksecurity@hotpop.com: Technical Note by Amit Klein: Detecting and Preventing HTTP Response Splitting and HTTP Request Smuggling Attacks at the TCP Le]


    DATE: Mon, 22 Aug 2005 13:04:51 +0200
    Egy érdekes ötlet arra, hogy mit tehetnének a proxy szerverek a HTTP
    request smuggling valamint response splitting támadásokkal szemben.
    
    
    ----- Forwarded message from "Amit Klein (AKsecurity)" <aksecurity@hotpop.com> -----
    
    Date: Mon, 15 Aug 2005 20:31:00 +0200
    From: "Amit Klein (AKsecurity)" <aksecurity@hotpop.com>
    Subject: Technical Note by Amit Klein: Detecting and Preventing HTTP Response
     Splitting and HTTP Request Smuggling Attacks at the TCP Le
    To: bugTraq <bugtraq@securityfocus.com>
    
      Technical Note: Detecting and Preventing HTTP Response Splitting 
             and HTTP Request Smuggling Attacks at the TCP Level
    
    
                          Amit Klein, August 2005
    
    
    Introduction
    ============
    
    This technical note describes a detection/prevention technique that 
    works in many cases both with HTTP Response Splitting and with HTTP 
    Request Smuggling. This technique makes use of implicit information 
    found in the TCP stream, namely the segmentation into packets and 
    the TCP PSH bit. In HTTP Response Splitting, this technique needs 
    to be applied at the proxy server, the one closest to the web 
    server, and to the response stream. In HTTP Request Smuggling, this 
    technique needs to be applied at the entity closest to the attacked 
    proxy server/device (i.e. implemented in another proxy server, or 
    the web server itself), and to the request stream (note, however, 
    that this second server may be off the premises of the organization 
    wherein the web server is, see also "Can HTTP Request Smuggling be 
    blocked by Web Application Firewalls?", 
    http://www.securityfocus.com/archive/107/402974).
     
    
    TCP PSH bit and PUSH flag
    =========================
    
    Before describing the technique, the reader is reminded what are 
    the TCP PSH bit and PUSH flag. RFC 793 (Transmission Control 
    Protocol, http://www.ietf.org/rfc/rfc793.txt) defines the push 
    functionality as following (from section 1.5):
    
          Sometimes users need to be sure that all the data they have
          submitted to the TCP has been transmitted.  For this purpose 
          a push function is defined.  To assure that data submitted to 
          a TCP is actually transmitted the sending user indicates that 
          it should be pushed through to the receiving user.  A push 
          causes the TCPs to promptly forward and deliver data up to 
          that point to the receiver.
    
    And in section 2.8:
    
          The sending user indicates in each SEND call whether the data 
          in that call (and any preceeding [sic] calls) should be 
          immediately pushed through to the receiving user by the 
          setting of the PUSH flag.
    
    This is realized by a PSH bit in the TCP header.
    
    RFC 793 also mandates that the socket API provides means for the 
    caller to set this bit via a PUSH flag in the SEND function, and to 
    likewise receive it in the RECV function. 
    However, this requirement was later waived in RFC 1122 
    (Requirements for Internet Hosts - Communication Layers, 
    http://www.ietf.org/rfc/rfc1122.txt), section 4.2.2.2:
    
          A TCP MAY implement PUSH flags on SEND calls. If PUSH flags 
          are not implemented, then the sending TCP: (1) must not 
          buffer data indefinitely, and (2) MUST set the PSH bit in the 
          last buffered segment (i.e., when there is no more queued 
          data to be sent).
    
          The discussion in RFC-793 on pages 48, 50, and 74 erroneously 
          implies that a received PSH flag must be passed to the 
          application layer. Passing a received PSH flag to the 
          application layer is now OPTIONAL.
    
    And indeed, the two implementations of sockets, the UNIX BSD 
    sockets and WinSock, do not implement the PUSH flag neither in SEND 
    nor in RECEIVE:
    
    *) FreeBSD (example of standard BSD sockets)
       send(2) man page:   
    http://www.freebsd.org/cgi/man.cgi?query=send&apropos=0&sektion=2&manpath=FreeBSD+5.4-
    RELEASE+and+Ports&format=html
       recv(2) man page: 
    http://www.freebsd.org/cgi/man.cgi?query=recv&apropos=0&sektion=2&manpath=FreeBSD+5.4-
    RELEASE+and+Ports&format=html
    
    *) Sun Solaris 8 (another example of standard BSD sockets)
       send(3SOCKET) man page: http://docs.sun.com/app/docs/doc/806-0628/6j9vie803?a=view 
       recv(3SOCKET) man page: http://docs.sun.com/app/docs/doc/806-0628/6j9vie7u0?a=view 
    
    *) Microsoft Windows WinSock (2.0) sockets: 
       send:    
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/send_2.asp
       recv: 
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/recv_2.asp 
    
    This means that according to RFC 1122, these implementations should 
    simply set the TCP PSH flag in the last TCP segment of the caller's 
    data buffer. Unfortunately, this also means that socket 
    applications do not have direct access to the PSH bit (in other 
    words, it would take some hacking around the standard sockets API 
    to get this information - thus making the whole idea presented 
    below much harder to implement in pure sockets applications).
    To illustrate: a sender uses the sockets send() function to send a 
    payload of 2000 bytes over a TCP circuit on a LAN. The call is 
    (assuming C API):
    
          send(socket, buffer, 2000, ...);
    
    This results in 2 TCP segments (IP packets), the first carrying a 
    payload of 1448 bytes (maximal LAN packet, minus level 2, IP and 
    TCP headers), the second carrying a payload of the remaining 552 
    bytes, with a PSH bit set.
    In contrast, having the caller invoke send twice to send the same 
    data:
    
          send(socket, buffer, 1000, ...);
          send(socket,buffer+1000, 1000, ...);
    
    Results in 2 TCP segments, both having 1000 bytes of payload, and 
    both having the PSH bit set.
    Therefore, by inspecting the TCP header, one can figure out (in 
    this rather simplistic example) whether the data was sent via a 
    single call to send(), or via two calls.
    This observation is the basis for the following technique described 
    below.
     
    
    Detecting HTTP Response Splitting and HTTP Request Smuggling
    ============================================================
    
    Detection of HTTP Response Splitting attack can be realized by 
    fulfilling the following requirements (the technique can be applied 
    to HTTP Request Smuggling with some obvious modifications):
    
    Requirement #1: Deny "pipelined" traffic, that is, do not accept a 
    second response before a first response was fully served, and a 
    second request was fully received. Particularly, a packet 
    containing data for the first response must not contain superfluous 
    data beyond the end of the first response (i.e. a second response).
    
    Requirement #2: Since from #1 it follows that the end of the first 
    response coincides with an end of a packet, and end of 
    transmission, such packet should contain a PSH bit set (see above).
    
    Requirement #1 is obvious, yet insufficient, as shown in the 
    successful HTTP Response Splitting attacks against Squid and 
    NetCache (see "Divide and Conquer - HTTP Response Splitting, Web 
    Cache Poisoning Attacks, and Related Topics", 
    http://www.packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf, 
    pp. 15-19), although both products impose packet 
    boundary requirements (making sure that the first response 
    terminates at a packet boundary isn't so hard if the packet length 
    is known to the attacker). But if we are to add requirement #2, the 
    attack can be thwarted in many cases, because the attacker has no 
    way of forcing the web server to send the PSH flag (remember that 
    the from the web server's perspective, it is in the middle of the 
    first response, and will send the PSH bit only at the end of the 
    first response). Of course, it may be possible that the web server 
    always sends the PSH bit (for example, the TCP stack of IBM TPF 4.1 
    apparently does so by default - see the description of TCP_PSH_LAST 
    ioctl option in http://www-306.ibm.com/software/htp/tpf/serv/GTPMLB19.pdf), 
    or sends it after each HTTP response header, or in the middle of 
    the response, but that is not the case with many servers (although
    I have seen servers that on occasion will send the PSH flag in the
    middle of HTTP responses).
    
    So, while it may not be perfect, it seems that this technique has a 
    high detection probability (much higher than enforcing requirement 
    #1 alone), yet very low likelihood for false positives. 
    
    
    Notes
    =====
    
    1. The technique fails if there are TCP/HTTP aware devices between 
    the web server and the proxy server, as these may alter the TCP 
    stream.
    
    2. The technique can be applied to HTTP Request Smuggling as 
    following: the proxy server forwards the requests to the web 
    server. The web server (or the receiving entity) needs to verify 
    that the request ends on a packet boundary, and that the PSH flag 
    is set.
    
    3. While the technique covers detection of attacks, since such 
    detection is carried out in real-time, it is possible to terminate 
    the TCP connection (or perform other actions) and thereby to block 
    the attack. 
    
    4. This technique lends itself nicely to detection/prevention by 
    network IDS/IPS, as it only requires sniffing the TCP/IP traffic 
    and flagging HTTP requests/responses that do not terminate on a 
    packet boundary, with PSH bit set.
    
    
    Alternatives
    ============
    
    Other, complementary methods (for prevention) that are known to 
    work are:
    
    1. The web site can use SSL connections (HTTPS) only. This will 
    only eliminate 3rd party proxy servers. It does not eliminate the 
    browser cache issue, and it may not handle the site's own cache 
    server (or any other on-site HTTP aware devices). Of course, 
    migrating to SSL only has many real-life drawbacks.
    
    2. A proxy cache server can be configured not to use persistent 
    HTTP connections with the *server*, in which case, its cache will 
    not be poisoned. This prevention technique has significant 
    performance impact.
    
    
    Summary
    =======
    
    Observing that an end of HTTP request/response message is aligned 
    with a TCP segment (packet) boundary, *and* that that segment has 
    the PSH bit set, can be an effective way to detect and prevent HTTP 
    Response Splitting and HTTP Request Smuggling. This technique can 
    be easily employed when the TCP layer is directly accessible (as 
    opposed to the sockets model). 
    
    
    Off topic personal notice/clarification
    =======================================
    
    I am often asked whether I work for Watchfire, or did so in the 
    past. So let me state the following:
    
    1. I am not employed by Watchfire, and I am not part of any 
    Watchfire team.
    
    2. In fact, I have never been employed by watchfire (I was employed 
    by Sanctum for many years, but I quit Sanctum slightly before it 
    was acquired by Watchfire).
    
    Having said that, I have nothing against Watchfire, and I wish them 
    best of luck.
    
    
    ----- End forwarded message -----
    
    
    

    Vissza a www.andrews.hu-ra