|
1 | 1 | # -*- coding: utf-8 -*- |
2 | 2 | # type: ignore[import] |
3 | | -from burp import IBurpExtender, ITab, IHttpListener |
| 3 | +from burp import IBurpExtender, ITab, IHttpListener, IScanIssue |
4 | 4 | from java.awt import BorderLayout, GridBagLayout, GridBagConstraints, Font |
5 | 5 | from javax.swing import ( |
6 | 6 | JPanel, JTextArea, JScrollPane, |
|
15 | 15 | from datetime import datetime |
16 | 16 | from consts import * |
17 | 17 | from api_adapters import get_api_adapter |
| 18 | +from issues import BurpferenceIssue |
18 | 19 |
|
19 | 20 |
|
20 | 21 | def load_ascii_art(file_path): |
@@ -144,7 +145,7 @@ def compare(self, s1, s2): |
144 | 145 | n2 = int(s2) |
145 | 146 | return n1 - n2 |
146 | 147 | except: |
147 | | - return 0 # Return 0 if conversion fails |
| 148 | + return 0 |
148 | 149 |
|
149 | 150 | # Add sorting capability |
150 | 151 | sorter = TableRowSorter(self.historyTableModel) |
@@ -598,6 +599,57 @@ def applyDarkTheme(self, component): |
598 | 599 | for child in component.getComponents(): |
599 | 600 | self.applyDarkTheme(child) |
600 | 601 |
|
| 602 | + def map_severity(self, ai_severity): |
| 603 | + """Map burpference model severity levels to Burp's iscan exact severity strings""" |
| 604 | + severity_map = { |
| 605 | + "CRITICAL": "High", |
| 606 | + "HIGH": "High", |
| 607 | + "MEDIUM": "Medium", |
| 608 | + "LOW": "Low", |
| 609 | + "INFORMATIONAL": "Information" |
| 610 | + } |
| 611 | + return severity_map.get(ai_severity, "Information") |
| 612 | + |
| 613 | + def extract_severity_from_response(self, response): |
| 614 | + """Extract severity level from model response""" |
| 615 | + for level in ["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFORMATIONAL"]: |
| 616 | + if "**%s**" % level in response: |
| 617 | + return level |
| 618 | + return "INFORMATIONAL" |
| 619 | + |
| 620 | + def create_scan_issue(self, messageInfo, processed_response): |
| 621 | + try: |
| 622 | + severity = self.extract_severity_from_response(processed_response) |
| 623 | + burp_severity = self.map_severity(severity) |
| 624 | + |
| 625 | + # Convert response to string and handle escaping |
| 626 | + if isinstance(processed_response, str): |
| 627 | + detail = processed_response |
| 628 | + else: |
| 629 | + detail = str(processed_response) |
| 630 | + |
| 631 | + if detail.startswith('"') and detail.endswith('"'): |
| 632 | + detail = detail[1:-1] # Remove surrounding quotes |
| 633 | + |
| 634 | + # Create properly formatted issue name |
| 635 | + issue_name = "burpference: %s Security Finding" % severity |
| 636 | + |
| 637 | + issue = BurpferenceIssue( |
| 638 | + httpService=messageInfo.getHttpService(), |
| 639 | + url=self._helpers.analyzeRequest(messageInfo).getUrl(), |
| 640 | + httpMessages=[messageInfo], |
| 641 | + name=issue_name, |
| 642 | + detail=detail, |
| 643 | + severity=burp_severity, |
| 644 | + confidence="Certain" |
| 645 | + ) |
| 646 | + |
| 647 | + self._callbacks.addScanIssue(issue) |
| 648 | + self.log_message("Added %s issue to Burp Scanner" % severity) |
| 649 | + |
| 650 | + except Exception as e: |
| 651 | + self.log_message("Error creating scan issue: %s" % str(e)) |
| 652 | + |
601 | 653 | def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): |
602 | 654 | if not self.is_running: |
603 | 655 | return |
@@ -731,6 +783,9 @@ def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): |
731 | 783 |
|
732 | 784 | # Only update the main UI if we got a successful response |
733 | 785 | if status == "Success" and self.is_running: |
| 786 | + # Create Burp scanner issue |
| 787 | + self.create_scan_issue(messageInfo, processed_response) |
| 788 | + |
734 | 789 | # Add to history table with metadata |
735 | 790 | self.historyTableModel.addRow([ |
736 | 791 | table_metadata.get("id", ""), |
|
0 commit comments