Tuesday, January 28, 2014

Configuring a bridged promisc interface in Security Onion

A few months ago I configured an all in one (server and sensor) Security Onion VM on my ESXi box.  It took a while, but I finally found a good box that I could use for a physical sensor.   I bought this Barracuda ethernet TAP back around 2007-9, and while it worked great, after I moved to my house, it has literally been collecting dust in my basement for years.  Lucky for me, it still works! 

This is a non aggregating TAP, which means I have two "output" cables coming from the TAP to my IDS.   On the physical server, I installed Security Onion as a sensor only, and the TAP interfaces ended up being eth0 and eth2 (eth1 is the mgmt. interface).

I quickly realized that I only knew how to bond two interfaces together on CentOS/RedHat.  It took a few hours of googling and trial and error, but I finally got eth0 and eth2 bonded/bridged together. 

Aside from the Security Onion install, and configuring the interfaces (as shows below), the only other thing I needed to do was to install the bridge-utils package.  Until I did that, even though my interfaces file was configured properly, the br0 interface would not come up.  

I don't want to lose the config that ended up working, so here is the final config for Ubuntu/Xubuntu:


seth@sensor-dell:~$ uname -a
Linux sensor-dell 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 17:37:58 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux


seth@sensor-dell:~$ history | grep bridge-utils
   67  sudo apt-get install bridge-utils


seth@sensor-dell:~$ cat /etc/network/interfaces
# This configuration was created by the Security Onion setup script.  The original network
# interface configuration file was backed up to /etc/networking/interfaces.bak.

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# loopback network interface
auto lo
iface lo inet loopback

# Management network interface
auto eth1
iface eth1 inet static
  address 192.168.0.202
  gateway 192.168.0.1
  netmask 255.255.255.0
  dns-nameservers 8.8.8.8 8.8.4.4

auto eth0
iface eth0 inet manual
  up ip link set eth0 promisc on arp off up
  down ip link set eth0 promisc off down
  post-up ethtool -G eth0 rx ; for i in rx tx sg tso ufo gso gro lro; do ethtool -K eth0 $i off; done
  post-up echo 1 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6

auto eth2
iface eth2 inet manual
  up ip link set eth2 promisc on arp off up
  down ip link set eth2 promisc off down
  post-up ethtool -G eth2 rx ; for i in rx tx sg tso ufo gso gro lro; do ethtool -K eth2 $i off; done
  post-up echo 1 > /proc/sys/net/ipv6/conf/eth2/disable_ipv6

auto br0
iface br0 inet manual
  bridge_ports eth0 eth2
  up ip link set br0 promisc on arp off up
  down ip link set br0 promisc off down
  post-up ethtool -G br0 rx ; for i in rx tx sg tso ufo gso gro lro; do ethtool -K br0 $i off; done
  post-up echo 1 > /proc/sys/net/ipv6/conf/br0/disable_ipv6

Tuesday, January 14, 2014

Writing and Debugging BurpSuite Extensions in Python

When I first started with Burp extensions over a year ago, I used the hiccup framework to develop my plugins.   Hiccup had a way of monitoring my custom "plugin" for changes each time it performed an action.  As a result, it appeared that any changes I made to a plugin took effect in Burp instantly.   

Well, when Burp Extender API 1.5 came out, while it greatly improved what could be done with Burp extensions, it also broke projects like Hiccup.   Not wanting to be dependent on another non PortSwigger API, I decided to spend whatever time I needed to learn how to interface with the Burp API directly.   

As I began, one frustrating thing I realized was that I had to reload my extension each time I made even the smallest change.   This process takes some time, and because I am using Jython, it sucks some memory each time the extension is reloaded.  I finally gave in and asked on the Burp Suite forum if anyone had a better way of writing and/or debugging Burp Extensions in Python.  

It turns out someone did. elespike figured out that if you move your new functionality to a second file, you could import it once, and then reload it as frequently as you like.  His guidance is in the thread listed above, but I thought it would be helpful to blog my entire solution.  Also, after he pointed me in the direction of the reload, I went back to look at hiccup, and that is in fact what what chair6 was doing to make hiccup reload the plugin.  

And it is WAY BETTER.  It saves a ton of time. 

So, with that intro, I wanted to document what I did. 

Step 1

In Burp >> Extensions >> Options, I set my "Folder for loading modules (optional)" to c:\python\lib


Step 2

I then created my Burp Extension file. Where I would normally include all of my extension logic in this file, I instead moved all of my custom functions to another file (shown in step 3):

from burp import IBurpExtender
from burp import IContextMenuFactory
from burp import IExtensionHelpers
from javax.swing import JMenuItem
from java.awt.event import ActionListener
from java.awt.event import ActionEvent
from java.awt.event import KeyEvent
import traceback
# Burp is configured to look for python modules in c:\python27\lib. 
# If the following file exists in that directory, it will be loaded
import UniqueParamValues

class BurpExtender(IBurpExtender, IContextMenuFactory, ActionListener):
    def __init__(self):
 self.menuItem = JMenuItem('Print Unique Parameter Values')
 self.menuItem.addActionListener(self)    

    def actionPerformed(self, actionEvent):
 print "*" * 60
 # Here is the reload. You can place this anywhere you wantm but you will 
 # most likely want to place this within an action (request recieved, menu
 # item clicked, scanner started, etc).  
 reload(UniqueParamValues)
 # This try statement, and the traceback included in the except, are what
 # allowed me to finally get the trace information I needed to debug my 
 # issues.  I highly recommned including these when developing Burp 
 # Extensions
 try:
     UniqueParamValues.getUniqueParams(self)
 except:
     tb = traceback.format_exc()
     print tb
 
    # implement IBurpExtender
    def registerExtenderCallbacks(self, callbacks):
    
        # keep a reference to our callbacks object (Burp Extensibility Feature)
        self._callbacks = callbacks   
        self._helpers = callbacks.getHelpers()
        # set our extension name
        callbacks.setExtensionName("Unique Parameter Values")
 callbacks.registerContextMenuFactory(self)
        return
    
    def createMenuItems(self, ctxMenuInvocation):
 self.ctxMenuInvocation = ctxMenuInvocation
 return [self.menuItem]
 
      
