Skip to content

Commit

Permalink
Fix multipart enctype and request update.
Browse files Browse the repository at this point in the history
  • Loading branch information
rammarj committed Apr 28, 2023
1 parent c624322 commit 598a904
Show file tree
Hide file tree
Showing 15 changed files with 375 additions and 306 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.0.2] - 2023-04-28

### Added

- Get updated request when changing poc type from combo box in GUI.

### Fixed

- HTML POC with multipart encoding "enctype" form attribute.

## [0.0.1] - 2016-05-09
30 changes: 13 additions & 17 deletions src/main/java/burp/BurpExtender.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package burp;

import burp.pocs.Pocs;
import burp.tab.TabImpl;
import burp.tab.PocCreatorTab;
import burp.tab.PocTabManager;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import burp.pocs.IPoc;
import burp.pocs.PocGenerator;
import burp.pocs.Pocs;
import burp.tab.PocCreatorTab;
import burp.tab.PocTabManager;
import burp.tab.TabImpl;
import burp.util.Request;

/**
* CSRF POC Creator extension for Burp Suite
Expand All @@ -39,7 +38,7 @@ public BurpExtender() {
public void registerExtenderCallbacks(IBurpExtenderCallbacks ibec) {
this.burpExtenderCallbacks = ibec;
this.pocTabManager = new PocTabManager();
this.pocs = new Pocs(this.burpExtenderCallbacks.getHelpers());
this.pocs = new Pocs();
ibec.registerContextMenuFactory(this);
ibec.setExtensionName("CSRF PoC Creator");
this.burpExtenderCallbacks.addSuiteTab(new TabImpl("CSRF PoC", this.pocTabManager));
Expand All @@ -48,11 +47,9 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks ibec) {
while (pocKeys.hasNext()) {
String key = pocKeys.next();
JMenuItem item = new JMenuItem(key);
item.addActionListener(BurpExtender.this);
item.addActionListener(this);
this.menuItems.add(item);
}
this.burpExtenderCallbacks.printOutput("Burp csrf-poc-creator plugin for Burp Suite Free loaded!");
this.burpExtenderCallbacks.printOutput("Created by @rammarj");
}

/**
Expand Down Expand Up @@ -84,12 +81,11 @@ public void actionPerformed(ActionEvent e) {
for (IHttpRequestResponse ihrr : selectedMessages) {
try {
String selectedPOC = e.getActionCommand();
IPoc poc = this.pocs.getPoc(selectedPOC);
byte[] pocContent = poc.getPoc(ihrr);

PocCreatorTab pocCreatorTab = new PocCreatorTab(this.burpExtenderCallbacks, ihrr, this.pocs, pocContent);
pocCreatorTab.setSelectedItem(selectedPOC);
this.pocTabManager.addTab(String.valueOf(this.tabCount++), pocCreatorTab);
PocGenerator pg = this.pocs.getPoc(selectedPOC);
byte[] poc = pg.generate(Request.fromHTTPRequestResponse(ihrr, this.burpExtenderCallbacks.getHelpers()));
PocCreatorTab pct = new PocCreatorTab(this.burpExtenderCallbacks, ihrr, this.pocs, poc);
pct.setSelectedItem(selectedPOC);
this.pocTabManager.addTab(String.valueOf(this.tabCount++), pct);
} catch (Exception ex) {
JOptionPane.showMessageDialog(this.pocTabManager, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
Expand Down
75 changes: 0 additions & 75 deletions src/main/java/burp/Util.java

This file was deleted.

165 changes: 98 additions & 67 deletions src/main/java/burp/pocs/AjaxPoc.java
Original file line number Diff line number Diff line change
@@ -1,82 +1,113 @@

package burp.pocs;

import burp.BurpExtender;
import burp.IExtensionHelpers;
import burp.IHttpRequestResponse;
import java.util.List;

import burp.IRequestInfo;
import burp.Parameter;
import burp.Util;
import burp.util.Header;
import burp.util.Parameter;
import burp.util.Request;
import burp.util.Util;

/**
* Ajax CSRF POCs
*
* @author Joaquin R. Martinez <[email protected]>
*/
public class AjaxPoc implements IPoc {

private IExtensionHelpers helpers;

public AjaxPoc(IExtensionHelpers helpers) {
this.helpers = helpers;
public class AjaxPoc implements PocGenerator {

@Override
public byte[] generate(final Request request) {
String lineSeparator = System.lineSeparator();
String scriptTag = createScriptTag(request, lineSeparator);
String formTag = createFormTag(lineSeparator);
return createHTMLPage(scriptTag + formTag, lineSeparator).getBytes();
}

@Override
public byte[] getPoc(final IHttpRequestResponse request) {
String lineSeparator = System.lineSeparator();
StringBuilder pocString = new StringBuilder();
pocString.append("<!DOCTYPE html>").append(lineSeparator);
pocString.append("<html>").append(lineSeparator).append(" <!-- CSRF PoC - generated by Burp Suite plugin -->").append(lineSeparator);
pocString.append("<body>").append(lineSeparator).append(" <script>\n function submitRequest()").append(lineSeparator);
pocString.append(" {").append(lineSeparator).append(" var xhr = new XMLHttpRequest();").append(lineSeparator);
String method;
IRequestInfo requestInfo = helpers.analyzeRequest(request);
method = requestInfo.getMethod();
pocString.append(" xhr.open(\"").append(method).append("\", \"");
private String createFormTag(String lineSeparator) {
String form = " <form action=\"#\">" + lineSeparator;
form += " <input type=\"button\" value=\"Submit request\" onclick=\"submitRequest();\" />" + lineSeparator;
form += " </form>" + lineSeparator;
return form;
}

private String createScriptTag(final Request request, String lineSeparator) {
String script = " <script>" + lineSeparator;
script += " function submitRequest() {" + lineSeparator;
script += " var xhr = new XMLHttpRequest();" + lineSeparator;
if ("GET".equals(request.getMethod())) {
script += createGETXHRRequest(request.getUrl().toString(), lineSeparator);
} else {
script += createNotGETXHRRequest(request, lineSeparator);
}
script += " }" + lineSeparator;
script += " </script>" + lineSeparator;
return script;
}

private String createGETXHRRequest(String url, String lineSeparator) {
String getRequest = String.format(" xhr.open(\"GET\", \"%s\", true);%s", url, lineSeparator);
getRequest += " xhr.send();" + lineSeparator;
return getRequest;
}

private String createNotGETXHRRequest(final Request request, String lineSeparator) {
String postRequest = "";
postRequest += String.format(" xhr.open(\"%s\", \"%s\", true);%s", request.getMethod(),
request.getUrl().toString(), lineSeparator);
postRequest += addHeaders(request.getHeaders(), lineSeparator);
postRequest += " xhr.withCredentials = true;" + lineSeparator;
postRequest += " var body = " + createBody(request, lineSeparator) + lineSeparator;
postRequest += " var aBody = new Uint8Array(body.length);" + lineSeparator;
postRequest += " for (var i = 0; i < aBody.length; i++)" + lineSeparator;
postRequest += " aBody[i] = body.charCodeAt(i);" + lineSeparator;
postRequest += " xhr.send(new Blob([aBody]));" + lineSeparator;
return postRequest;
}

if ("GET".equals(method)) {
pocString.append(requestInfo.getUrl()).append("\", true);").append(lineSeparator);
pocString.append(" xhr.send();\n");
} else {
pocString.append(requestInfo.getUrl().toString()).append("\", true);").append(lineSeparator);
String body = helpers.bytesToString(request.getRequest()).substring(requestInfo.getBodyOffset());
body = Util.escape(body);
String accept = "*/*";
String content = "text/plain";
for (Parameter next : Util.parseHeaders(requestInfo.getHeaders())) {
if ("Accept".equalsIgnoreCase(next.getName())) {
accept = next.getValue();
}
if ("Content-Type".equalsIgnoreCase(next.getName())) {
content = next.getValue();
}
}
pocString.append(" xhr.setRequestHeader(\"Accept\", \"").append(accept).append("\");").append(lineSeparator);
pocString.append(" xhr.setRequestHeader(\"Content-Type\", \"").append(content).append("\");").append(lineSeparator);
pocString.append(" xhr.withCredentials = true;").append(lineSeparator).append(" var body = ");
private String addHeaders(final List<Header> headers, String lineSeparator) {
String accept = "*/*";
String content = "text/plain";
for (Parameter next : headers) {
if ("Accept".equalsIgnoreCase(next.getName()))
accept = next.getValue();
if ("Content-Type".equalsIgnoreCase(next.getName()))
content = next.getValue();
}

String pocString = String.format(" xhr.setRequestHeader(\"Accept\", \"%s\");", accept) + lineSeparator;
pocString += String.format(" xhr.setRequestHeader(\"Content-Type\", \"%s\");", content) + lineSeparator;
return pocString;
}

private String createHTMLPage(String body, String lineSeparator) {
String html = "<!DOCTYPE html>" + lineSeparator;
html += "<html>" + lineSeparator;
html += " <!-- CSRF PoC - generated by Burp Suite plugin -->" + lineSeparator;
html += "<body>" + lineSeparator;
html += body;
html += "</body>" + lineSeparator;
html += "</html>";
return html;
}

private String createBody(final Request request, final String lineSeparator) {
String body = Util.escape(request.getRequestBody());
String formattedBody = String.format("\"%s\";%s", body, lineSeparator);
if (request.getContentType() == IRequestInfo.CONTENT_TYPE_MULTIPART) {
formattedBody = createMultipartBody(body, lineSeparator);
}
return formattedBody;
}

private String createMultipartBody(final String body, final String lineSeparator) {
String formattedLines = "";
String[] lines = body.split("\r\n");
for (int i = 0; i < lines.length; i++) {
String endLine = (i == lines.length - 1) ? ";" : " +";
formattedLines += String.format("\"%s\\r\\n\"%s%s", lines[i], endLine, lineSeparator);
}
return formattedLines;
}

if (requestInfo.getContentType() == IRequestInfo.CONTENT_TYPE_MULTIPART) {
String[] lines = body.split("\r\n");
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
if (i == lines.length - 1) {
pocString.append("\"").append(line).append("\\r\\n\";").append(lineSeparator);
} else {
pocString.append("\"").append(line).append("\\r\\n\" +").append(lineSeparator);
}
}
} else {
pocString.append("\"").append(body).append("\";").append(lineSeparator);
}
pocString.append(" var aBody = new Uint8Array(body.length);").append(lineSeparator);
pocString.append(" for (var i = 0; i < aBody.length; i++)").append(lineSeparator);
pocString.append(" aBody[i] = body.charCodeAt(i); ").append(lineSeparator);
pocString.append(" xhr.send(new Blob([aBody]));").append(lineSeparator);
}
pocString.append(" }").append(lineSeparator).append(" </script>\n <form action=\"#\">").append(lineSeparator);
pocString.append(" <input type=\"button\" value=\"Submit request\" onclick=\"submitRequest();\" />").append(lineSeparator);
pocString.append(" </form>").append(lineSeparator).append(" </body>").append(lineSeparator).append("</html>");
return pocString.toString().getBytes();
}

}
Loading

0 comments on commit 598a904

Please sign in to comment.