thttpd 2.04 stack overflow (VD#6)

From: Blue Boar (BlueBoarat_private)
Date: Sat Nov 13 1999 - 09:54:29 PST

  • Next message: jlewisat_private: "Re: networksolutions CRYPT-PW salt (was: Re: Insecure handling of"

    -------------------------------------------------------------------
    Periodically, the moderator of of the vuln-dev mailing list will post
    summaries of issues discussed there to Bugtraq and possibly other relevant
    lists.  This will usually happen when an issue has been resolved, or it
    appears that there will be no further discussion on vuln-dev.  Each
    separate issue will be given it's own posting to facilitate referencing
    them separately, for discussion, forwarding, or appearance in vulnerability
    databases.
    
    To subscribe to vuln-dev, send an e-mail to listservat_private,
    with SUBSCRIBE VULN-DEV in the body of the message.
    
    A FAQ and archive can be found at www.securityfocus.com-->forums-->vuln-dev
    (click on these sections, the web pages are forms-based.)
    -------------------------------------------------------------------
    
    Sorry to take so long getting this one out, especially after how quickly
    the author had a fix.  Check out the times on the messages (My mail reader
    calculates those out to be 5:05 P.M. and 5:58 P.M., my time).  I've been
    wiped out for a few days with a nasty case of strep throat.  Anyway, I'm
    including the two messages in their entirety.  If you run thttpd, you'll
    want to take immediate action.
    
    I commend the package author on his handling of this issue.  No whining, no
    excuses, no attacking the person who found the holes, just a very timely
    fix.
    
    						BB
    -------------------------------------------------------------------
    Subject:     thttpd 2.04 stack overflow
       Date:     Wed, 10 Nov 1999 01:05:04 -0000
       From:     "D. J. Bernstein" <djbat_private>
         To:     VULN-DEVat_private
    
    thttpd is a single-process web server. According to Netcraft, it's used
    on 1.82% of all HTTP servers, behind only Apache, IIS, Enterprise, and
    Rapidsite. The current version is thttpd 2.04; as far as I know, the
    comments below apply to all versions back to 1.90a.
    
    The thttpd web page says that thttpd is simple, small, portable, fast,
    and secure; it ``goes to great lengths to protect the web server machine
    against attacks and breakins from other sites.'' Sounds good, doesn't it?
    
    Today I glanced at the thttpd 2.04 source code, wondering how seriously
    thttpd parsed HTTP If-Modified-Since fields. I was horrified to see that
    tdate_parse() scans %[a-zA-Z] into a fixed-size stack buffer.
    
    I tried running thttpd on a throwaway account, and feeding it an
    If-Modified-Since line with 1300 x's. It dumped core. This is something
    that any attacker on the Internet could do to any thttpd server, taking
    down web service until thttpd is restarted.
    
    Presumably, at least on little-endian machines, a careful attacker can
    take over the thttpd server---i.e., take over web service, and anything
    else running as ``nobody''---by overwriting only two or three bytes of
    the return address. But I haven't spent any more time looking at the
    code. Perhaps other people here would be interested in investigating
    thttpd's security in more detail.
    
    (Disclaimer: I'm writing my own HTTP server.)
    
    ---Dan
    
    -------------------------------------------------------------------
    
    Subject:     Re: thttpd 2.04 stack overflow
       Date:     Tue, 9 Nov 1999 17:58:45 -0800
       From:     Jef Poskanzer <jefat_private>
         To:     VULN-DEVat_private
    
    >Today I glanced at the thttpd 2.04 source code, wondering how seriously
    >thttpd parsed HTTP If-Modified-Since fields. I was horrified to see that
    >tdate_parse() scans %[a-zA-Z] into a fixed-size stack buffer.
    
    You're right, that's pretty bad.  Thanks for the note.  Fortunately
    the fix is trivial, and I had a new version of thttpd ready to go,
    so I went ahead and released it.  The patch I applied is below, and
    you can find the full tarchive at the usual place,
        http://www.acme.com/software/thttpd/
    I was hoping to delay this release until I solve www.acme.com's current
    bandwidth problems, but this is urgent enough to require an immediate fix.
    
    By the way, this:
    
    >According to Netcraft, it's used
    >on 1.82% of all HTTP servers, behind only Apache, IIS, Enterprise, and
    >Rapidsite.
    
    is somewhat of an overstatement.  There are actually only a hundred or
    so sites running thttpd.  One of them is Demon Internet, a British
    company which serves over 100,000 domains on a single SGI box running
    their modified version of thttpd.
    ---
    Jef
    
             Jef Poskanzer  jefat_private  http://www.acme.com/jef/
    
    *** tdate_parse.c       1999/09/15 16:09:36     1.1
    --- tdate_parse.c       1999/11/10 01:16:39
    ***************
    *** 211,217 ****
          */
    
          /* DD-mth-YY HH:MM:SS GMT */
    !     if ( sscanf( cp, "%d-%[a-zA-Z]-%d %d:%d:%d GMT",
                    &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                    &tm_sec ) == 6 &&
                scan_mon( str_mon, &tm_mon ) )
    --- 211,217 ----
          */
    
          /* DD-mth-YY HH:MM:SS GMT */
    !     if ( sscanf( cp, "%d-%400[a-zA-Z]-%d %d:%d:%d GMT",
                    &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                    &tm_sec ) == 6 &&
                scan_mon( str_mon, &tm_mon ) )
    ***************
    *** 225,231 ****
            }
    
          /* DD mth YY HH:MM:SS GMT */
    !     else if ( sscanf( cp, "%d %[a-zA-Z] %d %d:%d:%d GMT",
                    &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                    &tm_sec) == 6 &&
                scan_mon( str_mon, &tm_mon ) )
    --- 225,231 ----
            }
    
          /* DD mth YY HH:MM:SS GMT */
    !     else if ( sscanf( cp, "%d %400[a-zA-Z] %d %d:%d:%d GMT",
                    &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                    &tm_sec) == 6 &&
                scan_mon( str_mon, &tm_mon ) )
    ***************
    *** 239,245 ****
            }
    
          /* HH:MM:SS GMT DD-mth-YY */
    !     else if ( sscanf( cp, "%d:%d:%d GMT %d-%[a-zA-Z]-%d",
                    &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
                    &tm_year ) == 6 &&
                scan_mon( str_mon, &tm_mon ) )
    --- 239,245 ----
            }
    
          /* HH:MM:SS GMT DD-mth-YY */
    !     else if ( sscanf( cp, "%d:%d:%d GMT %d-%400[a-zA-Z]-%d",
                    &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
                    &tm_year ) == 6 &&
                scan_mon( str_mon, &tm_mon ) )
    ***************
    *** 253,259 ****
            }
    
          /* HH:MM:SS GMT DD mth YY */
    !     else if ( sscanf( cp, "%d:%d:%d GMT %d %[a-zA-Z] %d",
                    &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
                    &tm_year ) == 6 &&
                scan_mon( str_mon, &tm_mon ) )
    --- 253,259 ----
            }
    
          /* HH:MM:SS GMT DD mth YY */
    !     else if ( sscanf( cp, "%d:%d:%d GMT %d %400[a-zA-Z] %d",
                    &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
                    &tm_year ) == 6 &&
                scan_mon( str_mon, &tm_mon ) )
    ***************
    *** 267,273 ****
            }
    
          /* wdy, DD-mth-YY HH:MM:SS GMT */
    !     else if ( sscanf( cp, "%[a-zA-Z], %d-%[a-zA-Z]-%d %d:%d:%d GMT",
                    str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                    &tm_sec ) == 7 &&
                scan_wday( str_wday, &tm_wday ) &&
    --- 267,273 ----
            }
    
          /* wdy, DD-mth-YY HH:MM:SS GMT */
    !     else if ( sscanf( cp, "%400[a-zA-Z], %d-%400[a-zA-Z]-%d %d:%d:%d
    GMT",
                    str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                    &tm_sec ) == 7 &&
                scan_wday( str_wday, &tm_wday ) &&
    ***************
    *** 283,289 ****
            }
    
          /* wdy, DD mth YY HH:MM:SS GMT */
    !     else if ( sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d:%d GMT",
                    str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                    &tm_sec ) == 7 &&
                scan_wday( str_wday, &tm_wday ) &&
    --- 283,289 ----
            }
    
          /* wdy, DD mth YY HH:MM:SS GMT */
    !     else if ( sscanf( cp, "%400[a-zA-Z], %d %400[a-zA-Z] %d %d:%d:%d
    GMT",
                    str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                    &tm_sec ) == 7 &&
                scan_wday( str_wday, &tm_wday ) &&
    ***************
    *** 299,305 ****
            }
    
          /* wdy mth DD HH:MM:SS GMT YY */
    !     else if ( sscanf( cp, "%[a-zA-Z] %[a-zA-Z] %d %d:%d:%d GMT %d",
                    str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec,
                    &tm_year ) == 7 &&
                scan_wday( str_wday, &tm_wday ) &&
    --- 299,305 ----
            }
    
          /* wdy mth DD HH:MM:SS GMT YY */
    !     else if ( sscanf( cp, "%400[a-zA-Z] %400[a-zA-Z] %d %d:%d:%d GMT %d",
                    str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec,
                    &tm_year ) == 7 &&
                scan_wday( str_wday, &tm_wday ) &&
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 15:12:13 PDT