Extending burp proxy

Posted: November 2, 2008 in security
Tags: , , , , , ,

Intercepting proxies and other intercepting software like tamperdata are ideal tools to modify a http request or response when you are taking a peek into the nice world of web application hacking.

Burp suite is not free like webscarab but I like it because the interface is more intuitive. It seems though that wescarab-ng is doing a pretty good job on the interface part. So what is burp suite exactly?

From the burp suite website:

Burp Suite is an integrated platform for attacking web applications. It contains all of the Burp tools with numerous interfaces between them designed to facilitate and speed up the process of attacking an application. All tools share the same robust framework for handling HTTP requests, authentication, downstream proxies, logging, alerting and extensibility.

The best thing? It can be extended!

For the purpose of extending burp proxy (one of the tools from the burp suite) the makers have created the IBurpExtender interface. So what can we accomplish with this interface? A LOT of things…the first time I looked at the interface i felt restricted ( I still do a bit). So after thinking a bit more about it and reading the website several extension ideas popped in my head.

  • logging functionality
  • testing multiple extension
  • e-mail address gathering
  • vulnerability scanner( aka low fruit)
  • gathering all kind of html/script comments

Now that’s a lot of extra functionality to implement with the IBurpExtender interface. The logging one is only usefull if it’s different then the logging functionality burp suite already has. I started out with the logging functionality which basically is the same as the one that burp suite already has, except mine only logs burp proxy traffic. So to practice in extending burp suite I coded a little logger.

Here is the code for the logger it’s just a quick draft, I am planning to expanding it so it actually is usefull and greppable.

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 *
 * @author DiabloHorn
 */
public class BurpExtender implements IBurpExtender {
    /**
     * Causes burp proxy to follow the current interception rules to determine
     * the appropriate action to take for the message.
     */
    public final static int ACTION_FOLLOW_RULES = 0;
    /**
     * Causes burp proxy to present the message to the user for manual
     * review or modification.
     */
    public final static int ACTION_DO_INTERCEPT = 1;
    /**
     * Causes burp proxy to forward the message to the remote server.
     */
    public final static int ACTION_DONT_INTERCEPT = 2;
    /**
     * Causes burp proxy to drop the message and close the client connection.
     */
    public final static int ACTION_DROP = 3;

    private static String LOG_PATH;
    private static String LOG_NAME = "BurpLogFile_#.txt";
    private FileWriter fstream;
    private BufferedWriter out;
    public static final String DATE_FORMAT_NOW = "yyyyMMdd_HHmm";

    /**
     * Creates a new instance of BurpExtender
     */
    public BurpExtender() {
        System.out.println("BurpLogExtender Loaded");
        String mydir = System.getProperty ("user.dir");
        LOG_PATH = mydir.concat(File.separator).concat(LOG_NAME.replace("#",getTimeStamp()));
        System.out.println("LOG_PATH " + LOG_PATH);
        openFile();
    }

    private String getTimeStamp(){
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
        return sdf.format(cal.getTime());
    }

