AppSec USA 2015: Customizing Burp Suite

Post on 23-Feb-2017

1.813 views 5 download

Transcript of AppSec USA 2015: Customizing Burp Suite

Customizing Burp Suite

Getting the Most out of Burp Extensions

August Detlefsen

• Senior Application Security Consultant• Author

augustd@codemagi.com@codemagihttp://www.codemagi.com/blog

Monika Morrow

• Senior Application Security Consultant@ AppSec Consulting

mmorrow@appsecconsulting.com @fortytwowho

Agenda/Overview

• Extensions• Using the BApp Store• Building Your First Extension• Adding GUI to extensions• Building Scanners• Utilities

Burp Suite

• What is Burp? • What are extensions?– What can I do with them? (use cases)

What Can I Do With Extensions?

• Passive Scanning• Active Scanning• Alter/append requests• Define Insertion Points for Scanner/Intruder• Create new payload types• Automate Authentication• Much, Much More

BApp Store

• What is it? • How do I use it? • A look at some useful extensions– Logger++– WSDL Wizard

BApp Store

Burp Extension Tab

BApp Store

Logger++

List of Active/Inactive Burp Extensions

Logger++ Options

Logger++ View Logs

Logger++ Item Details

Jython Extensions

Burp Extensions Settings

Burp Extensions Settings

One Click Install Jython Extensions

WSDL Wizard Installed

Installed Burp Extensions

WSDL Wizard Usage

WSDL Wizard Results

Limited Examples

• Proprietary code• One-Offs• No process for updating BApp Store

extensions

Loading a Custom Extension

• Java, Python, and Ruby extensions are loaded and managed through a single interface within the Extension tab

Loading a Custom Extension

Loading a Custom Extension

Loading a Custom Extension

Loading a Custom Extension

Loading a Custom Extension

Building Custom Extensions

• Burp Suite Pro v 1.6.x• Current NetBeans IDE (8.0.2)• JDK 8

Starting with a Template

• Find a starter project• Some example projects at

https://portswigger.net/burp/extender/ • Today we’ll start with my NetbeansGUI project

found at https://github.com/monikamorrow/ Burp-Suite-Extension-Examples– Which depends on

https://github.com/augustd/burp-suite-utils

Starting with a Template

• Clone Burp-Suite-Extension-Examples and burp-suite-utils into your working directory

• Open the Burp-Suite-Extension-Examples NetBeans project and expand folders and resolve issues along the way

• Compile the project to resolve remaining issues

Open the NetBeans Project

Problems already! No problem.

Resolve Project Problems

Find the Cloned Project

….and Repeat. Resolved.

Now what!?

Invalid Java Version?

Select Java Version

Resolved!

More Problems?

Compile to Fix!Building jar: C:\Users\mmorrow\Documents\GitHub\Burp-Suite-Extension-Examples\Example4NetBeansGUI\BurpExtender\dist\BurpExtender-combined.jarjar:BUILD SUCCESSFUL (total time: 1 second)

Edit build.xml

<target name="-post-jar"><jar jarfile=

