├── .gitignore ├── BappDescription.html ├── BappManifest.bmf ├── README.md ├── build.gradle ├── pom.xml └── src ├── burp └── BurpExtender.java └── sharerequests ├── CustomURLServer.java ├── ExtensionPanel.java ├── ExtensionStateListener.java ├── HttpRequestResponse.java ├── HttpService.java ├── ManualRequestSenderContextMenu.java ├── ProxyListener.java ├── SharedLinksModel.java ├── SharedRequest.java └── SharedValues.java /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /BappDescription.html: -------------------------------------------------------------------------------- 1 |

This Burp Suite extension enables the generation of shareable links to specific requests which other Burp Suite users can import.

2 | 3 |

How To Use

4 | 5 |

Once this extension is installed a new tab titled "Burp Share Requests" will appear in Burp Suite which will contain all the currently generated links that are ready to be shared.

6 | 7 |

To create these links right click on a Request from either the Site Map, HTTP History, Intercept Tab, or Repeater tab and select the "create link" option within the context menu options. 8 | This will generate a new line within the "Burp Share Requests" showing the URL of the Request you generated a link for.

9 | 10 |

To share the Request with others, right click on the desired request within the "Burp Share Requests" tab and select "Get link" to generate a link suitable for pasting into a browser URL bar 11 | (i.e. http://burpsharedrequest/...) or select "Get HTML Link" to generate a link suitable for including in a report or blog post (i.e. http://burpsharedrequest/

12 | -------------------------------------------------------------------------------- /BappManifest.bmf: -------------------------------------------------------------------------------- 1 | Uuid: 30ec677a0f134150985b273d8c1dea22 2 | ExtensionType: 1 3 | Name: Burp Share Requests 4 | RepoName: burp-share-requests 5 | ScreenVersion: 1.0 6 | SerialVersion: 1 7 | MinPlatformVersion: 0 8 | ProOnly: False 9 | Author: Static-Flow 10 | ShortDescription: Enables the generation of shareable links to specific requests which other Burp Suite users can import. 11 | EntryPoint: target/BurpSuiteShareRequests.jar 12 | BuildCommand: mvn package 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BurpSuiteShareRequests 2 | This Burp Suite extension enables the generation of shareable links to specific requests which other Burp Suite users can import. If this collaboration feature is useful, checkout my main extension https://github.com/Static-Flow/BurpSuite-Team-Extension which includes this functionality and more! 3 | 4 | # How To Use 5 | Once this extension is installed a new tab titled "Burp Share Requests" will appear in Burp Suite which will contain all the currently generated links that are ready to be shared. 6 | 7 | To create these links right click on a Request from either the Site Map, HTTP History, Intercept Tab, or Repeater tab and select the "create link" option within the context menu options. This will generate a new line within the "Burp Share Requests" showing the URL of the Request you generated a link for. 8 | 9 | To share the Request with others, right click on the desired request within the "Burp Share Requests" tab and select "Get link" to generate a link suitable for pasting into a browser URL bar (i.e. http://burpsharedrequest/...) or select "Get HTML Link" to generate a link suitable for including in a report or blog post (i.e. http://burpsharedrequest/ 10 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | repositories { 4 | mavenCentral() 5 | } 6 | 7 | dependencies { 8 | compile 'net.portswigger.burp.extender:burp-extender-api:1.7.22' 9 | } 10 | 11 | sourceSets { 12 | main { 13 | java { 14 | srcDir 'src' 15 | } 16 | resources { 17 | srcDir 'resources' 18 | } 19 | } 20 | } 21 | 22 | task fatJar(type: Jar) { 23 | 24 | baseName = project.name + '-all' 25 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 26 | with jar 27 | } 28 | 29 | compileJava { 30 | targetCompatibility '1.8' 31 | sourceCompatibility '1.8' 32 | } 33 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | StaticFlow 8 | BurpSuiteShareRequests 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 14 | com.google.code.gson 15 | gson 16 | 2.8.6 17 | 18 | 19 | 20 | com.sun.xml.bind 21 | jaxb-core 22 | 2.3.0.1 23 | 24 | 25 | javax.xml.bind 26 | jaxb-api 27 | 2.3.1 28 | 29 | 30 | com.sun.xml.bind 31 | jaxb-impl 32 | 2.3.1 33 | 34 | 35 | net.portswigger.burp.extender 36 | burp-extender-api 37 | 2.1 38 | 39 | 40 | 41 | 42 | ${project.basedir}/src 43 | BurpSuiteShareRequests 44 | 45 | 46 | 47 | 48 | org.apache.maven.plugins 49 | maven-eclipse-plugin 50 | 2.9 51 | 52 | true 53 | false 54 | 55 | 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-compiler-plugin 61 | 2.3.2 62 | 63 | 1.8 64 | 1.8 65 | 66 | 67 | 68 | 69 | 70 | org.apache.maven.plugins 71 | maven-assembly-plugin 72 | 2.4.1 73 | 74 | 75 | false 76 | 77 | jar-with-dependencies 78 | 79 | 80 | 81 | 82 | 83 | make-assembly 84 | 85 | package 86 | 87 | single 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /src/burp/BurpExtender.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import sharerequests.*; 4 | 5 | import java.awt.*; 6 | import java.io.IOException; 7 | 8 | public class BurpExtender 9 | implements IBurpExtender, ITab { 10 | private SharedValues sharedValues; 11 | 12 | public void registerExtenderCallbacks(IBurpExtenderCallbacks iBurpExtenderCallbacks) { 13 | iBurpExtenderCallbacks.setExtensionName("Burp Shared Requests"); 14 | this.sharedValues = new SharedValues(iBurpExtenderCallbacks); 15 | iBurpExtenderCallbacks.addSuiteTab(this); 16 | iBurpExtenderCallbacks.registerContextMenuFactory(new ManualRequestSenderContextMenu(this.sharedValues)); 17 | iBurpExtenderCallbacks.registerProxyListener(new ProxyListener(this.sharedValues)); 18 | iBurpExtenderCallbacks.registerExtensionStateListener(new ExtensionStateListener(this.sharedValues)); 19 | CustomURLServer innerServer; 20 | try { 21 | innerServer = new CustomURLServer(sharedValues); 22 | Thread innerServerThread = new Thread(innerServer); 23 | innerServerThread.start(); 24 | sharedValues.setInnerServer(innerServer); 25 | } catch (IOException e) { 26 | iBurpExtenderCallbacks.printError(e.getMessage()); 27 | } 28 | } 29 | 30 | public String getTabCaption() { 31 | return "Burp Share Requests"; 32 | } 33 | 34 | public Component getUiComponent() { 35 | return new ExtensionPanel(this.sharedValues); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/sharerequests/CustomURLServer.java: -------------------------------------------------------------------------------- 1 | package sharerequests; 2 | 3 | import java.io.*; 4 | import java.net.ServerSocket; 5 | import java.net.Socket; 6 | import java.net.SocketException; 7 | import java.util.Base64; 8 | import java.util.Date; 9 | import java.util.StringTokenizer; 10 | 11 | public class CustomURLServer implements Runnable { 12 | 13 | private static final String NEW_LINE = "\r\n"; 14 | private final SharedValues sharedValues; 15 | 16 | private ServerSocket socket; 17 | private boolean running; 18 | 19 | public CustomURLServer(SharedValues sharedValues) throws IOException { 20 | this.sharedValues = sharedValues; 21 | socket = new ServerSocket(0); 22 | } 23 | 24 | @Override 25 | public void run() { 26 | running = true; 27 | try { 28 | while (running) { 29 | handleConnection(socket.accept()); 30 | } 31 | } catch (SocketException tr) { 32 | sharedValues.getCallbacks().printError("Inner Server Closed."); 33 | } catch (IOException io) { 34 | sharedValues.getCallbacks().printError("Exception in socket: " + io); 35 | } 36 | 37 | } 38 | 39 | private void handleConnection(Socket connection) { 40 | try { 41 | BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); 42 | OutputStream out = new BufferedOutputStream(connection.getOutputStream()); 43 | PrintStream pout = new PrintStream(out); 44 | 45 | // read first line of request 46 | String request = in.readLine(); 47 | if (request != null) { 48 | 49 | StringTokenizer tokenizer = new StringTokenizer(request); 50 | String httpMethod = tokenizer.nextToken(); 51 | String httpQueryString = tokenizer.nextToken(); 52 | sharedValues.getCallbacks().printOutput(httpMethod + ":" + httpQueryString.substring(1)); 53 | parseCustomMessage(httpQueryString); 54 | // we ignore the rest 55 | while (true) { 56 | String ignore = in.readLine(); 57 | if (ignore == null || ignore.length() == 0) break; 58 | } 59 | 60 | if (!request.startsWith("GET ") || 61 | !(request.endsWith(" HTTP/1.0") || request.endsWith(" HTTP/1.1"))) { 62 | // bad request 63 | pout.print("HTTP/1.0 400 Bad Request" + NEW_LINE + NEW_LINE); 64 | } else { 65 | String response = "Link Processed!"; 66 | 67 | pout.print( 68 | "HTTP/1.0 200 OK" + NEW_LINE + 69 | "Content-Type: text/plain" + NEW_LINE + 70 | "Date: " + new Date() + NEW_LINE + 71 | "Content-length: " + response.length() + NEW_LINE + NEW_LINE + 72 | response 73 | ); 74 | } 75 | 76 | pout.close(); 77 | } 78 | } catch (Exception tri) { 79 | sharedValues.getCallbacks().printError(tri.getMessage()); 80 | } 81 | } 82 | 83 | private void parseCustomMessage(String httpQueryString) { 84 | try { 85 | HttpRequestResponse httpRequestResponse = this.sharedValues.getGson().fromJson( 86 | new String(Base64.getDecoder().decode(httpQueryString.substring(1))), 87 | HttpRequestResponse.class); 88 | this.sharedValues.getCallbacks().sendToRepeater( 89 | httpRequestResponse.getHttpService().getHost(), 90 | httpRequestResponse.getHttpService().getPort(), 91 | httpRequestResponse.getHttpService().getProtocol() 92 | .equalsIgnoreCase("https"), 93 | httpRequestResponse.getRequest(), 94 | "Burp Shared Link Payload"); 95 | } catch (Exception e) { 96 | sharedValues.getCallbacks().printError(e.getMessage()); 97 | } 98 | } 99 | 100 | ServerSocket getSocket() { 101 | return socket; 102 | } 103 | 104 | void stopRunning() { 105 | running = false; 106 | try { 107 | this.socket.close(); 108 | } catch (IOException e) { 109 | sharedValues.getCallbacks().printError("Error closing socket"); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/sharerequests/ExtensionPanel.java: -------------------------------------------------------------------------------- 1 | package sharerequests; 2 | 3 | import javax.swing.*; 4 | import javax.swing.event.PopupMenuEvent; 5 | import javax.swing.event.PopupMenuListener; 6 | import javax.swing.table.DefaultTableCellRenderer; 7 | import java.awt.*; 8 | import java.awt.datatransfer.Clipboard; 9 | import java.awt.datatransfer.StringSelection; 10 | import java.io.ByteArrayOutputStream; 11 | import java.io.IOException; 12 | import java.util.Base64; 13 | import java.util.zip.GZIPOutputStream; 14 | 15 | public class ExtensionPanel 16 | extends JPanel { 17 | private static final long serialVersionUID = 1L; 18 | private SharedValues sharedValues; 19 | 20 | public ExtensionPanel(SharedValues sharedValues) { 21 | this.sharedValues = sharedValues; 22 | this.initComponents(); 23 | } 24 | 25 | private void initComponents() { 26 | GridBagLayout gridBagLayout = new GridBagLayout(); 27 | gridBagLayout.columnWeights = new double[]{1.0, 1.0}; 28 | gridBagLayout.rowWeights = new double[]{0.0, 1.0}; 29 | setLayout(gridBagLayout); 30 | 31 | //info panel 32 | JPanel infoPanel = new JPanel(new BorderLayout()); 33 | JLabel explainer = new JLabel(); 34 | explainer.setHorizontalAlignment(SwingConstants.LEFT); 35 | infoPanel.add(explainer, BorderLayout.WEST); 36 | explainer.setText("This extension allows you to create shareable links to Burp Suite requests.
" + 37 | "When others visit the generated links, in a browser proxied by Burp Suite with this extension installed,
" + 38 | "the request as you shared it will be imported into their repeater tab.
Links can be generated from" + 39 | " right click context menus on requests in the following places:
\n"); 41 | GridBagConstraints gridBagConstraints = new GridBagConstraints(); 42 | gridBagConstraints.fill = GridBagConstraints.BOTH; 43 | gridBagConstraints.insets = new Insets(5, 5, 5, 5); 44 | gridBagConstraints.gridx = 0; 45 | gridBagConstraints.gridy = 0; 46 | add(infoPanel, gridBagConstraints); 47 | JPanel filler = new JPanel(); 48 | gridBagConstraints.gridx = 1; 49 | add(filler, gridBagConstraints); 50 | //end info panel 51 | 52 | //shareable links 53 | JTable j = new JTable(this.sharedValues.getSharedLinksModel()) { 54 | public boolean getScrollableTracksViewportWidth() { 55 | return getPreferredSize().width < getParent().getWidth(); 56 | } 57 | }; 58 | DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer(); 59 | centerRenderer.setHorizontalAlignment(JLabel.CENTER); 60 | j.getColumnModel().getColumn(1).setCellRenderer(centerRenderer); 61 | final JPopupMenu popupMenu = new JPopupMenu(); 62 | popupMenu.addPopupMenuListener(new PopupMenuListener() { 63 | 64 | @Override 65 | public void popupMenuWillBecomeVisible(PopupMenuEvent e) { 66 | SwingUtilities.invokeLater(() -> { 67 | int rowAtPoint = j.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), j)); 68 | if (rowAtPoint > -1) { 69 | j.setRowSelectionInterval(rowAtPoint, rowAtPoint); 70 | 71 | } 72 | }); 73 | } 74 | 75 | @Override 76 | public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 77 | //this just isn't needed but I have to override it 78 | } 79 | 80 | @Override 81 | public void popupMenuCanceled(PopupMenuEvent e) { 82 | //this just isn't needed but I have to override it 83 | } 84 | }); 85 | JMenuItem removeLinkItem = new JMenuItem("Remove Link"); 86 | removeLinkItem.addActionListener(e -> ((SharedLinksModel) j.getModel()).removeBurpMessage(j.getSelectedRow())); 87 | JMenuItem getHTMLLinkItem = new JMenuItem("Get HTML Link"); 88 | getHTMLLinkItem.addActionListener(e -> { 89 | HttpRequestResponse burpMessage = ((SharedLinksModel) j.getModel()).getBurpMessageAtIndex(j.getSelectedRow()); 90 | StringSelection stringSelection = new StringSelection(generateHTMLLink(burpMessage)); 91 | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 92 | clipboard.setContents(stringSelection, null); 93 | JOptionPane.showMessageDialog(null, "Link has been added to the clipboard"); 94 | }); 95 | JMenuItem getLinkItem = new JMenuItem("Get Link"); 96 | getLinkItem.addActionListener(e -> { 97 | HttpRequestResponse burpMessage = ((SharedLinksModel) j.getModel()).getBurpMessageAtIndex(j.getSelectedRow()); 98 | StringSelection stringSelection = new StringSelection(""); 99 | try { 100 | byte[] rawBytes; 101 | rawBytes = stripBurpMessage(burpMessage); 102 | stringSelection = new StringSelection( 103 | "burpsharedrequest/" + 104 | Base64.getEncoder().encodeToString(compress(new String(rawBytes)))); 105 | } catch (IOException ex) { 106 | sharedValues.getCallbacks().printError(ex.getMessage()); 107 | } 108 | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 109 | clipboard.setContents(stringSelection, null); 110 | JOptionPane.showMessageDialog(null, "Link has been added to the clipboard"); 111 | }); 112 | popupMenu.add(getLinkItem); 113 | popupMenu.add(getHTMLLinkItem); 114 | popupMenu.add(removeLinkItem); 115 | j.setComponentPopupMenu(popupMenu); 116 | JScrollPane sp = new JScrollPane(j); 117 | JPanel pane = new JPanel(new BorderLayout()); 118 | pane.add(sp, BorderLayout.CENTER); 119 | GridBagConstraints optionsPanelConstraints = new GridBagConstraints(); 120 | optionsPanelConstraints.fill = GridBagConstraints.BOTH; 121 | optionsPanelConstraints.weighty = 1; 122 | optionsPanelConstraints.weightx = 1; 123 | optionsPanelConstraints.gridwidth = 2; 124 | optionsPanelConstraints.gridx = 0; 125 | optionsPanelConstraints.gridy = 1; 126 | add(pane, optionsPanelConstraints); 127 | //end shareable links 128 | 129 | } 130 | 131 | private byte[] stripBurpMessage(HttpRequestResponse burpMessage) throws IOException { 132 | sharedValues.getCallbacks().printOutput(burpMessage.toString()); 133 | ByteArrayOutputStream myStream = new ByteArrayOutputStream(); 134 | byte divider = (byte) 127; 135 | myStream.write(burpMessage.getRequest()); 136 | myStream.write(divider); 137 | myStream.write(burpMessage.getResponse()); 138 | myStream.write(divider); 139 | myStream.write(burpMessage.getHttpService().getHost().getBytes()); 140 | myStream.write(divider); 141 | myStream.write(Integer.toString(burpMessage.getHttpService().getPort()).getBytes()); 142 | myStream.write(divider); 143 | myStream.write(burpMessage.getHttpService().getProtocol().getBytes()); 144 | sharedValues.getCallbacks().printOutput(myStream.toString()); 145 | return myStream.toByteArray(); 146 | } 147 | 148 | private static byte[] compress(String data) throws IOException { 149 | ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length()); 150 | GZIPOutputStream gzip = new GZIPOutputStream(bos); 151 | gzip.write(data.getBytes()); 152 | gzip.close(); 153 | byte[] compressed = bos.toByteArray(); 154 | bos.close(); 155 | return compressed; 156 | } 157 | 158 | private String generateHTMLLink(HttpRequestResponse burpMessage) { 159 | return "http://burpsharedrequest/"; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/sharerequests/ExtensionStateListener.java: -------------------------------------------------------------------------------- 1 | package sharerequests; 2 | 3 | import burp.IExtensionStateListener; 4 | 5 | public class ExtensionStateListener 6 | implements IExtensionStateListener { 7 | private final SharedValues sharedValues; 8 | 9 | public ExtensionStateListener(SharedValues sharedValues) { 10 | this.sharedValues = sharedValues; 11 | } 12 | 13 | public void extensionUnloaded() { 14 | this.sharedValues.getInnerServer().stopRunning(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/sharerequests/HttpRequestResponse.java: -------------------------------------------------------------------------------- 1 | package sharerequests; 2 | 3 | import burp.IHttpRequestResponse; 4 | import burp.IHttpService; 5 | 6 | import java.util.Arrays; 7 | 8 | public class HttpRequestResponse implements IHttpRequestResponse { 9 | 10 | private byte[] request; 11 | private byte[] response; 12 | private String comment; 13 | private String highlight; 14 | private HttpService httpService; 15 | 16 | HttpRequestResponse() { 17 | } 18 | 19 | public HttpRequestResponse(IHttpRequestResponse copy) { 20 | this.request = copy.getRequest(); 21 | this.response = copy.getResponse(); 22 | this.comment = copy.getComment(); 23 | this.highlight = copy.getHighlight(); 24 | this.httpService = new HttpService(copy.getHttpService()); 25 | } 26 | 27 | @Override 28 | public byte[] getRequest() { 29 | if(request == null) { 30 | return new byte[]{}; 31 | } 32 | return request; 33 | } 34 | 35 | @Override 36 | public void setRequest(byte[] message) { 37 | request = message; 38 | } 39 | 40 | @Override 41 | public byte[] getResponse() { 42 | 43 | if(response == null) { 44 | return new byte[]{}; 45 | } 46 | return response; 47 | } 48 | 49 | @Override 50 | public void setResponse(byte[] message) { 51 | response = message; 52 | } 53 | 54 | @Override 55 | public String getComment() { 56 | return comment; 57 | } 58 | 59 | @Override 60 | public void setComment(String comment) { 61 | this.comment = comment; 62 | } 63 | 64 | @Override 65 | public String getHighlight() { 66 | return highlight; 67 | } 68 | 69 | @Override 70 | public void setHighlight(String color) { 71 | this.highlight = color; 72 | } 73 | 74 | @Override 75 | public IHttpService getHttpService() { 76 | return httpService; 77 | } 78 | 79 | @Override 80 | public void setHttpService(IHttpService httpService) { 81 | this.httpService = new HttpService(httpService); 82 | } 83 | 84 | @Override 85 | public String toString() { 86 | return "HttpRequestResponse{" + 87 | "request=" + Arrays.toString(request) + 88 | ", response=" + Arrays.toString(response) + 89 | ", comment='" + comment + '\'' + 90 | ", highlight='" + highlight + '\'' + 91 | ", httpService=" + httpService; 92 | } 93 | 94 | @Override 95 | public boolean equals(Object o) { 96 | if (this == o) return true; 97 | if (o == null || getClass() != o.getClass()) return false; 98 | HttpRequestResponse that = (HttpRequestResponse) o; 99 | return Arrays.equals(request, that.request) && 100 | Arrays.equals(response, that.response); 101 | } 102 | 103 | @Override 104 | public int hashCode() { 105 | int result = Arrays.hashCode(request); 106 | result = 31 * result + Arrays.hashCode(response); 107 | return result; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/sharerequests/HttpService.java: -------------------------------------------------------------------------------- 1 | package sharerequests; 2 | 3 | import burp.IHttpService; 4 | 5 | public class HttpService implements IHttpService { 6 | private final String host; 7 | private final int port; 8 | private final String protocol; 9 | 10 | public HttpService() { 11 | host = ""; 12 | port = 0; 13 | protocol = ""; 14 | } 15 | 16 | HttpService(IHttpService copy) { 17 | this.host = copy.getHost(); 18 | this.port = copy.getPort(); 19 | this.protocol = copy.getProtocol(); 20 | } 21 | 22 | @Override 23 | public String getHost() { 24 | return host; 25 | } 26 | 27 | @Override 28 | public int getPort() { 29 | return port; 30 | } 31 | 32 | @Override 33 | public String getProtocol() { 34 | return protocol; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/sharerequests/ManualRequestSenderContextMenu.java: -------------------------------------------------------------------------------- 1 | package sharerequests; 2 | 3 | import burp.IContextMenuFactory; 4 | import burp.IContextMenuInvocation; 5 | import burp.IHttpRequestResponse; 6 | 7 | import javax.swing.*; 8 | import java.time.LocalDateTime; 9 | import java.time.format.DateTimeFormatter; 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | import java.util.List; 13 | import java.util.Objects; 14 | 15 | public class ManualRequestSenderContextMenu implements IContextMenuFactory { 16 | 17 | private final SharedValues sharedValues; 18 | 19 | public ManualRequestSenderContextMenu(SharedValues sharedValues) { 20 | this.sharedValues = sharedValues; 21 | } 22 | 23 | 24 | private Collection createLinkMenu(IContextMenuInvocation invocation) { 25 | JMenuItem click = new JMenuItem("create link"); 26 | click.addActionListener(e -> 27 | createLinkForSelectedRequests(invocation)); 28 | ArrayList menuList = new ArrayList<>(); 29 | menuList.add(click); 30 | return menuList; 31 | } 32 | 33 | private void createLinkForSelectedRequests(IContextMenuInvocation invocation) { 34 | HttpRequestResponse httpRequestResponse = 35 | new HttpRequestResponse(); 36 | for (IHttpRequestResponse message : invocation.getSelectedMessages()) { 37 | new SwingWorker() { 38 | @Override 39 | public Boolean doInBackground() { 40 | DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); 41 | LocalDateTime localDate = LocalDateTime.now(); 42 | httpRequestResponse.setRequest(message.getRequest()); 43 | httpRequestResponse.setHttpService(message.getHttpService()); 44 | sharedValues.getSharedLinksModel().addBurpMessage(httpRequestResponse, dtf.format(localDate)); 45 | JOptionPane.showMessageDialog(null, "Link has been generated! Goto the Burp Shared Requests tab to share it."); 46 | return Boolean.TRUE; 47 | } 48 | 49 | @Override 50 | public void done() { 51 | //we don't need to do any cleanup so this is empty 52 | } 53 | }.execute(); 54 | } 55 | 56 | } 57 | 58 | @Override 59 | public List createMenuItems(IContextMenuInvocation invocation) { 60 | ArrayList menues = new ArrayList<>(); 61 | if (Objects.equals(IContextMenuInvocation.CONTEXT_MESSAGE_EDITOR_REQUEST, invocation.getInvocationContext()) || 62 | Objects.equals(IContextMenuInvocation.CONTEXT_MESSAGE_VIEWER_REQUEST, invocation.getInvocationContext()) || 63 | Objects.equals(IContextMenuInvocation.CONTEXT_TARGET_SITE_MAP_TREE, invocation.getInvocationContext()) || 64 | Objects.equals(IContextMenuInvocation.CONTEXT_TARGET_SITE_MAP_TABLE, invocation.getInvocationContext())) { 65 | menues.addAll(createLinkMenu(invocation)); 66 | } 67 | return menues; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/sharerequests/ProxyListener.java: -------------------------------------------------------------------------------- 1 | package sharerequests; 2 | 3 | import burp.IHttpService; 4 | import burp.IInterceptedProxyMessage; 5 | import burp.IProxyListener; 6 | 7 | public class ProxyListener implements IProxyListener { 8 | 9 | private SharedValues sharedValues; 10 | 11 | public ProxyListener(SharedValues sharedValues) { 12 | this.sharedValues = sharedValues; 13 | } 14 | 15 | public void processProxyMessage(boolean isResponse, 16 | IInterceptedProxyMessage iInterceptedProxyMessage) { 17 | IHttpService httpService = iInterceptedProxyMessage.getMessageInfo().getHttpService(); 18 | if ("burpsharedrequest".equalsIgnoreCase(iInterceptedProxyMessage.getMessageInfo().getHttpService().getHost())) { 19 | System.out.println("got custom link request"); 20 | sharedValues.getCallbacks().issueAlert("This host created a custom repeater payload. If you did not paste this yourself " + 21 | "or clicked on a link you should leave that site."); 22 | iInterceptedProxyMessage.getMessageInfo().setHttpService(this.sharedValues.getCallbacks().getHelpers().buildHttpService( 23 | "127.0.0.1", this.sharedValues.getInnerServer().getSocket().getLocalPort(), httpService.getProtocol())); 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/sharerequests/SharedLinksModel.java: -------------------------------------------------------------------------------- 1 | package sharerequests; 2 | 3 | import burp.IBurpExtenderCallbacks; 4 | 5 | import javax.swing.table.AbstractTableModel; 6 | import java.util.ArrayList; 7 | 8 | class SharedLinksModel extends AbstractTableModel { 9 | 10 | private final ArrayList sharedRequests; 11 | private final IBurpExtenderCallbacks callbacks; 12 | 13 | SharedLinksModel(IBurpExtenderCallbacks callbacks) { 14 | this.callbacks = callbacks; 15 | sharedRequests = new ArrayList<>(); 16 | } 17 | 18 | void addBurpMessage(HttpRequestResponse burpMessage, String datetime) { 19 | sharedRequests.add(new SharedRequest(burpMessage, datetime)); 20 | fireTableDataChanged(); 21 | } 22 | 23 | void removeBurpMessage(int rowIndex) { 24 | sharedRequests.remove(rowIndex); 25 | fireTableDataChanged(); 26 | } 27 | 28 | @Override 29 | public int getRowCount() { 30 | return sharedRequests.size(); 31 | } 32 | 33 | @Override 34 | public String getColumnName(int col) { 35 | if (col == 0) { 36 | return "URL"; 37 | } else { 38 | return "Date Created"; 39 | } 40 | } 41 | 42 | @Override 43 | public int getColumnCount() { 44 | return 2; 45 | } 46 | 47 | @Override 48 | public Object getValueAt(int row, int col) { 49 | Object temp = null; 50 | if (col == 0) { 51 | temp = this.callbacks.getHelpers().analyzeRequest(sharedRequests.get(row).getRequestResponse()).getUrl().toString(); 52 | } else if (col == 1) { 53 | temp = sharedRequests.get(row).getDatetime(); 54 | } 55 | return temp; 56 | } 57 | 58 | HttpRequestResponse getBurpMessageAtIndex(int rowIndex) { 59 | return sharedRequests.get(rowIndex).getRequestResponse(); 60 | } 61 | 62 | @Override 63 | public Class getColumnClass(int columnIndex) { 64 | return String.class; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/sharerequests/SharedRequest.java: -------------------------------------------------------------------------------- 1 | package sharerequests; 2 | 3 | class SharedRequest { 4 | private HttpRequestResponse requestResponse; 5 | private String datetime; 6 | 7 | SharedRequest(HttpRequestResponse burpMessage, String datetime) { 8 | this.requestResponse = burpMessage; 9 | this.datetime = datetime; 10 | } 11 | 12 | HttpRequestResponse getRequestResponse() { 13 | return requestResponse; 14 | } 15 | 16 | String getDatetime() { 17 | return datetime; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/sharerequests/SharedValues.java: -------------------------------------------------------------------------------- 1 | package sharerequests; 2 | 3 | import burp.IBurpExtenderCallbacks; 4 | import com.google.gson.Gson; 5 | 6 | public class SharedValues { 7 | 8 | private IBurpExtenderCallbacks callbacks; 9 | private SharedLinksModel sharedLinksModel; 10 | private Gson gson; 11 | private CustomURLServer innerServer; 12 | 13 | public SharedValues(IBurpExtenderCallbacks callbacks) { 14 | this.callbacks = callbacks; 15 | this.sharedLinksModel = new SharedLinksModel(callbacks); 16 | this.gson = new Gson(); 17 | } 18 | 19 | IBurpExtenderCallbacks getCallbacks() { 20 | return callbacks; 21 | } 22 | 23 | SharedLinksModel getSharedLinksModel() { 24 | return sharedLinksModel; 25 | } 26 | 27 | Gson getGson() { 28 | return gson; 29 | } 30 | 31 | public void setInnerServer(CustomURLServer innerServer) { 32 | this.innerServer = innerServer; 33 | } 34 | 35 | CustomURLServer getInnerServer() { 36 | return innerServer; 37 | } 38 | } 39 | --------------------------------------------------------------------------------