Created
August 29, 2018 04:55
-
-
Save toripiyo/0d459746f59b27b7cffa1254396dbddf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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