Archive for the ‘http’ Category

Burp suite tip / tutorial: renaming tabs

Saturday, June 29th, 2013

This will be a quick and simple tip that you may not have been aware of, you can rename tabs within Burp. A friend of mine who works out of Raleigh turned me onto this. I find new sometimes obvious and hidden features in Burp all the time and this is one of them.

I find this feature handy especially in a large application as I can easily keep track of what I’m testing.  I use the tab renaming on the Repeater and Intruder functionality. In order to rename a tab simply double click the tab which will allow you to edit the tab.

Repeater before

Repeater after

Intruder before

Intruder after

Hope this simple tip helps you perform better application pen testing.

Burp suite tutorial / tip: using intercept to locate automated scanner findings

Saturday, February 23rd, 2013

So the problem I have in my job and maybe others do as well is that when assessing a web application for vulnerabilities you want to throw automated tools at it first to get the low hanging fruit. So you get the results back and you have some good findings but you’re not exactly sure where that finding resides inside the application. Meaning first click here, then here, then here, and modify parameter X. It’s not crucial to know this because with burp or any decent web proxy we can replay that request to retrieve and prove the vulnerable results but when dealing with laymen and even developers you have to hand hold them through the exploitation process via the browser as much as possible hence the need to know where in the application the vulnerability exists.

In big applications simply knowing a what GET or POST request is vulnerable may not tell you where the vulnerability lies. Let’s say the scanner reports back that http://example.com/xskw/requestID?=blah is vulnerable, well this is a generic URL without much context so it’s not obvious where you would have to browse to stumble upon that request. It’s even worse for POST requests because going directly to the URL without the parameters can produce errors within the application.

Let’s walk through an example of using the burp intercept feature to find where scanner results are located. I’ll be using an intentionally vulnerable web application named Peruggia found within the owaspbwa project which is a great project to learn web app testing. So I ran the active scan against peruggia and got the following results.

I’m going to focus on the highlighted cross site scripting vulnerability in the screen shot above. I picked this request for a number of reasons but first let’s take a look the details of the request below.

Here we see it’s a POST request and I wanted to focus on a POST request because some of the challenges faced with these requests. In the top third tab we see the response was redirected which means we’ll get a 302 status code. If you were to copy and paste the URL into the browser and make that request you’ll be redirected to the home page. This is the nature of POST requests we can’t just put the URL into the address bar and be take to that location. Because of this it can be hard to determine where in the application the vulnerability exists. Especially for XSS (cross site scripting) vulnerabilities I like to obtain screen shots of the alert box to prove to the customer that I was able to exploit the vulnerability. With a GET request this is easier but POST requests add a level of difficulty.

Let’s walk through an example to understand the challenges. I’ll be starting out on the about page of the Peruggia application. Next I’ll paste the URL from the XSS finding into the address bar.

After I enter this request I get redirected to the home page.

This is also reflected in burp where we see the 302 redirect status code that sends us back to the home page.

So the challenge is to find that “comment” parameter that burp flagged as vulnerable but without a simple GET request this can be difficult. I didn’t pick the greatest example because the “comment” parameter shouldn’t be that hard to find in this application because it’s fairly small and the parameter is actually providing some context, adding a comment, which doesn’t always happen. So for this example let’s ignore the big comment box on the home page and pretend we didn’t see that.

We’ll now set up a rule inside the proxy intercept to alert us when we stumble across the vulnerable “comment” parameter. Let me explain the term stumble for a second. When I get a result back from a scanner and I’m not sure where it’s located inside the application I’ll typically start walking the application and monitor my proxy history to see if that parameter was passed within a request. This can be a pain in the butt so setting up a proxy intercept rule can help automate the process. The rule is somewhat counter intuitive because we’ll leave the intercept on the entire time and let it catch when it sees our parameter. In this case we’ll disable the default file extension match rule and add our new rule to look for the parameter in question. Below is the rule I setup to catch the vulnerable parameter “comment”.