"dist/BurpExtender-combined.jar"><zipfileset src="${dist.jar}" /><zipgroupfileset dir="dist/lib" includes="*.jar”excludes="META-INF/*"/></jar>

</target>

Test!

Let's Write Some Code

• Start new class BurpExtender• Import BurpGUIExtender• Implement BurpGUIExtender's abstract

functions– init()– processSelectedMessage()

BurpExtenderpackage burp;import com.monikamorrow.burp.BurpGUIExtender;

public class BurpExtender extends BurpGUIExtender { ... }

BurpExtenderpublic class BurpExtender extends BurpGUIExtender {

public void init() { mPluginName = "MYPROJECT"; mUsageStatement = "Usage statement for " + mPluginName; }

}

BurpExtenderpublic class BurpExtender extends BurpGUIExtender

protected IHttpRequestResponse processSelectedMessage( IHttpRequestResponse messageInfo, boolean isRequest) { ... return messageInfo; }}

BurpExtender{if(isRequest) { mStdOut.println( "processSelectedMessage triggered for request"); messageInfo.setComment("Request processed");} else { mStdOut.println( "processSelectedMessage triggered for response"); messageInfo.setComment( messageInfo.getComment() + "/Response processed");} return messageInfo;}

What's Available?

• Mix and match– BurpGUIExtender– BurpSuiteTab• ToolsScopeComponent• UrlScopeComponent

– BaseExtender– PassiveScan– ….and more

GUI Components

• Configuration of options• Enable only what you want• Autosave

How to Add?

mTab = new BurpSuiteTab (mPluginName, mCallbacks);mTab.add(toolsScope);mTab.add(urlScope);mTab.add(myJPanel);mCallbacks.customizeUiComponent(mTab);mCallbacks.addSuiteTab(mTab);

How to Get Settings?urlScope.processAllRequests();

toolsScope.isToolSelected(toolFlag);

Passive Scanning• Search responses for problematic values• Built-in passive scans– Credit card numbers– Known passwords– Missing headers

Building a Passive Scanner

Passive Scanning – Room for Improvement• Error Messages• Software Version Numbers

Building a Passive Scanner

Implement the IScannerCheck interfacepublic class PassiveScan implements IScannerCheck {

@Override public List<IScanIssue> doPassiveScan(

IHttpRequestResponse baseRequestResponse) { … }

@Override public List<IScanIssue> doActiveScan(

IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) { … }

@Override public int consolidateDuplicateIssues(

IScanIssue existingIssue, IScanIssue newIssue) { … }

Building a Passive Scanner

Register the extension as a custom scanner@Overrideprotected void initialize() { callbacks.registerScannerCheck(this);}

Building a Passive Scanner

IScannerCheck.doPassiveScan()for (MatchRule rule : rules) {

Matcher matcher = rule.getPattern().matcher(response);

while (matcher.find()) {matches.add(

new ScannerMatch(matcher.start(), matcher.end(), group,

rule));

Building a Passive Scanner

IScannerCheck.doPassiveScan()if (!matches.isEmpty()) {

Collections.sort(matches);

List<int[]> startStop = new ArrayList<int[]>(1);

for (ScannerMatch match : matches) {startStop.add(new int[]{match.getStart(), match.getEnd()

});

Building a Passive Scanner

IScannerCheck.doPassiveScan()return new ScanIssue(

baseRequestResponse.getHttpService(),

helpers.analyzeRequest(baseRequestResponse).getUrl(),

new IHttpRequestResponse[] {callbacks.applyMarkers(

baseRequestResponse, null, startStop)}, issueName, issueDetail, ScanIssueSeverity.MEDIUM, ScanIssueConfidence.FIRM

Building a Passive Scanner

IScannerCheck.consolidateDuplicateIssues()@Overridepublic int consolidateDuplicateIssues(

IScanIssue existingIssue, IScanIssue newIssue) {

if (existingIssue.getIssueDetail().equals(newIssue.getIssueDetail())) {

return -1; //It is a duplicate

} else { return 0; //This is a new issue}

Building a Passive Scanner

Extending from PassiveScan@Overrideprotected void initPassiveScan() {

//set the extension NameextensionName = "Error Message Checks";

//create match rulesaddMatchRule(

new MatchRule(PHP_ON_LINE, 0, "PHP"));addMatchRule(

new MatchRule(PHP_HTML_ON_LINE, 0, "PHP"));…

Building a Passive Scanner

Extending from PassiveScan@Overrideprotected ScanIssue getScanIssue(

IHttpRequestResponse baseRequestResponse, List<ScannerMatch> matches, List<int[]> startStop) {

return new ScanIssue(baseRequestResponse, helpers,callbacks, startStop, getIssueName(), getIssueDetail(matches), ScanIssueSeverity.MEDIUM.getName(), ScanIssueConfidence.FIRM.getName());

Building a Passive Scanner

Active Scanning• Issue requests containing attacks • Look for indication of success in response• Built-In Active Scans– XSS– SQL Injection– Path Traversal– etc

Building an Active Scanner

IScannerCheck.doActiveScan()@Overridepublic List<IScanIssue> doActiveScan(

IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) {

for (MatchRule rule : rules) { // compile a request containing our // injection test in the insertion point byte[] testBytes = rule.getTest(); byte[] checkRequest =

insertionPoint.buildRequest(testBytes);

Building an Active Scanner

IScannerCheck.doActiveScan()// issue the requestIHttpRequestResponse checkRequestResponse =

callbacks.makeHttpRequest( httpService, checkRequest);

//get the responseString response = helpers.bytesToString(

checkRequestResponse.getResponse());

Building an Active Scanner

IScannerCheck.doActiveScan()// get the offsets of the payload // within the request, for in-UI highlightingList<int[]> requestHighlights =

new ArrayList<int[]>(1);requestHighlights.add(

insertionPoint.getPayloadOffsets(testBytes));

Building an Active Scanner

Extending from ActiveScan@Overrideprotected void initActiveScan() { //set the extension Name extensionName = "Server Side Javascript Injection checks"; //create match rules addMatchRule(

new MatchRule("response.end('success')", SUCCESS, 0, "response.end")); addMatchRule(

new MatchRule("1995';return(true);var%20foo='bar", TRUE, 0, "string"));

Building an Active Scanner

Insertion Points • Locations of parameters in request • Contain data the server will act upon

Building an Active Scanner

Defining Insertion Points

Defining Insertion Points

Defining Insertion Points• Implement IScannerInsertionPointProvider– getInsertionPoints()

• Register as an insertion point provider:

callbacks.registerScannerInsertionPointProvider(this)

;

Defining Insertion Points

BurpExtender.getInsertionPoints()@Overridepublic List<IScannerInsertionPoint> getInsertionPoints(

IHttpRequestResponse baseRR) { byte[] request = baseRR.getRequest(); String requestAsString =

new String(request);

GWTParser parser = new GWTParser(); parser.parse(requestAsString);

Defining Insertion Points

BurpExtender.getInsertionPoints()for (int[] offset : insertionPointOffsets) {IScannerInsertionPoint point = helpers.makeScannerInsertionPoint(

"GWT", request, offset[0] - bodyStart, offset[1] - bodyStart);

insertionPoints.add(point);

}return insertionPoints;

Defining Insertion Points

Defining Insertion Points

Viewing Insertion Points• Add menu option to send request to Intruder

• Implement IContextMenuFactory– createMenuItems()

• Register as a menu factorycallbacks.registerContextMenuFactory(this);

Defining Insertion Points

BurpExtender.createMenuItems()@Overridepublic List<JMenuItem> createMenuItems(

IContextMenuInvocation invocation) { //get selected requests from //the invocation IHttpRequestResponse[] ihrrs =

invocation.getSelectedMessages();

Defining Insertion Points

BurpExtender.createMenuItems()//create clickable menu itemJMenuItem item = new JMenuItem(

"Send GWT request(s) to Intruder");item.addActionListener(new MenuItemListener(ihrrs));

//return a Collection of menu itemsList<JMenuItem> menuItems =

new ArrayList<JMenuItem>();menuItems.add(item); return menuItems;

Defining Insertion Points

MenuItemListenerclass MenuItemListener implements ActionListener { private IHttpRequestResponse[] ihrrs; public MenuItemListener(

IHttpRequestResponse[] ihrrs) {this.ihrrs = ihrrs;

} public void actionPerformed(ActionEvent ae) {

sendGWTToIntruder(ihrrs); }}

Defining Insertion Points

BurpExtender.sendGWTToIntruder()public void sendGWTToIntruder(IHttpRequestResponse[] ihrrs) { for (IHttpRequestResponse baseRR : ihrrs) {

IHttpService service = baseRR.getHttpService();

// parse the request (not shown)

if (isGWTRequest) {// Send GWT request to Intrudercallbacks.sendToIntruder(

service.getHost(), service.getPort(),

service.getProtocol().equals("https"), request, insertionPointOffsets);

Defining Insertion Points

BurpExtender.sendGWTToIntruder()

baseRR.setComment("GWT: " +

parser.getServiceMethod() + " " + baseRR.getComment()

);

Defining Insertion Points

Defining Insertion Points

Defining Insertion Points

Modifying Requests• Add custom headers• Add signatures• CSRF tokens

Modifying Requests

Modifying Requests• Implement IHttpListener

processHttpMessage()

• Register as an HTTP Listenercallbacks.registerHttpListener(this);

Modifying Requests

@Overridepublic void processHttpMessage(

int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {

if (messageIsRequest && callbacks.TOOL_SCANNER == toolFlag) {

BurpExtender.processHttpMessage()Modifying a Request

//see if the request contains a CSRF_TOKENbyte[] scannerRequest =

messageInfo.getRequest();String requestString =

helpers.bytesToString(scannerRequest);

Matcher matcher =TOKEN_PATTERN.matcher(requestString);

if (matcher.find()) { getFreshToken();

BurpExtender.processHttpMessage()Modifying a Request

byte[] request = helpers.buildHttpRequest(FORM_URL);

// issue the request and get the responsebyte[] response = callbacks.makeHttpRequest(

DOMAIN_NAME, 443, true, request);

getFreshToken()Modifying a Request

String responseString = helpers.bytesToString(response);

Matcher matcher = TOKEN_INPUT_PATTERN.matcher(responseString)

;

if (matcher.find()) return matcher.group(1);

getFreshToken()Modifying a Request

String token = getFreshToken(); if (token != null) { requestString = matcher.replaceAll(

"name=\"CSRF_TOKEN\" value=\" + token);} messageInfo.setRequest(

requestString.getBytes());

BurpExtender.processHttpMessage()Modifying a Request

Debugging• callbacks.printOutput(String)• callbacks.printError(String)

Utilities

Utilities

Debugging – Stack Traces• Exception.printStackTrace()• Get the error OutputStream

• Print a stack trace to the stream

Utilities

Utilities

Bringing it all Together

• BApp Store Challenges• Base Classes• Passive Scanning• GUI Building

Using Base Classes• com.codemagi.burp.BaseExtender– com.codemagi.burp.PassiveScan• com.monikamorrow.burp.BurpSuiteTab

Bringing it all Together

Bringing it all TogetherGUI Building

Passive Scanning@Overrideprotected void initPassiveScan() { //set the extension Name extensionName = "Software Version Checks"; //create a component rulesTable = new RuleTableComponent(this, callbacks); //add component to Burp GUI mTab = new BurpSuiteTab(extensionName, callbacks); mTab.addComponent(rulesTable);}

Bringing it all Together

Bringing it all TogetherSolving BApp Store Challenges

Get the Code• Burp Suite Utils:– https://github.com/augustd/burp-suite-utils

• Burp Suite Extension Examples: – https://github.com/monikamorrow/Burp-Suite-Extension-Exam

ples

• Software Version Checks– https://github.com/augustd/burp-suite-software-version-checks

• GWT Scan– https://github.com/augustd/burp-suite-gwt-scan

Get the Extensions

• Software Version Checks• GWT Scan

Also See: • Error Message Checks• Session Timeout Test

Available in the Bapp Store

Thank You!

August Detlefsen

augustd@codemagi.com@codemagi

Monika Morrow

mmorrow@ appsecconsulting.com@fortytwowho