Step 3

And finally, I created a file that would contain the customized functions needed in my extension (UniqueParamValues.py), and dropped that file in c:\python\lib directory. 


def getUniqueParams(self):
    # Initialize list
    parameter_array = []
    parameter_string_array = []
    messages = self.ctxMenuInvocation.getSelectedMessages()
    # This for loop iterates through all of the selected messages pulling out 
    # everything Burp considers a parameter (even cookies), and putting all of 
    # the parameters in an array
    for m in messages: 
 request_byte_array=m.getRequest()
 requestInfo = self._helpers.analyzeRequest(request_byte_array)
 parameters = requestInfo.getParameters()
 parameter_array = parameter_array + parameters

    # This for loop iterates through each paramter and creates a string with the 
    # paramname=paramvalue, so that they can be compared and sorted later.  
    for p in parameter_array:
 param_string = p.getName() + "=" + p.getValue()
 #print "Param String:", param_string
 parameter_string_array.append(param_string)
    
    # After the for loop is finished, then uniquify and sort the parameters -- The main purpose of the extension
    unique_parameters = sorted(uniqify(self,parameter_string_array))
    
    print "************************************************************"
    print "******************** Unique Paramters **********************"
    print "************************************************************"
    print
    print "Number of Parameters:", len(parameter_string_array)
    print "Number of Unique Parameters :", len(unique_parameters)
    print 
    
    param_dict = {}
    for unique_param in unique_parameters:
 #print "Param: %s" % (unique_param))
 param_name = unique_param.split("=")[0]
 param_value = unique_param.split("=")[1]
  #This if statement creates a dictionary, but unlike a normal dictionary, the value of each key is a list.
  #This is so that I can use the append function.  
  #The key is the parameter name
  #The value is a list of all of unique the seen parameter values
 if not param_name in param_dict:
     param_dict[param_name] = []
 param_dict[param_name].append(param_value)
        
    for key, value in param_dict.iteritems():
 print(len(key) * "-" + "----")
 print("| %s |" % (key))
 print (len(key) * "-" + "----")            
 for item in value:
     print(item)
    print("\n\n\n\n") 

def uniqify(self, parameter_string_array):
    # not order preserving
    set = {}
    map(set.__setitem__, parameter_string_array, [])
    return set.keys()   
As you can see in the snippet above, this file does not require any additional imports. You just define the definitions, receive the arguments, process, and then optionally return the result to the caller. This extension is far from complete, and is the first python I have written in a year, so please don't judge me :).

Regardless, I wanted to put it up here as an example on how to quickly develop and debug a Burp Extension with Python.

If you are curious, at this point, the extension spits out a table in stdout that looks like this:

************************************************************
******************** Unique Paramters **********************
************************************************************


Number of Parameters: 40
Number of Unique Parameters: 12

--------------
| csrf_token |
--------------
null
------------
| board_id |
------------
2
----------
| __utmb |
----------
194279098.1.10.1389713652
----------
| __utmc |
----------
194279098
----------
| __utmz |
----------
194279098.1389713652.1.1.utmcsr
----------
| __utma |
----------
194279098.364032451.1389713652.1389713652.1389713652.1
--------
| page |
--------
2
3
4
5
6


My goal is to eventually create a window in Burp that will contain this information, as well as counts for each parameter value. 

Monday, January 13, 2014

Re-launch - A focus on Web Application Pen Testing, Burp Extensions, etc

It has been quite a while since my last blog post here. Not that I have ever really blogged much, but in 2010, I officially switched from a world filled with enterprise firewalls and intrusion detection systems, to one filled with Web Applications (and other types of applications).

On one hand, for someone who likes to learn, Web Application Penenetration Testing is perfect: There are so many languages, frameworks, best practices, and common mistakes to understand, that as a tester, you will never run out of things to learn. Of course, that also means that you will never come close to being able to learning it all. Left unmanaged, this can be a source of frustration and despair.

The main point of this blog re-launch, is that it has been far too long since I have written any code. I'd like to document the mistakes I make, and the lessons I am bound to learn, as I jump back into things. 

I mainly test applications from a Windows OS, so those thousands of hours of BASH scripting experience from my past are just sitting in my brain as memories. I was just starting to become functional in Python also, when I essentially abandoned that as well. I have found a few things to automate over the last few years, but to be honest, most times I think of something related to application testing that I can automate in Python, I realize that Portswigger's Burp Suite already does that. I can't tell you how many times this has happened.

Of course, the problem with relying on a tool to do something for you is that if you need it to do something slightly differently, you are stuck. This is where the Burp Extension API comes into play.

Recently, I have done a number of assessments on custom applications (Mostly thick clients written in Java, C#, etc), that use web services to communicate with the server. While these applications use HTTP(s), and can be intercepted with Burp, their implementations are unique and it becomes difficult to analyze the requests with the default Burp functionality.

This is of course, the perfect opportunity for me to extend Burp Suite to make it do things that only I need it to do, while at the same time, an opportunity for me to dust off my scripting/programming skills.

The next few posts at least, will contain Burp Extension related info.  They will hopefully show me improving from noob to moderatly functional.  We'll see...