Now the next thing is to start browsing / walking the application and the proxy intercept will automatically alert you when you come across the vulnerable parameter. So while walking the application I decide to post a comment on a picture to ensure I’m touching every functionality of the application. My intercept is on with my new rule waiting for it to flag the vulnerable parameter.

After I make this request my proxy starts blinking and alerting me to the fact that I’ve come across the “comment” parameter.

Unfortunately for large applications it may take some time before you stumble upon the proper vulnerable parameter but hopefully this will help you out when trying to pinpoint the location of automated findings. Of course once we’ve found the vulnerable parameter that the automated scanner has found we’ll want to capture a screenshot of the exploit and this case we’ll need to document that we’re abe to execute javascript inside the application. So now I’ll capture that POST request again and insert the classic javascript alert message.

And now the alert message proving to the application owner’s, developer’s, and customer’s that executing javascript is possible.

XSS FTW. Hopefully my little small tip will help you when trying to hunt down where in the application an automated finding resides. Happy bug hunting.

Python script to check for vulnerable printers

Thursday, June 17th, 2010

People often overlook printers when it comes to information security. Truth is that a ton of useful information can be found in printers. Employees will often scan sensitive documents such as social security cards, loan information, birth certificates, etc. I’ve also seen important organizational information on printers such as internal memos between higher up executives. The documents I’ve seen in the past were never meant to be shared but a default printer will more than happily share your sensitive information. Almost any new commercial printer will come with a ton of features to store and retrieve any documentation that flows through the printer (copy, scan, and print jobs). Almost all of these new printers also give you a web interface to retrieve that documentation, an example of a printer’s web interface can be seen here. When I’m performing a penetration test I always go for the web interface of a printer, the web interface is where I can grab all the sensitive information. These printers usually get unboxed and plugged into the network without much configuration from the default state, this means that the web interface is wide open with default usernames and passwords. Usually admin access to these printers will give you more access and it’s this admin access that I check for.

When you’ve only got a limited amount of time during a penetration test you want to get the best bang for your buck so I created a python script that will go and check for default usernames and passwords on certain models of printers. Below is the python script.

import urllib2
import sys

target = open(sys.argv[1])
eachIPinList = target.readlines(); target.close()
output = open(sys.argv[2], 'w')

for string in eachIPinList:
  try:
    print 'Trying ' + string.rstrip()

    theurl = 'http://' + string.rstrip() + '/index.html'
    username = 'root'
    password = ''

    passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
    passman.add_password(None, theurl, username, password)
    authhandler =  urllib2.HTTPBasicAuthHandler(passman)
    opener = urllib2.build_opener(authhandler)
    urllib2.install_opener(opener)
    pagehandle =  urllib2.urlopen(theurl)
    if pagehandle.getcode() == 200:
      output.write(string)
  except:
    pass

Usage:  at the command line type the following

python nameOfScript.py IPlist.txt output.txt

So this script takes two arguments, 1) A list of IP’s you’ll want to test against, 2) Name of an output file where successful attempts are logged. If you’re having troubles running the script read my other post about running a python script. The output.txt will contain a list of IP’s that the script was able to log into. There are three variables that you’ll have to modify for your particular printer model that you are trying to scan for on your network, they are listed below.

theurl = 'http://' + string.rstrip()  + '/index.html'
username = 'root'
password = ''

Username and password variables should be obvious, simply put in the default username and password of the printer on your network. The only thing you’ll have to change in ‘theurl’ variable is the last quoted string. In my case it was ‘/index.html’, in your case it could be ‘/auth/login.html’. Variable ‘theurl’ builds the http request used to log into your printer’s web interface. A full example is below.

http://192.168.1.5/index.html

This script is doing nothing more than trying to log into the web interface of a printer, that’s it. So the script is not limited to printers, it can be used against any web application that takes a username and password. Although this script can be used against any web application there is a limitation.  This script authenticates to the printer using Basic Access Authentication. There are three main ways to authenticate to a web application.

  1. HTTP Basic Access Authentication
  2. HTTP Digest Access Authentication
  3. HTML Form-based Authentication

