Testing HTTP methods

A good place to start with testing web servers is at the beginning of the HTTP request, by enumerating the HTTP methods. The HTTP method is sent by the client and indicates to the web server the type of action that the client is expecting.

As specified in RFC 7231, all web servers must support GET and HEAD methods, and all other methods are optional. As there are a lot of common methods beyond the initial GET and HEAD methods, this makes it a good place to focus testing on, as each server will be written to handle requests and send responses in a different way.

An interesting HTTP method to look out for is TRACE, as its availability leads to Cross Site Tracing (XST). TRACE is a loop-back test and basically echoes the request it receives back to the user. This means it can be used for Cross-site scripting attacks (called in this case Cross Site Tracing). To do this, the attacker gets a victim to send a TRACE request, with a JavaScript payload in the body, which would then get executed locally when returned. Modern browsers now have defenses built-in to protect the user from these attacks by blocking TRACE requests made through JavaScript, so this technique now only works against old browsers or when leveraging other technologies such as Java or Flash.

How to do it…

In this recipe, we are going to connect to the target web server and attempt to enumerate the various HTTP methods available. We shall also be looking for the presence of the TRACE method and highlighting it, if available:

import requests

verbs = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE', 'TEST']
for verb in verbs:
    req = requests.request(verb, 'http://packtpub.com')
    print verb, req.status_code, req.reason
    if verb == 'TRACE' and 'TRACE / HTTP/1.1' in req.text:
      print 'Possible Cross Site Tracing vulnerability found'

How it works…

The first line imports the requests library; this will be used a lot in this section:

import requests

The next line creates an array of the HTTP methods we are going to send. Notice the standard ones—GET, POST, PUT, HEAD, DELETE, and OPTIONS—followed by a non-standard TEST method. This has been added to check how the server handles input that it's not expecting. Some web frameworks treat a non-standard verb as a GET request and respond accordingly. This can be a good way to bypass firewalls, as they may have a strict list of methods to match against and not process requests from unexpected methods:

verbs = ['GET', 'POST', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE', 'CONNECT', 'TEST']

Next is the main loop of the script. This part sends the HTTP packet; in this case, to the target http://packtpub.com web server. It prints out the method and the response status code and reason:

for verb in verbs:
    req = requests.request(verb, 'http://packtpub.com')
    print verb, req.status_code, req.reason

Finally, there is a section of code to specifically test for XST:

if verb == 'TRACE' and 'TRACE / HTTP/1.1' in req.text:
      print 'Possible Cross Site Tracing vulnerability found'

This code checks the server response when sending a TRACE call, checking to see if the response contains the request text.

Running the script gives the following output:

How it works…

Here, we can see that the web server is correctly handling the first five requests, returning a 200 OK response for all these methods. The TRACE response returns 405 Not Allowed, showing that this has been explicitly denied by the web server. One interesting thing with the target server here is that it returns a 200 OK response for the TEST method. This means that the server is processing the TEST request as a different method; for example, it's treating it as a GET request. As earlier mentioned, this makes a good way to bypass some firewalls, as they may not process the unexpected TEST method.

There's more…

In this recipe, we've shown how to test a target web server for the XST vulnerability and test how it handles various HTTP methods. This script could be extended further by expanding the example HTTP method array to include various other valid and invalid data values; perhaps you could try sending Unicode data to test how the web server handles unexpected character sets or send a very long HTTP method and to test for buffer overflows in custom web servers. A good resource for this data is to check back to the fuzzing scripts in Chapter 3, Vulnerability Identification, for example, using payloads from Mozilla's FuzzDB.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.79.20