├── target
├── maven-archiver
│ └── pom.properties
├── maven-status
│ └── maven-compiler-plugin
│ │ ├── testCompile
│ │ └── default-testCompile
│ │ │ ├── createdFiles.lst
│ │ │ └── inputFiles.lst
│ │ └── compile
│ │ └── default-compile
│ │ ├── createdFiles.lst
│ │ └── inputFiles.lst
├── Semgrep4BurpSuite-1.0-SNAPSHOT.jar
├── classes
│ └── com
│ │ └── semgrep4burpsuite
│ │ ├── Utilities.class
│ │ ├── BurpExtender.class
│ │ ├── ExtensionUI$1.class
│ │ ├── ExtensionUI$2.class
│ │ ├── ExtensionUI.class
│ │ ├── SemgrepResult.class
│ │ ├── Utilities$1.class
│ │ ├── CustomScanIssue.class
│ │ └── BurpExtender$SemgrepScanner.class
├── test-classes
│ └── com
│ │ └── semgrep4burpsuite
│ │ └── AppTest.class
├── Semgrep4BurpSuite-1.0-SNAPSHOT-jar-with-dependencies.jar
└── surefire-reports
│ ├── com.semgrep4burpsuite.AppTest.txt
│ └── TEST-com.semgrep4burpsuite.AppTest.xml
├── README.md
├── src
├── main
│ └── java
│ │ └── com
│ │ └── semgrep4burpsuite
│ │ ├── SemgrepResult.java
│ │ ├── CustomScanIssue.java
│ │ ├── Utilities.java
│ │ ├── ExtensionUI.java
│ │ └── BurpExtender.java
└── test
│ └── java
│ └── com
│ └── semgrep4burpsuite
│ └── AppTest.java
└── pom.xml
/target/maven-archiver/pom.properties:
--------------------------------------------------------------------------------
1 | artifactId=Semgrep4BurpSuite
2 | groupId=com.semgrep4burpsuite
3 | version=1.0-SNAPSHOT
4 |
--------------------------------------------------------------------------------
/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst:
--------------------------------------------------------------------------------
1 | com/semgrep4burpsuite/AppTest.class
2 |
--------------------------------------------------------------------------------
/target/Semgrep4BurpSuite-1.0-SNAPSHOT.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/Semgrep4BurpSuite-1.0-SNAPSHOT.jar
--------------------------------------------------------------------------------
/target/classes/com/semgrep4burpsuite/Utilities.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/classes/com/semgrep4burpsuite/Utilities.class
--------------------------------------------------------------------------------
/target/classes/com/semgrep4burpsuite/BurpExtender.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/classes/com/semgrep4burpsuite/BurpExtender.class
--------------------------------------------------------------------------------
/target/classes/com/semgrep4burpsuite/ExtensionUI$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/classes/com/semgrep4burpsuite/ExtensionUI$1.class
--------------------------------------------------------------------------------
/target/classes/com/semgrep4burpsuite/ExtensionUI$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/classes/com/semgrep4burpsuite/ExtensionUI$2.class
--------------------------------------------------------------------------------
/target/classes/com/semgrep4burpsuite/ExtensionUI.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/classes/com/semgrep4burpsuite/ExtensionUI.class
--------------------------------------------------------------------------------
/target/classes/com/semgrep4burpsuite/SemgrepResult.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/classes/com/semgrep4burpsuite/SemgrepResult.class
--------------------------------------------------------------------------------
/target/classes/com/semgrep4burpsuite/Utilities$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/classes/com/semgrep4burpsuite/Utilities$1.class
--------------------------------------------------------------------------------
/target/test-classes/com/semgrep4burpsuite/AppTest.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/test-classes/com/semgrep4burpsuite/AppTest.class
--------------------------------------------------------------------------------
/target/classes/com/semgrep4burpsuite/CustomScanIssue.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/classes/com/semgrep4burpsuite/CustomScanIssue.class
--------------------------------------------------------------------------------
/target/Semgrep4BurpSuite-1.0-SNAPSHOT-jar-with-dependencies.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/Semgrep4BurpSuite-1.0-SNAPSHOT-jar-with-dependencies.jar
--------------------------------------------------------------------------------
/target/classes/com/semgrep4burpsuite/BurpExtender$SemgrepScanner.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TRIKKSS/Semgrep4BurpSuite/HEAD/target/classes/com/semgrep4burpsuite/BurpExtender$SemgrepScanner.class
--------------------------------------------------------------------------------
/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst:
--------------------------------------------------------------------------------
1 | /home/trikkss/projects/javascript-code-analyzer/javascriptSourceAnalyzer/src/test/java/com/semgrep4burpsuite/AppTest.java
2 |
--------------------------------------------------------------------------------
/target/surefire-reports/com.semgrep4burpsuite.AppTest.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | Test set: com.semgrep4burpsuite.AppTest
3 | -------------------------------------------------------------------------------
4 | Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.022 s -- in com.semgrep4burpsuite.AppTest
5 |
--------------------------------------------------------------------------------
/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst:
--------------------------------------------------------------------------------
1 | com/semgrep4burpsuite/ExtensionUI$2.class
2 | com/semgrep4burpsuite/Utilities.class
3 | com/semgrep4burpsuite/CustomScanIssue.class
4 | com/semgrep4burpsuite/ExtensionUI.class
5 | com/semgrep4burpsuite/BurpExtender.class
6 | com/semgrep4burpsuite/BurpExtender$SemgrepScanner.class
7 | com/semgrep4burpsuite/SemgrepResult.class
8 | com/semgrep4burpsuite/Utilities$1.class
9 | com/semgrep4burpsuite/ExtensionUI$1.class
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Semgrep4BurpSuite
2 |
3 | ## Build
4 |
5 | ```
6 | mvn package
7 | ```
8 |
9 | ## Usage
10 |
11 | 1. Add your Semgrep rules in the Semgrep4BurpSuite tab.
12 | 2. Right-click on the request you want to analyze.
13 | 3. Go to Extensions -> Semgrep4BurpSuite -> Analyze JavaScript file.
14 | 4. An issue has been created in the Target tab, highlighting the potentially vulnerable part of the code.
15 |
16 | ## cool semgrep rules
17 |
18 | - [DOM XSS Rules by dipa96](https://github.com/dipa96/semgrep-rules)
--------------------------------------------------------------------------------
/src/main/java/com/semgrep4burpsuite/SemgrepResult.java:
--------------------------------------------------------------------------------
1 | package com.semgrep4burpsuite;
2 |
3 | import burp.*;
4 | import java.util.List;
5 | import java.util.Map;
6 | import org.json.JSONObject;
7 |
8 | class SemgrepResult {
9 | public String message;
10 | public int offset;
11 | public int length;
12 |
13 |
14 | SemgrepResult(String message, int offset, int length) {
15 | this.message = message;
16 | this.offset = offset;
17 | this.length = length;
18 | }
19 |
20 | public int[] getHighlighted(int bodyOffset) {
21 | return new int[]{bodyOffset + this.offset, bodyOffset + this.offset + this.length};
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst:
--------------------------------------------------------------------------------
1 | /home/trikkss/projects/javascript-code-analyzer/javascriptSourceAnalyzer/src/main/java/com/semgrep4burpsuite/BurpExtender.java
2 | /home/trikkss/projects/javascript-code-analyzer/javascriptSourceAnalyzer/src/main/java/com/semgrep4burpsuite/CustomScanIssue.java
3 | /home/trikkss/projects/javascript-code-analyzer/javascriptSourceAnalyzer/src/main/java/com/semgrep4burpsuite/ExtensionUI.java
4 | /home/trikkss/projects/javascript-code-analyzer/javascriptSourceAnalyzer/src/main/java/com/semgrep4burpsuite/SemgrepResult.java
5 | /home/trikkss/projects/javascript-code-analyzer/javascriptSourceAnalyzer/src/main/java/com/semgrep4burpsuite/Utilities.java
6 |
--------------------------------------------------------------------------------
/src/test/java/com/semgrep4burpsuite/AppTest.java:
--------------------------------------------------------------------------------
1 | package com.semgrep4burpsuite;
2 |
3 | import junit.framework.Test;
4 | import junit.framework.TestCase;
5 | import junit.framework.TestSuite;
6 |
7 | /**
8 | * Unit test for simple App.
9 | */
10 | public class AppTest
11 | extends TestCase
12 | {
13 | /**
14 | * Create the test case
15 | *
16 | * @param testName name of the test case
17 | */
18 | public AppTest( String testName )
19 | {
20 | super( testName );
21 | }
22 |
23 | /**
24 | * @return the suite of tests being tested
25 | */
26 | public static Test suite()
27 | {
28 | return new TestSuite( AppTest.class );
29 | }
30 |
31 | /**
32 | * Rigourous Test :-)
33 | */
34 | public void testApp()
35 | {
36 | assertTrue( true );
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | com.semgrep4burpsuite
5 | Semgrep4BurpSuite
6 | jar
7 | 1.0-SNAPSHOT
8 | Semgrep4BurpSuite
9 | http://maven.apache.org
10 |
11 |
12 | junit
13 | junit
14 | 3.8.1
15 | test
16 |
17 |
18 | org.json
19 | json
20 | 20250107
21 |
22 |
23 | net.portswigger.burp.extender
24 | burp-extender-api
25 | 1.7.22
26 | provided
27 |
28 |
29 |
30 |
31 |
32 | maven-assembly-plugin
33 |
34 |
35 |
36 | jar-with-dependencies
37 |
38 |
39 |
40 |
41 | true
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | make-assembly
50 | package
51 |
52 | single
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/main/java/com/semgrep4burpsuite/CustomScanIssue.java:
--------------------------------------------------------------------------------
1 | package com.semgrep4burpsuite;
2 |
3 | import burp.IHttpRequestResponse;
4 | import burp.IHttpService;
5 | import burp.IScanIssue;
6 |
7 | import java.net.URL;
8 |
9 | //
10 | // class implementing IScanIssue to hold our custom scan issue details
11 | //
12 |
13 | public class CustomScanIssue implements IScanIssue {
14 | private final IHttpService httpService;
15 | private final URL url;
16 | private final IHttpRequestResponse[] httpMessages;
17 | private final String name;
18 | private final String background;
19 | private final String detail;
20 | private final String severity;
21 | private final String confidence;
22 |
23 | public CustomScanIssue(
24 | IHttpService httpService,
25 | URL url,
26 | IHttpRequestResponse[] httpMessages,
27 | String name,
28 | String detail,
29 | String background,
30 | String severity,
31 | String confidence) {
32 | this.httpService = httpService;
33 | this.url = url;
34 | this.httpMessages = httpMessages;
35 | this.name = name;
36 | this.detail = detail;
37 | this.background = background;
38 | this.severity = severity;
39 | this.confidence = confidence;
40 | }
41 |
42 | @Override
43 | public URL getUrl() {
44 | return url;
45 | }
46 |
47 | @Override
48 | public String getIssueName() {
49 | return name;
50 | }
51 |
52 | @Override
53 | public int getIssueType() {
54 | return 0;
55 | }
56 |
57 | @Override
58 | public String getSeverity() {
59 | return severity;
60 | }
61 |
62 | @Override
63 | public String getConfidence() {
64 | return confidence;
65 | } // Expected values are "Certain", "Firm" or "Tentative".
66 |
67 | @Override
68 | public String getIssueBackground() {
69 | return background;
70 | }
71 |
72 | @Override
73 | public String getRemediationBackground() {
74 | return null;
75 | }
76 |
77 | @Override
78 | public String getIssueDetail() {
79 | return detail;
80 | }
81 |
82 | @Override
83 | public String getRemediationDetail() {
84 | return null;
85 | }
86 |
87 | @Override
88 | public IHttpRequestResponse[] getHttpMessages() {
89 | return httpMessages;
90 | }
91 |
92 | @Override
93 | public IHttpService getHttpService() {
94 | return httpService;
95 | }
96 | }
--------------------------------------------------------------------------------
/src/main/java/com/semgrep4burpsuite/Utilities.java:
--------------------------------------------------------------------------------
1 | package com.semgrep4burpsuite;
2 |
3 | import burp.*;
4 | import java.util.List;
5 | import java.util.ArrayList;
6 | import java.util.Map;
7 | import java.util.Comparator;
8 | import org.json.JSONArray;
9 | import org.json.JSONObject;
10 |
11 | class Utilities {
12 |
13 | private static final IBurpExtenderCallbacks callbacks = BurpExtender.getCallbacks();
14 | private static final IExtensionHelpers helpers = BurpExtender.getHelpers();
15 |
16 | public static List parseOutput(JSONObject semgrepOutput) {
17 | List results = new ArrayList<>();
18 |
19 | JSONArray resultsJson = semgrepOutput.getJSONArray("results");
20 |
21 | for (int i = 0; i < resultsJson.length(); i++) {
22 | JSONObject result = resultsJson.getJSONObject(i);
23 |
24 | JSONObject start = result.getJSONObject("start");
25 | JSONObject end = result.getJSONObject("end");
26 | JSONObject extra = result.getJSONObject("extra");
27 |
28 | int startOffset = start.getInt("offset");
29 | int endOffset = end.getInt("offset");
30 | String message = extra.getString("message");
31 |
32 | results.add(new SemgrepResult(message, startOffset, endOffset - startOffset));
33 | }
34 |
35 | return results;
36 | }
37 |
38 | public static void addCustomIssue(
39 | IHttpRequestResponse baseRequestResponse,
40 | String issueName,
41 | List responseMarkers,
42 | String severity,
43 | String confidence
44 | ) {
45 | IScanIssue newCustomIssue = new CustomScanIssue(
46 | baseRequestResponse.getHttpService(),
47 | helpers.analyzeRequest(baseRequestResponse).getUrl(),
48 | new IHttpRequestResponse[]{callbacks.applyMarkers(baseRequestResponse, null, responseMarkers)},
49 | issueName,
50 | "This issue was generated by \"" + BurpExtender.EXTENSION_NAME + "\" Burp extension.
" +
51 | "The identified matches should be highlighted in the HTTP response.
",
52 | null,
53 | severity,
54 | confidence);
55 |
56 | callbacks.addScanIssue(newCustomIssue);
57 | }
58 |
59 | public static List getMatches(int bodyOffset, List results) {
60 | List matches = new ArrayList();
61 |
62 | for (SemgrepResult result : results)
63 | {
64 | matches.add(result.getHighlighted(bodyOffset));
65 | }
66 |
67 | // Sort found matches or otherwise Burp will complain (Source: https://stackoverflow.com/questions/19596950/sort-an-arraylist-of-integer-arrays)
68 | matches.sort(new Comparator() {
69 | private static final int INDEX = 0;
70 |
71 | @Override
72 | public int compare(int[] o1, int[] o2) {
73 | return Integer.compare(o1[INDEX], o2[INDEX]);
74 | }
75 | });
76 |
77 | // Dirty trick to fix overlapping offsets
78 | for (int i = 0; i < matches.size(); i++) {
79 | if (i + 1 != matches.size()
80 | && matches.get(i)[1] > matches.get(i + 1)[0]) {
81 | int[] fixed = {matches.get(i)[0], matches.get(i + 1)[0]};
82 | matches.set(i, fixed);
83 | }
84 | }
85 |
86 | return matches;
87 | }
88 | }
--------------------------------------------------------------------------------
/src/main/java/com/semgrep4burpsuite/ExtensionUI.java:
--------------------------------------------------------------------------------
1 | package com.semgrep4burpsuite;
2 |
3 | import burp.*;
4 |
5 | import javax.swing.*;
6 | import java.awt.*;
7 | import javax.swing.border.EmptyBorder;
8 | import java.util.List;
9 | import java.util.ArrayList;
10 | import java.awt.event.ActionEvent;
11 | import java.awt.event.ActionListener;
12 | import java.io.File;
13 |
14 | public class ExtensionUI {
15 |
16 | private JPanel pnlMain;
17 | private List selectedRules;
18 | private BurpExtender mainClass;
19 | private DefaultListModel listModel;
20 | private JList fileList;
21 |
22 | public ExtensionUI(BurpExtender mainClass) {
23 | this.mainClass = mainClass;
24 | this.selectedRules = new ArrayList<>(this.mainClass.getRules());
25 |
26 | pnlMain = new JPanel();
27 | pnlMain.setLayout(new BorderLayout());
28 | pnlMain.setBorder(new EmptyBorder(10, 10, 10, 10));
29 |
30 | JLabel lblTitle = new JLabel(mainClass.EXTENSION_NAME);
31 | lblTitle.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));
32 | lblTitle.setForeground(new Color(255, 102, 51));
33 | lblTitle.setBorder(new EmptyBorder(5, 0, 5, 5));
34 | pnlMain.add(lblTitle, BorderLayout.NORTH);
35 |
36 | JLabel label = new JLabel("Add or Remove Semgrep rules:");
37 | pnlMain.add(label, BorderLayout.NORTH);
38 |
39 | // Utiliser un DefaultListModel pour rendre la liste modifiable
40 | listModel = new DefaultListModel<>();
41 | for (String file : selectedRules) {
42 | listModel.addElement(file);
43 | }
44 |
45 | // Créer le JList avec le modèle
46 | fileList = new JList<>(listModel);
47 | fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
48 | JScrollPane scrollPane = new JScrollPane(fileList);
49 | pnlMain.add(scrollPane, BorderLayout.CENTER);
50 |
51 | // Panel des boutons
52 | JPanel buttonPanel = new JPanel(new FlowLayout());
53 |
54 | JButton addButton = new JButton("Add File");
55 | addButton.addActionListener(new ActionListener() {
56 | @Override
57 | public void actionPerformed(ActionEvent e) {
58 | addFile();
59 | }
60 | });
61 | buttonPanel.add(addButton);
62 |
63 | JButton removeButton = new JButton("Remove Selected");
64 | removeButton.addActionListener(new ActionListener() {
65 | @Override
66 | public void actionPerformed(ActionEvent e) {
67 | removeFile();
68 | }
69 | });
70 | buttonPanel.add(removeButton);
71 |
72 | pnlMain.add(buttonPanel, BorderLayout.SOUTH);
73 | }
74 |
75 | private void addFile() {
76 | JFileChooser fileChooser = new JFileChooser();
77 | fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
78 | int result = fileChooser.showOpenDialog(pnlMain);
79 |
80 | if (result == JFileChooser.APPROVE_OPTION) {
81 | File selectedFile = fileChooser.getSelectedFile();
82 | String filePath = selectedFile.getAbsolutePath();
83 |
84 | if (!selectedRules.contains(filePath)) {
85 | listModel.addElement(filePath); // Mettre à jour le modèle de la liste
86 | selectedRules.add(filePath);
87 | mainClass.addRules(filePath);
88 | } else {
89 | JOptionPane.showMessageDialog(pnlMain, "File already added!", "Warning", JOptionPane.WARNING_MESSAGE);
90 | }
91 | }
92 | }
93 |
94 | private void removeFile() {
95 | int selectedIndex = fileList.getSelectedIndex();
96 | if (selectedIndex != -1) {
97 | String fileToRemove = listModel.getElementAt(selectedIndex);
98 | listModel.remove(selectedIndex);
99 | selectedRules.remove(fileToRemove);
100 | mainClass.removeRules(fileToRemove); // Supposant que la méthode existe
101 | } else {
102 | JOptionPane.showMessageDialog(pnlMain, "No file selected!", "Error", JOptionPane.ERROR_MESSAGE);
103 | }
104 | }
105 |
106 | public JPanel getMainPanel() {
107 | return pnlMain;
108 | }
109 |
110 | public List getSelectedRules() {
111 | return selectedRules;
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/target/surefire-reports/TEST-com.semgrep4burpsuite.AppTest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/main/java/com/semgrep4burpsuite/BurpExtender.java:
--------------------------------------------------------------------------------
1 | package com.semgrep4burpsuite;
2 |
3 | import burp.*;
4 |
5 | import javax.swing.*;
6 | import java.awt.*;
7 | import javax.swing.border.EmptyBorder;
8 | import java.util.List;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 | import java.util.Arrays;
13 |
14 | import java.awt.event.ActionListener;
15 | import java.awt.event.ActionEvent;
16 |
17 | import java.io.BufferedReader;
18 | import java.io.InputStreamReader;
19 | import java.io.File;
20 | import java.io.FileOutputStream;
21 | import java.io.IOException;
22 | import org.json.JSONObject;
23 | import java.nio.charset.StandardCharsets;
24 |
25 |
26 | public class BurpExtender implements IBurpExtender, IContextMenuFactory, ITab {
27 | private static IBurpExtenderCallbacks callbacks;
28 | private static IExtensionHelpers helpers;
29 |
30 | private ExtensionUI UI;
31 |
32 | private List rulesFiles = new ArrayList();
33 |
34 | public static final String EXTENSION_NAME = "Semgrep4BurpSuite";
35 |
36 |
37 | @Override
38 | public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
39 | // Enregistrement des callbacks
40 | this.callbacks = callbacks;
41 | this.helpers = callbacks.getHelpers();
42 |
43 | // Définir le nom de l'extension
44 | callbacks.setExtensionName(EXTENSION_NAME);
45 |
46 | // Ajouter le menu contextuel
47 | callbacks.registerContextMenuFactory(this);
48 |
49 | callbacks.addSuiteTab(this);
50 | }
51 |
52 | @Override
53 | public Component getUiComponent() {
54 | UI = new ExtensionUI(this);
55 | return UI.getMainPanel();
56 | }
57 |
58 | @Override
59 | public String getTabCaption() {
60 | return EXTENSION_NAME;
61 | }
62 |
63 | /*
64 | * Context menu items
65 | */
66 | @Override
67 | public List createMenuItems(IContextMenuInvocation invocation) {
68 | List items = new ArrayList<>();
69 |
70 | if (IContextMenuInvocation.CONTEXT_TARGET_SITE_MAP_TABLE == invocation.getInvocationContext() ||
71 | IContextMenuInvocation.CONTEXT_TARGET_SITE_MAP_TREE == invocation.getInvocationContext() ||
72 | IContextMenuInvocation.CONTEXT_PROXY_HISTORY == invocation.getInvocationContext() ||
73 | IContextMenuInvocation.CONTEXT_MESSAGE_VIEWER_REQUEST == invocation.getInvocationContext() ||
74 | IContextMenuInvocation.CONTEXT_MESSAGE_VIEWER_RESPONSE == invocation.getInvocationContext() ||
75 | IContextMenuInvocation.CONTEXT_MESSAGE_EDITOR_REQUEST == invocation.getInvocationContext() ||
76 | IContextMenuInvocation.CONTEXT_MESSAGE_EDITOR_RESPONSE == invocation.getInvocationContext()
77 | ) {
78 | IHttpRequestResponse[] selectedMessages = invocation.getSelectedMessages();
79 |
80 | JMenuItem scanItem = new JMenuItem("Analyze");
81 | SemgrepScanner scanItemActionAction = new SemgrepScanner(selectedMessages);
82 | scanItem.addActionListener(scanItemActionAction);
83 | items.add(scanItem);
84 | }
85 |
86 | return items;
87 | }
88 |
89 |
90 | class SemgrepScanner implements ActionListener {
91 | private final IHttpRequestResponse[] httpReqResArray;
92 |
93 | SemgrepScanner(IHttpRequestResponse[] httpReqResArr) {
94 | this.httpReqResArray = httpReqResArr;
95 | }
96 |
97 | @Override
98 | public void actionPerformed(ActionEvent e) {
99 | /*
100 | todo : for each loop over IHttpRequestResponse[]
101 | */
102 | new Thread(() -> {
103 | // long ts = Instant.now().toEpochMilli();
104 | // ScannerBuilder scannerBuilder = new ScannerBuilder.Builder(httpReqResArray)
105 | // .runAllScans()
106 | // .taskId(++taskCount)
107 | // .timeStamp(ts)
108 | // .build();
109 | // scannerBuilder.runScans();
110 | Scan(httpReqResArray[0]);
111 | }).start();
112 | }
113 | }
114 |
115 |
116 | public void Scan(IHttpRequestResponse httpReqResArr) {
117 | IRequestInfo requestInfo = helpers.analyzeRequest(httpReqResArr);
118 | java.net.URL url = requestInfo.getUrl();
119 |
120 | try {
121 |
122 | if (rulesFiles.isEmpty()) {
123 | return;
124 | }
125 |
126 | // get response body
127 | int bodyOffset = helpers.analyzeRequest(httpReqResArr.getResponse()).getBodyOffset();
128 | byte[] responseBytes = httpReqResArr.getResponse();
129 | byte[] responseBodyBytes = Arrays.copyOfRange(responseBytes, bodyOffset, responseBytes.length);
130 | // callbacks.printOutput("Request body : " + new String(responseBodyBytes));
131 | File tempFile = File.createTempFile("request_body_", ".js");
132 |
133 | FileOutputStream outputStream = new FileOutputStream(tempFile);
134 | outputStream.write(responseBodyBytes);
135 |
136 | // Exécuter la commande
137 | ArrayList command = new ArrayList<>();
138 | command.add("semgrep");
139 | command.add("scan");
140 | command.add("--json");
141 | for (String filename : rulesFiles) {
142 | command.add("--config");
143 | command.add(filename);
144 | }
145 | command.add(tempFile.getAbsolutePath());
146 | ProcessBuilder processBuilder = new ProcessBuilder(command);
147 | callbacks.printOutput("Commande exécutée : " + String.join(" ", processBuilder.command()));
148 | Process process = processBuilder.start();
149 |
150 | // Lire la sortie de la commande
151 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
152 | StringBuilder output = new StringBuilder();
153 | String line;
154 | while ((line = reader.readLine()) != null) {
155 | output.append(line);
156 | }
157 |
158 | // Attendre la fin du processus
159 | process.waitFor();
160 |
161 | // Parse la sortie comme JSON
162 | String jsonString = output.toString();
163 | JSONObject json = new JSONObject(jsonString);
164 | callbacks.printOutput(json.toString());
165 | List results = new ArrayList();
166 | try {
167 | results = Utilities.parseOutput(json);
168 | } catch (Exception e) {
169 | callbacks.printOutput(e.getMessage());
170 | }
171 | callbacks.printOutput("calling reportFindings");
172 | reportFinding(httpReqResArr, results);
173 | callbacks.printOutput("Findings reported.");
174 | } catch (IOException | InterruptedException e) {
175 | callbacks.printOutput("error !!!!");
176 | callbacks.printOutput("Erreur : " + e.getMessage());
177 | }
178 | // tempFile.getAbsolutePath();
179 |
180 | // callbacks.printOutput("analyzing " + url.getPath());
181 | // callbacks.printOutput(new String(httpReqResArr.getResponse()));
182 | }
183 |
184 | private void reportFinding(IHttpRequestResponse baseRequestResponse, List results) {
185 | int bodyOffset = helpers.analyzeRequest(baseRequestResponse.getResponse()).getBodyOffset();
186 | List allMatchesMarkers = Utilities.getMatches(bodyOffset, results);
187 |
188 | // report the issue
189 | Utilities.addCustomIssue(
190 | baseRequestResponse,
191 | "[" + this.EXTENSION_NAME + "] result",
192 | allMatchesMarkers,
193 | "Information",
194 | "Certain"
195 | );
196 | }
197 |
198 |
199 | public static IBurpExtenderCallbacks getCallbacks() {
200 | return callbacks;
201 | }
202 |
203 | public static IExtensionHelpers getHelpers() {
204 | return helpers;
205 | }
206 |
207 | public void addRules(String path) {
208 | rulesFiles.add(path);
209 | }
210 |
211 | public void removeRules(String filePath) {
212 | if (rulesFiles.contains(filePath)) {
213 | rulesFiles.remove(filePath);
214 | } else {
215 | callbacks.printOutput("Rule not found: " + filePath);
216 | }
217 | }
218 |
219 | public List getRules() {
220 | return rulesFiles;
221 | }
222 | }
--------------------------------------------------------------------------------