Extending-Burp-with-Pythonx
Download
Report
Transcript Extending-Burp-with-Pythonx
Extending Burp with
Python
Defeating web application idiosyncrasies
with common-sense, Python and minimal
knowledge of Java GUIs
What is Burp?
Purpose of this Talk
•
•
Quick tour of Burp APIs with examples to
show what can be achieved
Demonstrate that Web app assessment
hurdles overcome with minimal coding effort
Why would you need a custom extn?
1. Decode custom encoding/serialization
2. Handle anti-tamper or signed requests
3. Provide a new “view” into an application
4. Automate a manual task with a new scanner check
Setup to run a Python Burp Extn.
1 Download Jython standalone binary
2 Tell Burp where find Jython
3 Load a Python extension
Path to Jython binary goes here
The helloworld of Burp extensions
from burp import IBurpExtender
class BurpExtender(IBurpExtender):
# required
def registerExtenderCallbacks(self, callbacks):
Just writes “Hello alerts” out to alerts tab
# set our extension name
callbacks.setExtensionName("Hello world extension")
# write a message to the Burp alerts tab
callbacks.issueAlert("Hello alerts")
1. Problem: Unsupported encoding
Application uses an encoding not understood
by Burp
Examples:
Serialised Java, SAP’s weird URLenc variant, SAML, Websphere Portlet
Burp APIs: IMessageEditorTab to display
decoded content
Solution: new encoder/decoder
1. Tell Burp about your new message editor
tab
class CustomDecoderTab(IMessageEditorTab):
def __init__(self, extender, controller, editable):
...
def getTabCaption(self):
return "Custom Decoder"
Solution: new decoder/encoder
2. Use setMessage to display decode
def setMessage(self, content, isRequest):
...
if '!ut' in path:
# actual decoding magic omitted
content = response.read()
content = xml.dom.minidom.parseString(content).toprettyxml()
if content:
self._txtInput.setText(content)
self._currentMessage = content
Websphere portlet state decoder
Encoded content on URL
Gets decoded in new tab
Source:
https://github.com/faffi/WebSphere-Portlet-State-Decoder
2. Problem: Signed requests
Application requires signature thats generated
client side.
examples
1. Seen in thick client apps as anti-tamper mechanism
2. AWS API calls are signed for authentication
http://rajasaur.blogspot.co.nz/2009/10/hmac-sha-signatures-using-python-for.html
Burp API: processHTTPMessage allows us to
re-write traffic
Solution: automate request signing
1. Catch an outbound request
from burp import IBurpExtender# this function catches requests and
responses
def processHttpMessage(self, toolFlag, messageIsRequest,
currentRequest):
# only process requests
if not messageIsRequest:
return
...
Solution: automate request signing
2. Grab the request body and headers
# requestInfo object allows us to easily spit body and headers
requestInfo = self._helpers.analyzeRequest(currentRequest)
bodyBytes = currentRequest.getRequest()[requestInfo.getBodyOffset():]
bodyStr = self._helpers.bytesToString(bodyBytes)
headers = requestInfo.getHeaders()
newHeaders = list(headers) #it's a Java arraylist; get a python list
Solution: automate request signing
3. Append signature as HTTP Header
# Do custom signing shenanigans
secret = "SuperSecret123"
h = hmac.new(secret, bodyStr, hashlib.sha256)
newHeaders.append("Authorization: " + base64.b64encode(h.digest()))
Solution: automate request signing
4. Create and send request
newMessage = self._helpers.buildHttpMessage(newHeaders, bodyStr)
currentRequest.setRequest(newMessage)
Here’s the new Authorization header being sent out
3. Problem: Big apps, lotsa headers
Large applications may emit different headers
from various locations within the app.
Headers can reveal useful info. Eg. Reverse proxy may hand off from
backend A to backend B.
Burp APIs: processHTTPMessage and ITab to
display result
Solution: View of unique headers
Keep track of unique headers, filter out
uninteresting headers.
# insert an entry if the header is 'interesting’
if header_name.lower() not in boring_headers:
# and we haven't seen this name/value pair before, log it
if header not in self.headers_seen:
self.headers_seen.append(header)
self._log.add(LogEntry(header, …, … )
Solution: View of unique headers
Create a new tab and display collected
headers in the new tab.
# Give the new tab a name
def getTabCaption(self):
return "Response Headers”
# This adds all the Java UI unpleasantness
def getUiComponent(self):
return self._splitpane
Solution: View of unique headers
List of unique headers
displayed in new
“Response Headers” tab
Clicking item in list shows
request/response
4. Problem: Automate a manual task
Locate and decode F5 cookies, display as a
passive scan result
Burp API: doPassiveScan to trigger check
code
Solution: create new check
1. doPassiveScan catches request
def doPassiveScan(self, baseRequestResponse):
# Returns IResponseInfo
analyzedResponse =
self.helpers.analyzeResponse(baseRequestResponse.getResponse())
analyzedRequest = self.helpers.analyzeRequest(baseRequestResponse)
# Get Cookies from IResponseInfo Instance
analyzedResponse.getCookies()
cookieList =
Solution: create new check
2. Locate BIGIP cookies and decode them
# Loop though list of cookies
for cookie in cookieList:
cookieName = cookie.getName()
# Look for BIGIP Cookies
if cookieName.lower().startswith("bigip"):
f5CookieName = cookieName
f5RawCookieValue = cookie.getValue()
# Decode and check for RFC 1918 address
f5info = decode(f5RawCookieValue)
Solution: create new check
3. Create Issue class to return useful info
class PassiveScanIssue(IScanIssue):
...
def getIssueName(self):
return "Encoded IP Address Discovered in F5 Cookie Value"
...
def getIssueDetail(self):
msg = "The URL <b>" + str(self.findingurl) + "</b> sets the F5 load
balancer cookie <b>"
F5-BigIP Cookie Checker
Internal IP address
retrieved from encoded
cookie
Source:
http://blog.secureideas.com/2013/08/burp-extension-for-f5-cookie-detection.html
Summary
1. Decode custom encoding/serialization
Use IMessageEditorTab interface to display decoded content
2. Handle anti-tamper or signed requests
Use processHTTPMessage to catch and rewrite requests
3. Provide a new “view” into an application
Use ITab interface to display custom view
4. Automate a manual task with a new scanner check
Use doPassiveScan to trigger a check