    private void openFile(){
        try {
            fstream = new FileWriter(LOG_PATH,true);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        out = new BufferedWriter(fstream);
    }

    private void writeFile(String data){
        try {
            out.write(data);
            out.write("\r\n");
            out.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void writeFile(int numData){
        writeFile(Integer.toString(numData));
    }

    private void writeFile(int[] numAData){
        switch(numAData[0]){
            case ACTION_FOLLOW_RULES:
                writeFile("ACTION_FOLLOW_RULES");
                break;
            case ACTION_DO_INTERCEPT:
                writeFile("ACTION_DO_INTERCEPT");
                break;
            case ACTION_DONT_INTERCEPT:
                writeFile("ACTION_DONT_INTERCEPT");
                break;
            case ACTION_DROP:
                writeFile("ACTION_DROP");
                break;
        }
    }

    private void writeFile(boolean bData){
        writeFile(Boolean.toString(bData));
    }

    private void writeFile(byte[] btData){
        writeFile(new String(btData));
    }

    public byte[] processProxyMessage(int messageReference, boolean messageIsRequest, String remoteHost, int remotePort, boolean serviceIsHttps, String httpMethod, String url, String resourceType, String statusCode, String responseContentType, byte[] message, int[] action) {
        writeFile("messageReference: " + messageReference);
        writeFile("messageIsRequest: " + messageIsRequest);
        writeFile("remoteHost: " + remoteHost);
        writeFile("remotePort: " + remotePort);
        writeFile("serviceIsHttps: " + serviceIsHttps);
        writeFile("httpMethod: " + httpMethod);
        writeFile("url: " + url);
        writeFile("resourceType: " + resourceType);
        writeFile("statusCode: " + statusCode);
        writeFile("responseContentType: " + responseContentType);
        writeFile("message: ");
        writeFile(message);
        writeFile("action: ");
        writeFile(action);
        writeFile("[***END***]");
        return message;
    }

    public void applicationClosing() {
        try {
            out.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        try {
            out.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        try {
            fstream.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void registerHttpRequestMethod(Method makeHttpRequestMethod, Object makeHttpRequestObject) {
        //for the moment beeing we don't use this
    }

    public void setCommandLineArgs(String[] args) {
        //for the moment beeing we don't use this
    }

}

When you compile that and package it into a jar, you need to modify the burp startup command so that it will actually be loaded by burp.
on my machine (win32) I changed the .bat to the following:

java -classpath burpsuite_v1.1.jar;E:\Projects\BurpLogExtender\dist\BurpLogExtender.jar burp.StartBurp

Now if all went well your burp suite alert tab could/should like this:

Burp Suite alert tab

Burp Suite alert tab

This is all actually…the IBurpExtender interface is pretty self explanatory. I’m working on  a plugin for “testing multiple extension” at the moment. All it does is when the proxy sees a URL which ends with for example .php or .asp it tries to request .php.bak or .asp.old etc. A lot of developers edit files or just copy complete developers folder structures on/to the server which is really bad habit.

Anyways I’m off for some sleep, I’ll post more burp suite extensions if/when I make/update them. For the moment beeing the extension bruter is still a alpha version.

Advertisements
Comments
  1. jay says:

    The error turned out to be in the documentation. It says the new interface looks for extensions in the package “burp”. But, it doesn’t. It still works like in v1.1 where the default package is used. As soon as I removed “package burp;” from the source files, the extension started up. Thanks for your help, diablohorn

  2. diablohorn says:

    Make sure your extension/class is named BurpExtender and that it resides inside the default package. If you start it inside the burp classpath it should be seen.

  3. jay says:

    Have you tried this with burp 1.2? for the life of me I cannot get the code loaded up.burp just doesnt seem to “see” the extension. i’ve double-checked the path and cant figure out what the error could be. any help would be appreciated.

  4. sefis says:

    Thanks for the example, worked great for me.

    There are a few breaking changes in v1.2 regarding extensions, read the burp release notes if you can’t get it working =)

  5. diablohorn says:

    Sorry for this very late reply…like you will prolly read in my latest blog entry I’ve beek kinda lazy latley and well…just busy. My blog doesn’t allow me to upload the jar file afaik. If you really can’t get it to work I can always post a step by step tutorial on how to do it, with screenshots.

    The portswigger people are really friendly so you will have no problems in communicating with them to solve the problem. Hope you solve it. Good luck.

  6. spinbad says:

    One more time

    I tried this with burp 1.1 and didn’t have any problems. It seems that there is a mistake in the 1.2 version – I will ask the guys from portswigger.net directly.

    One more time, thank you…

  7. spinbad says:

    I will try it during the weekend
    Could you please send me your jar file or upload it to your blog (I think this would make it quite easy for me…)

    Thanky you

  8. diablohorn says:

    Well the version should not mather. I used netbeans and just created a normal project. Then just package/build it and it should generate the jar file.

    The main problem to get it working is the path, just make sure your path is correct and that your main class is called BurpExtender.

    Let me know if this helps you out.

  9. spinbad says:

    Hi

    Do you have any expirience with the version 1.1? I tried to implement a modul, however with no success.

    The reason might be an error in the way I created the jar file? Can you tell me how you did that?

    Kind regards

    spinbad

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s