├── 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 | } --------------------------------------------------------------------------------