Skip to content

Instantly share code, notes, and snippets.

@toripiyo
Created August 29, 2018 04:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toripiyo/0d459746f59b27b7cffa1254396dbddf to your computer and use it in GitHub Desktop.
Save toripiyo/0d459746f59b27b7cffa1254396dbddf to your computer and use it in GitHub Desktop.
from burp import IBurpExtender
from burp import IContextMenuFactory
from burp import IHttpRequestResponse
from burp import IMessageEditorController
from burp import IHttpListener
from javax.swing import JMenuItem
from java.io import PrintWriter
from java.lang import RuntimeException
from java.net import URL
import string
import urllib2
import threading
import json
from urlparse import urlparse
from string import Template
class BurpExtender(IBurpExtender, IContextMenuFactory):
# Implement IBurpExtender
def registerExtenderCallbacks(self, callbacks):
# debug purpose
import sys
sys.stdout = callbacks.getStdout()
sys.stderr = callbacks.getStderr()
# set extension name
callbacks.setExtensionName("Jira SubTicket Generator")
# Callbacks object
self._callbacks = callbacks
# Helpers object
self._helpers = callbacks.getHelpers()
# Register a factory for custom context menu items
callbacks.registerContextMenuFactory(self)
return
# Create a menu item if the appropriate section of the UI is selected
def createMenuItems(self, invocation):
menu = []
# which part of the interface the user selects
ctx = invocation.getInvocationContext()
# Message Viewer Req/Res, Site Map Table, and Proxy History will show menu item if selected by the user
# if ctx == 2 or ctx == 3 or ctx == 4 or ctx == 5 or ctx == 6:
if ctx == 7:
menu.append(JMenuItem("Generate jira subticket", None, actionPerformed=lambda x, inv=invocation: self.createJira(inv)))
return menu if menu else None
def createJira(self, invocation):
# set variables
basic_base64 = "BASE64 ENCODED STRINGS" # echo -n '<username>:<password>' | base64
parent_id="PARENT JIRA TICKET ID"
try:
issues = invocation.getSelectedIssues()
if len(issues) == 1:
issue = issues[0]
# get issue details
confidence = issue.getConfidence()
httpMessages = issue.getHttpMessages()
httpService = issue.getHttpService()
issueDetail = issue.getIssueDetail()
issueBackground = issue.getIssueBackground()
issueDetailBackground = issueDetail + "\n" + issueBackground
issueName = issue.getIssueName()
issueType = issue.getIssueType()
remediationBackground = issue.getRemediationBackground()
remediationDetail = issue.getRemediationDetail()
severity = issue.getSeverity()
url = issue.getUrl()
# submit jira ticket creation request
self.originalMsgHost = "JIRA HOST DOMAIN"
self.originalMsgPort = 443
self.originalMsgProtocol = "https"
# description
description = ""
if type(issueDetail) is unicode and type(issueDetailBackground) is unicode:
description = "*Issue Detail*\n" + issueDetail.encode("utf-8") + "\n\n*IssueBackground*\n" + issueBackground.encode("utf-8")
elif type(issueDetail) is unicode:
description = "*Issue Detail*\n" + issueDetail.encode("utf-8")
elif type(issueDetailBackground) is unicode:
description = "*IssueBackground*\n" + issueBackground.encode("utf-8")
# insert request/response details into description
if len(httpMessages) > 0:
for i, message in enumerate(httpMessages):
# request
description = description + "\n\n*request" + str(i + 1) + "*\n{code}\n" + self._helpers.bytesToString(message.getRequest()).encode("utf-8") + "\n{code}\n"
# response
if len(self._helpers.bytesToString(httpMessages[0].getResponse()).encode("utf-8").splitlines()) >= 30:
# huge response data is cut off because jira api can't accept huge request data
description = description + "\n\n*response" + str(i + 1) + "*\n{code}\n" + '\r\n'.join(self._helpers.bytesToString(message.getResponse()).encode("utf-8").splitlines()[0:30]) + "\n\n***** skip the rest *****\n\n" + "\n{code}\n"
else:
description = description + "\n\n*response" + str(i + 1) + "*\n{code}\n" + self._helpers.bytesToString(message.getResponse()).encode("utf-8") + "\n{code}\n"
# payload
payload = {
"fields":{
"project": {
"key": "KEYNAME"
},
"parent": {
"key": parent_id
},
"summary": issueName,
"description": description,
"issuetype": {
"name": "Vulnerability"
}
}
}
payload_json = json.dumps(payload)
payload_length = len(payload_json)
self.requestString = '''POST /jira/rest/api/2/issue HTTP/1.1
Host: {self.originalMsgHost}
Accept: */*
Authorization: Basic {basic_base64}
Content-Type: application/json
Connection: close
Content-Length: {payload_length}
{payload_json}'''.format(basic_base64=basic_base64, payload_json=payload_json, payload_length=payload_length).strip()
thread = threading.Thread(target=self.issueRequest)
thread.start()
else:
print "Please select only 1 issue"
except:
e = sys.exc_info()[0]
print (e)
print "Error: exception occured.\n"
raise RuntimeException(e)
def issueRequest(self):
response = self._callbacks.makeHttpRequest(self._helpers.buildHttpService(self.originalMsgHost, self.originalMsgPort, self.originalMsgProtocol == "https"), self._helpers.stringToBytes(self.requestString))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment