diff --git a/Build/burp/BurpExtender$1.class b/Build/burp/BurpExtender$1.class new file mode 100644 index 0000000..5e8c1f7 Binary files /dev/null and b/Build/burp/BurpExtender$1.class differ diff --git a/Build/burp/BurpExtender$BodyType.class b/Build/burp/BurpExtender$BodyType.class new file mode 100644 index 0000000..7764c8c Binary files /dev/null and b/Build/burp/BurpExtender$BodyType.class differ diff --git a/Build/burp/BurpExtender.class b/Build/burp/BurpExtender.class new file mode 100644 index 0000000..94a91ad Binary files /dev/null and b/Build/burp/BurpExtender.class differ diff --git a/BurpExtender.java b/BurpExtender.java new file mode 100644 index 0000000..1fc4d3d --- /dev/null +++ b/BurpExtender.java @@ -0,0 +1,179 @@ +package burp; + +import java.util.*; +import java.awt.datatransfer.*; +import java.awt.event.*; +import java.awt.Toolkit; +import java.io.UnsupportedEncodingException; +import javax.swing.JMenuItem; + +public class BurpExtender implements IBurpExtender, IContextMenuFactory, ClipboardOwner +{ + private IExtensionHelpers helpers; + + private final static String NAME = "Copy as Go HTTP"; + private final static String[] GO_ESCAPE = new String[256]; + private int currentID = 0; + private int currentTotal = 0; + + static { + for (int i = 0x00; i <= 0xFF; i++) GO_ESCAPE[i] = String.format("\\x%02x", i); + for (int i = 0x20; i < 0x80; i++) GO_ESCAPE[i] = String.valueOf((char)i); + GO_ESCAPE['\n'] = "\\n"; + GO_ESCAPE['\r'] = "\\r"; + GO_ESCAPE['\t'] = "\\t"; + GO_ESCAPE['"'] = "\\\""; + GO_ESCAPE['\\'] = "\\\\"; + } + + @Override + public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) + { + helpers = callbacks.getHelpers(); + callbacks.setExtensionName(NAME); + callbacks.registerContextMenuFactory(this); + } + + @Override + public List createMenuItems(IContextMenuInvocation invocation) { + final IHttpRequestResponse[] messages = invocation.getSelectedMessages(); + if (messages == null || messages.length == 0) return null; + JMenuItem i = new JMenuItem(NAME); + i.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + copyMessages(messages); + } + }); + return Collections.singletonList(i); + } + + private void copyMessages(IHttpRequestResponse[] messages) { + StringBuilder goSrc = new StringBuilder(""); + buildBoilerCodeStart(goSrc); + + this.currentID = 0; + this.currentTotal = messages.length; + + for (IHttpRequestResponse message : messages) { + this.currentID += 1; + IRequestInfo ri = helpers.analyzeRequest(message); + byte[] req = message.getRequest(); + + goSrc.append(String.format(" method"+ this.currentID +" := \"%s\"\n", escapeGoString(ri.getMethod()))); + goSrc.append(String.format(" url"+ this.currentID +" := \"%s\"\n", escapeGoString(ri.getUrl().toString()))); + goSrc.append("\n"); + goSrc.append(" // making body\n"); + processBody(goSrc, req, ri.getBodyOffset()); + buildBoilerCodeRequest(goSrc); + processHeaders(goSrc, ri.getHeaders()); + buildBoilerCodeSend(goSrc); + } + goSrc.append(" return res\n"); + goSrc.append("}\n"); + + Toolkit.getDefaultToolkit().getSystemClipboard() + .setContents(new StringSelection(goSrc.toString()), this); + } + + public String escapeGoString(String src) { + StringBuilder buildStr = new StringBuilder(""); + for (int i=0;i headers) { + boolean firstHeader = true; + for (String header : headers) { + int colonPos = header.indexOf(':'); + if (colonPos == -1) continue; + if (header.substring(0,colonPos).toLowerCase().equals("cookie")) { + goSrc.append(" newRequest"+ this.currentID +".Header.Add(\""); + goSrc.append(header, 0, colonPos); + goSrc.append("\",\""); + goSrc.append(header, colonPos + 2, header.length()); + goSrc.append("\")\n"); + goSrc.append(" urlStruct"+ this.currentID +", _ := url.Parse(url"+ this.currentID +")\n"); + goSrc.append(" urlStruct"+ this.currentID +".Path = \"/\"\n"); + goSrc.append(" client.Jar.SetCookies(urlStruct"+ this.currentID +", newRequest"+ this.currentID +".Cookies())\n"); + goSrc.append(" newRequest"+ this.currentID +".Header.Del(\""+header.substring(0,colonPos)+"\")\n"); + } else { + goSrc.append(" newRequest"+ this.currentID +".Header.Add(\""); + goSrc.append(header, 0, colonPos); + goSrc.append("\",\""); + goSrc.append(header, colonPos + 2, header.length()); + goSrc.append("\")\n"); + } + } + } + + private void processBody(StringBuilder goSrc, byte[] fullRequest, int start) { + byte[] bodyBytes = Arrays.copyOfRange(fullRequest, start, fullRequest.length); + String str = new String(bodyBytes); + String bodyStr = String.format(" body"+ this.currentID +" := strings.NewReader(\"%s\")\n", escapeGoString(str)); + goSrc.append(bodyStr); + } + + + @Override + public void lostOwnership(Clipboard aClipboard, Transferable aContents) {} +} diff --git a/README.md b/README.md index cd927be..9aab422 100644 --- a/README.md +++ b/README.md @@ -1 +1,22 @@ -# copy-as-go-http \ No newline at end of file +# Burp Extension - copy-as-go-http + +It's a Burp extensions that generates Go code that would trigger the active request(s) on Burp. + +## Getting Started + +Run build.sh to build the Java plugin. + +To install it on Burp, use the 'extender' option on Burp + +## Versioning + +2019-04-27 1.0 Release + +## Authors + +* **Samuel Pua** - *Initial work* - [telboon](https://github.com/telboon) + +## License + +This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details + diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..9fb2770 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#! /bin/bash +javac -target 1.8 -source 1.8 -cp ~/BurpSuitePro/burpsuite_pro.jar BurpExtender.java -d Build +jar -cvf copy-as-go-http.jar -C Build/ . diff --git a/copy-as-go-http.jar b/copy-as-go-http.jar new file mode 100644 index 0000000..1beadef Binary files /dev/null and b/copy-as-go-http.jar differ