Full Disclosure mailing list archives

PR0V1NG RFP WR0NG


From: full-disclosure () lists netsys com (Rain Forest Puppy)
Date: Wed, 28 Aug 2002 03:00:10 +0000 (GMT)

auto461723_at_hushmail.com wrote:

Our esteemed web security expert doesn't know how to play around with
Content-Length properly.

Whoa, whoa, whoa.  First off, I'm not a 'web security expert'.  If others
have attributed that title to me, then they've done it by their own accord
and not by my choice.  I've never proclaimed myself as an expert at
anything.  That's so far from the truth.

As for the Content-Length thing, this discussion is really stupid, but I'm
willing to go through the motions with you.  And I'm willing to meet you
half-way on this.

And in our cgi-bin directory we create a rudimentary script that reads
only POST data and parses it in a manner consistent with almost every
Perl script on the Net...

Agree that the presented Perl code has issues, and I agree that it's very
predominant.  Moving on...

But there is nothing stopping us from sending in more data after the
23 characters -- data that WILL be fed to the sub-application, which
you say can't happen.

Alright, alright.  This where the 'meet you half-way' comes into play.

I should have never said 'never', or at least eluded to an absolute.
You've obviously found an example.  But the above statement you made is
also wrong.

In my defense, thttpd is 'different'.  Arguably it's broken in this
respect, but I'm not willing to pass judgement on it.  The protocol specs
say one thing, but we all know that specs don't matter--it's the
implementation that counts.

So, I've taken a sample perl test script which reads:

        #!/usr/bin/perl
        $|++;

        print "Content-type: text/plain\r\n\r\n";
        print "OK\n";
        while( read( STDIN, $buffer, 1024 )){
                print $buffer;
        }
        print "\n";


This script, for those of you who aren't willing to sink low enough to
learn perl, will just read as much input from STDIN as provided,
regardless of the Content-Length.

Next, I created a generic request into the file 'x':

        POST /cgi-bin/test.pl HTTP/1.0
        Content-Length: 5

        abcdefghijklmnop

(Note: the '/cgi-bin/test.pl' was modified to point to the actual location
       on my various test servers, below)

Now, if things go the way they should, when making a request to the
script, the server should only place/give the first five bytes ('abcde')
to the CGI's STDIN, since that's all we've delcared in the Content-Length
header.

First, we have thttpd-2.22beta4:

----------------------------------------------------------

[root@cide cgi]# cat x | nc localhost 81
HTTP/1.0 200 OK
Content-type: text/plain

OK
abcdefghijklmnop

----------------------------------------------------------

Yuck, it obviously passed more than the first five bytes.  Hence I am
wrong in this case, and you've already proven this in your post.

Next, let's look at what iPlanet 4.1 does:

----------------------------------------------------------

[root@cide cgi]# cat x | nc nammu.rfp.labs 80
HTTP/1.1 200 OK
Server: Netscape-Enterprise/4.1
Date: Wed, 28 Aug 2002 00:41:19 GMT
Content-type: text/plain
Content-length: 9
Connection: close

OK
abcde

----------------------------------------------------------

Wow, it truncates it, just as it should.  And next, let's check for
Apache-1.3.26:

----------------------------------------------------------

[root@cide cgi]# cat x | nc cide.rfp.labs 80
HTTP/1.1 200 OK
Date: Wed, 28 Aug 2002 01:13:44 GMT
Connection: close
Content-Type: text/plain

OK
abcde

----------------------------------------------------------

Apache truncates it as well.  Huh.  But hey, let's really get silly here,
shall we?  Here's what IIS 5.0 with ActiveState ISAPI handler (*.plx)
does:

----------------------------------------------------------

[root@cide cgi]# cat x | nc aeon.rfp.labs 80
HTTP/1.0 200 OK
Date: Wed, 28 Aug 2002 01:46:39 GMT
Server: Microsoft-IIS/5.0
Content-type: text/plain

OK
abcde

----------------------------------------------------------

Wow!  Even IIS seems to 'get it'.  But that could just be an ActiveState
glitch...what about ASP?  I drafted the following test ASP script:


        <%
        dim data, flag, count

        Response.Write "OK" + chr(13) + chr(10)

        flag = 1
        count = 1
        While count > 0
                data = Request.BinaryRead( count )
                If count > 0 Then
                        Response.Write data
                End If
        Wend

        Response.Write chr(13) + chr(10)
        %>

This basically does the same thing as the perl one: read in as much info
on STDIN as the server provides.  The result:

----------------------------------------------------------

[root@cide cgi]# cat x | nc aeon.rfp.labs 80
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Wed, 28 Aug 2002 01:23:36 GMT
Connection: Keep-Alive
Content-Length: 11
Content-Type: text/html
Set-Cookie: ASPSESSIONIDGGQQQVNG=NNNLJPACDPMDCHLJBAMCEIFH; path=/
Cache-control: private

OK
abcde

----------------------------------------------------------

Even the ASP handler gets it right, so I would say IIS gets it right.

So, conclusion?  You found a bug in thttpd.  Apache, Netscape, and IIS all
handle the situation correctly.  I based my research on those three
servers.  To take another look at your statement:

But there is nothing stopping us from sending in more data after the
23 characters -- data that WILL be fed to the sub-application, which
you say can't happen.

As we just saw it *WILL NOT* be given to the parent CGI, let alone the
sub-application, in many common webservers.  So your "WILL" is just as
wrong as my "NEVER".

Does the fact that thttpd has a broken CGI implementation mean I'm a farce
and the general statements I made are incorrect?

Well, I'll let everyone else be the judge.

Either way, I'll save you some keystrokes:

I suck. I can't code.  I don't know what I'm talking about.  I'm a washed
out sell out capitalizing on my 10 seconds of fame for writing some crappy
advisories and some shitty perl code.  But because I write perl code
doesn't mean I can code.  Because I can't code.  And I have a small penis.

Are we done?
- rfp





Current thread: