4

During my current security audit test I've stumbled on something I can't possibly comprehend. The behavior exhibits signs of a buffer overflow in the target or in some intermidiate service (HTTP proxy/IDE/IPS/firewall), but I haven't been able to prove it yet, or somehow show it can be exploited.

The service exhibits these 2 pecularities, both related to the first string of the HTTP request (exactly as such, not just an URL length, but the whole 1st string's length, includint HTTP verb (GET,POST, etc) and the HTTP protocol version):

1) The HTTP protocol version, specified at the end of the 1st string of http request, can't be changed (leads to "Protocol version isn't supported" type of error response), BUT it can be omitted - the page will still be served, but without response headers from the server, just plain HTML text.

2) After removal of the HTTP proto version as described above, upon inserting a very long character sequence in this first string, and preserving the URL format intact (like, adding it to some parameter, ?par1=very_long_string), the server responds with the same page as before, but with corrupt HTML - it abruptly ends in the middle of some tag. This behavior happens all the time, and with the exactly defined length of the 1st string in the HTTP request (if I make the request one character less it's ok, one character more - and it's distorted; note, not length of url, but length of the whole 1st string in request!).

The service does not crash after that. Also, you can insert much more lengthy strings into other strings of the HTTP request, it won't trigger anything unusual.

I fail to grasp how the length of HTTP request can affect the integrity of the HTML in the answer, so some good insight could be very helpful.

How should I proceed with this further? I've been thinnkig about exposing this target to fuzzer of sort, trying to force some more unusual behavior out of it, but that seems to be my limit.

Edit1: As Erwan Legrand admitted:

1) is not a peculiarity. You're sending an HTTP/0.9 request (as the original version of HTTP is now called) and getting back an HTTP/0.9 response

But still the peculiar part of it is why the 2) is only triggered while sending only these HTTP/0.9 requests (it doesn't happen if protocol version isn't ommited)

Edit2: Meanwhile, the deadline of aforementioned audit is almost at hand. After a couple days I'll lose access to the system and this mystery will remain unresolved. There is still some time for a couple fuzzer's runs, though. But at least I would love to understand how is it possible that some long string contained in HTTP request can truncate the response. This haunts me. Can somebody shoot a wild guess?

Edit3: I tried to issue queries to urls like http://some_host/some_path?long_string - i.e. while totally ommiting parameter's name at all - it still worked and still exhibited the same peculiar behaviour, as long as "somepath?" part of url was kept intact. In case even a one more character (like, "?") was removed, it just returned nothing at all.

Edit4: There is probably one more thing that could be important and related. As I mentioned, when HTTP/1.1 is specified in the 1st request's string and some excessively long string is introduced in url, server doesn't serve the page (it serves it only in case http version is ommited); it serves "bad request"/"uri too long" errors instead. But only until some another length of request's 1st string is reached (it's slightly greater - around 200 more characters - than aforementioned peculiar "point") - after that it becomes "protocol version not supported" and stays the same despite further increases in length of a string being inserted. What is intresting here is that the server responds with the same error type in case you try to tamper with HTTP/1.1 stanza in any way, while leaving all other segments of 1st request's string intact. And what even more intresting - even in case of so called "HTTP/0.9" (when HTTP/1.x stanza is ommited) it still happens, and exactly when reaching the same length of request's 1st string. It first serves page normally, then it serves it truncated for another ~200 character increments - and then suddenly it resorts to "protocol isn't supported".

In fact, this was the first oddity that ignited my suspicion that buffer overflow can be involved - I thought the HTTP version variable in some stack could be overwritten by url path part of the 1st string. But again, I failed to prove it, despite trying for hours. It still can be just a simple check for some maximum length of the 1st string which returns general error about unknown protocol, of course.

