Skip to content

Commit

Permalink
improved prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
tree-chtsec committed Nov 8, 2020
1 parent 6ca99d8 commit 87da5a3
Show file tree
Hide file tree
Showing 10 changed files with 1,112 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

# Source Map F1nder

This extension is for Burp Suite, finding sourceMap when passive/active scanning.

Tested on Burp Pro v2020.9.2

## Build

```bash
$ chmod +x compile.sh
$ ./compile.sh
```

## Screenshot

![sample-image](f1nder-screenshot.png)

## External Library

1. https://github.com/mitchhentges/json-parse
2. https://github.com/ooxi/jdatauri

Empty file added build/.gitignore
Empty file.
2 changes: 1 addition & 1 deletion compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

set -e

javac -d build src/main/burp/*.java
javac -d build src/main/*/*.java
(cd build; jar cvf sourceMap.jar *)
Binary file added f1nder-screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 88 additions & 15 deletions src/main/burp/BurpExtender.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.nio.charset.Charset;

import fuzzlesoft.JsonParse;
import jdatauri.DataUri;

public class BurpExtender implements IBurpExtender, IScannerCheck, ITab
{
private static final String EXT_NAME = "SourceMap F1nder";
private static final String SOURCE_MAP = "//# sourceMappingURL";
private static final String SOURCE_MAP = "//# sourceMappingURL=";

private IBurpExtenderCallbacks cbs;
private IExtensionHelpers helpers;
private JPanel tab;
private JTextArea textArea;
Expand Down Expand Up @@ -45,6 +54,8 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks)
textArea.setText("Hel1o ... Hack3r ...");

callbacks.registerScannerCheck(this);

cbs = callbacks;
}

//
Expand All @@ -55,21 +66,61 @@ public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks)
public List<IScanIssue> doPassiveScan(IHttpRequestResponse res) {
List<IScanIssue> result = new ArrayList<IScanIssue>();
IRequestInfo request = helpers.analyzeRequest(res);
java.net.URL urlReq = request.getUrl();
byte[] resBytes = res.getResponse();
String mimeType = helpers.analyzeResponse(resBytes).getStatedMimeType();
URL urlReq = request.getUrl();
IResponseInfo response = helpers.analyzeResponse(res.getResponse());
String mimeType = response.getStatedMimeType();
if ("script".equals(mimeType.toLowerCase())) {
textArea.append("\n" + "[+] Valid URL found: " + urlReq.toString());
String resText = helpers.bytesToString(resBytes);
textArea.append("\n" + "[+] Potential SourceMap URL found IN " + urlReq.toString());
//byte[] resBodyBytes = Arrays.copyOfRange(res.getResponse(), 0, response.getBodyOffset());
String resText = helpers.bytesToString(res.getResponse());
resText = resText.substring(response.getBodyOffset());
for (String line : resText.split("\\r?\\n")) {
if (line.indexOf(SOURCE_MAP) != -1) {
textArea.append("\n\t" + line);
result.add(new ScanIssue(urlReq, res));
break;
int occurIdx = line.indexOf(SOURCE_MAP);
if (occurIdx != -1) {

String data = null;
String mapUrl = line.substring(occurIdx + SOURCE_MAP.length());
if (mapUrl.toLowerCase().startsWith("data:")) {
DataUri u = DataUri.parse(mapUrl, Charset.forName("US-ASCII"));
data = helpers.bytesToString(u.getData());
textArea.append("\n\t" +
mapUrl.substring(0, 50) + "... " +
"Bytes Parsed: " + Integer.toString(data.length()));
}else {
//textArea.append("\n\t" + mapUrl);
// GET source map data from URL
if (!mapUrl.toLowerCase().startsWith("http")) {
String path = urlReq.getPath();
mapUrl = String.format("%s://%s%s/%s", urlReq.getProtocol(),
urlReq.getAuthority(), path.substring(0, path.lastIndexOf("/")), mapUrl);
}
try {
IHttpRequestResponse r2 = cbs.makeHttpRequest(
res.getHttpService(),
helpers.buildHttpRequest(new URL(mapUrl))
);
IResponseInfo mapResponse = helpers.analyzeResponse(r2.getResponse());
textArea.append("\n\t" + mapUrl + " => " + Short.toString(mapResponse.getStatusCode()));
if (mapResponse.getStatusCode() == 200) {
data = getResponseBodyStr(r2);
}
} catch (MalformedURLException e) {
System.err.println(e);
textArea.append("\n\t" + mapUrl + " => [Error]");
}
}
result.add(new ScanIssue(urlReq, res, mapUrl));

if (data != null)
{
for(String filename : extractSources(data))
{
textArea.append("\n\t\t" + filename);
}
}
}
}
}
resBytes = null;
return result;
}

Expand All @@ -90,6 +141,25 @@ public List<IScanIssue> doActiveScan(
return new ArrayList<IScanIssue>();
}

private String getResponseBodyStr(IHttpRequestResponse reqres)
{
byte[] resBytes = reqres.getResponse();
IResponseInfo response = helpers.analyzeResponse(resBytes);
//byte[] resBodyBytes = Arrays.copyOfRange(resBytes, 0, response.getBodyOffset());
return helpers.bytesToString(resBytes).substring(response.getBodyOffset());
}

private List<String> extractSources(String jsonData)
{
List<String> result = new ArrayList<String>();
Map<String, Object> map = JsonParse.map(jsonData);
//System.out.println((String) map.get("sources"));
for (String o : (List<String>) map.get("sources")) {
result.add(o);
}
return result;
}

//
// implement ITab
//
Expand Down Expand Up @@ -149,16 +219,18 @@ public void actionPerformed(ActionEvent e) {

private class ScanIssue implements IScanIssue
{
private java.net.URL url;
private URL url;
private IHttpRequestResponse rr;
private String mapUrl;

ScanIssue(java.net.URL _url, IHttpRequestResponse _rr)
ScanIssue(URL _url, IHttpRequestResponse _rr, String sourceMapURL)
{
url = _url;
rr = _rr;
mapUrl = sourceMapURL;
}

public java.net.URL getUrl()
public URL getUrl()
{
return url;
}
Expand Down Expand Up @@ -196,7 +268,8 @@ public String getRemediationBackground()
public String getIssueDetail()
{
return "Burp Scanner has analysed the following JS file for links:" +
"<b>" + url.toString() + "</b><br><br>";
"<b>" + url.toString() + "</b><br><br>" +
"<b>" + mapUrl + "</b><br></br>";
}

public String getRemediationDetail()
Expand Down
21 changes: 21 additions & 0 deletions src/main/fuzzlesoft/Constants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package fuzzlesoft;

/**
* @author mitch
* @since 30/12/15
*/
public class Constants {
public static boolean isWhitespace(char c) {
return c == ' '
|| c == '\n'
|| c == '\t';
}

public static boolean isLetter(char c) {
return c >= 'a' && c <= 'z';
}

public static boolean isNumberStart(char c) {
return (c >= '0' && c <= '9') || c == '-';
}
}
Loading

0 comments on commit 87da5a3

Please sign in to comment.