So this script will not work if your web application (printer in this case) is using the second or third option. How would you know which one your printer or web application is using? Turns out OWASP has a nice write up on how to test which type of authentication your web application is using. Turns out that no one really uses one and two because they are not as secure as HTML Form-based Authentication wrapped inside SSL. Of course some printers use Basic Authentication because they are poorly built. Basic Authentication actually passes your username and password essentially in plaintext, the only way it tries to hide your username and password is by base64 encoding them which is easily transformed back into plaintext. I don’t want to get lost in the weeds to much but just knowing that your printer is using Basic Authentication is bad enough. Even if you set a strong username and password anyone sniffing network traffic would be able to determine your credentials.

I kicked this script over to Dave Huggins who has tons of experience developing Python applications and he quickly improved upon it by adding the functionality of IP ranges instead of a file. His enhancements can be seen below.

def IPRange(octets, func=""):
  if func == "":
    def func():
      pass

  octets = (octets.split('.'))
  ranges = []
  loop = 0
  for octet in octets:
    if octet.find('-') != -1:
      spot = octet.find('-') + 1
      octets[loop] = int(octet[:octet.find('-')])
      ranges.append(int(octet[spot:]) + 1)
    else:
      octets[loop] = int(octet)
      ranges.append(int(octet) + 1)
      loop += 1
  CurrentAddress = ""
  loop = 0
  output = []
  for one in range(octets[0], ranges[0]):
    for two in range(octets[1], ranges[1]):
      for three in range(octets[2], ranges[2]):
        for four in range(octets[3], ranges[3]):
          for item in (one, two, three, four):
            CurrentAddress += str \
                ((one, two, three, four)[loop]) + "."
              loop += 1
          CurrentAddress = CurrentAddress[:-1]
          output.append(func(CurrentAddress))
          CurrentAddress = ""
          loop = 0
  return output

if __name__ == '__main__':
  import os, sys, urllib2

  def defaultPrinter(ipAddress):
    try:
      print 'Trying ' + ipAddress
      theurl = 'http://' + ipAddress + '/indexConf.html'
      username = 'root'
      password = ''

      passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
      passman.add_password(None, theurl, username, password)
      authhandler =  urllib2.HTTPBasicAuthHandler(passman)
      opener = urllib2.build_opener(authhandler)
      urllib2.install_opener(opener)
      pagehandle =  urllib2.urlopen(theurl)
      if pagehandle.getcode() == 200:
        output.write(ipAddress)
    except:
      pass

  output = open(sys.argv[2], 'w')
  IPRange(sys.argv[1], defaultPrinter)

Happy printer hunting.

Webscarab Tutorial Part 3 (fuzzing)

Tuesday, September 25th, 2007

Part 2 covered the neat functionality of session ID analysis within Webscarab. Now we’ll focus on another great function within Webscarab, fuzzing. I define fuzzing as testing the input of an application by trying various parameters that the input may not expect. These parameters don’t have to be random, in my opinion it’s best when you tailor your parameters depending on the application. When fuzzing you typically want to inject “command & control” parameters into the input to find the most serious vulnerability. For example if a web application is expecting a social security number I may inject html parameters such as ” < / > ” to manipulate the look, feel, and operation of a web application. I don’t want to delve a whole lot into fuzzing because there are books out there that talk about this one subject. This tutorial is going to focus on using Webscarab to fuzz web applications and find vulnerabilities. Hopefully by the end of this tutorial you will better understand the technical aspects of fuzzing as oppose to the concept of fuzzing, but more reading on fuzzing web applications may be required.

(more…)

Webscarab Tutorial Part 2 (sessiond ID analysis)

Wednesday, August 29th, 2007

Part 1 of this series focused on the basics of using a HTTP proxy to assess a web application. I encourage people to play around with HTTP proxies with a web application that they use frequently, it’s interesting to see what information is being passed between the client and server. This communication can sometimes include your private information so it’s good to understand how that particular web application is handling your information.

(more…)