Edit5: As I promissed, I did some additional checks:

  1. HTTP/1.0 instead of HTTP/1.1 - no noticeable difference at all
  2. POST requests - in case HTTP/1.x stanza specified there is no noticeable difference; in case it's ommited you can actually type anything you want instead of http verb (you still have to specify at least one character or requests will be left unanswered by the server) - I even tryied to insert this long payload here, while leaving url part of the 1st request's string intact - it's still producing the very same result, all is matters is the 1st string's overall length, and url correctly specifying some page
  3. As somebody asked about technologies that are in place - all is known it's powered by jboss seam.
  • 2
    1) is not a peculiarity. You're sending an HTTP/0.9 request (as the original version of HTTP is now called) and getting back an HTTP/0.9 response. – Erwan Legrand Jan 27 '15 at 12:00
  • Do you always use the same specific parameter in your query for the very long string, or does it work with any parameter? even a bogus one? – Dillinur Jan 27 '15 at 13:57
  • Erwan Legrand, thanks for your correction, thats intresting. I need to check this out. – tis Jan 27 '15 at 21:15
  • Dillinur, this particular request I discovered first had only one parameter in url. I will try to find some other request which url has 2 or more for additional checks, just to be sure. But it can turn out that parameters by itself have little to do with it. I tried to issue querys to urls like some_host/some_path?long_string - i.e. while totally ommiting parameter's name at all - it still worked and still exhibited the same peculiar behaviour, as long as "somepath?" part of url was kept intact. In case even a one more char (like, "?") was removed, it just returned nothing. – tis Jan 27 '15 at 21:20
  • 2
    It's clear that the server or proxy is handling HTTP 0.9 in a fundamentally different way to HTTP 1.1, so my question is what does 1.0 do? Also, do post requests or anything show any symptoms? – ewanm89 Jan 28 '15 at 1:00
2

This behaviour may be explained by some sort of check performered on the URI or on the GET parameters (php example):

if (check_ok()){
   Do_something
}
else
{
   die();
}
echo rest_of_page();
  • Yes, it can. I mean, the part about the same (for both cases, with HTTP/1.x stanza and without) error response of the server ("proto isn't supported") upon reaching some specific length of request's 1st string. But how can it explain the page's truncation which happens only when HTTP/1.x stanza is ommited, and occurs with slightly shorter length of the 1st request's string? And why only first string is checked, anyway? As I mentioned, much more lengthy strings can be inserted in other parts of a request (into its headers). – tis Jan 27 '15 at 22:04
  • Sorry, I didn't get your point as a whole and can't edit my first comment anymore. But still, it hardly can be the case. The problem is that the page is always abruptly ends in the middle of html tag. And mostly at the specific position in this document (in fact, there are several such positions - i.e. it's not always truncated at the same spot - and all of them are in the middle of some tag) – tis Jan 27 '15 at 22:11
  • For the same string, does it always end in the same place? Is the content of the long value( or part of it) included in the response? – Dinu Jan 28 '15 at 5:15
  • 1
    Can you give details on the Web Server and Programming Language that are used? The content that is displayed is the same as the one in the normal short request? – Dinu Jan 28 '15 at 8:20
  • 1
    It is a black box kind of testing, and servers are actually pretty securely configured, so little is known, especially about this particular one. It's powered by jboss seam, version unknown, thats all. – tis Jan 28 '15 at 21:04
0

If you had access to the server code, then Dinu S's answer would seem to be a good solution. Inlight of your new information, --- your server is a 'blackbox' --- and you suspect the reason is overflow, you can formulate a test for a page's validity. To start with the test could be:

for x in range( max_char_length_of_parameter ):
    request = makeRequest( x )
    r  = getResponseFromServer(  request )

    if isCompleteHTMLTree( r ) and isExpectedLengthOfResponse( r ):
        //pass - page is correct
    else:
        //fail - page is not correct

(Code roughly in Python)

Note:

If boundary checking on input requests isn't handled, then memory overflow (i.e. overwriting other program variable values including their string terminator(s)) is a real issue and can lead to many different kinds of error states, including (in likelihood) the states you describe.

Different programming languages handle overflow avoidance differently (or not at all). If the server is (using?) JBoss, you could take a guess your application is written in Java. IMO, from a blackbox viewpoint, without knowing the compiler behaviour and/or having assembly level compiled code, testing for the plethora of post-overflow states would be unwise.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.