Skip to content

Commit

Permalink
Tweak defaults & stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
albinowax committed Aug 7, 2024
1 parent ad3f8e9 commit 712b0f2
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 27 deletions.
Binary file modified bulkScan-all.jar
Binary file not shown.
16 changes: 8 additions & 8 deletions proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
Param Miner has a feature called "Identify proxyable destinations".
This can lead to high-impact discoveries, such as systems that are meant to be internal-only.

It will work out of the box, but a little configuration will make it a lot more powerful.

- Tick `external subdomain lookup` to dynmically look up known subdomains using columbus.elmasy.com. Warning: this discloses the top-level private domain that you are targeting. That's why it's not enabled by default.
- Use `subdomains-generic` to specify the path to your own subdomain wordlist. Download them from sources like: https://wordlists.assetnote.io/ and https://github.com/danielmiessler/SecLists/tree/master/Discovery/DNS
- Use `subdomains-specific` to specify a folder blah


It will work out of the box, but a little configuration will make it a lot more powerful:

Exploring known subdomains (highly recommended)
- Tick `external subdomain lookup` to dynamically look up known subdomains using columbus.elmasy.com. Warning: this discloses the top-level private domain that you are targeting. For example, if you target `beta.api.example.com`, Elmasy will see `example.com` in their server logs. That's why it's not enabled by default.
- If you have an alternative source of subdomains from your own recon, you can integrate these by placing them into a folder in the format /folder/top-level-domain, and using the `subdomains-specific` setting to load it. For example, if you set the path to `/hostnames/$domain` and scan `proxy.example.com`, Param Miner will load domains from `/hostnames/example.com`

Additional hostname wordlists:
- Use `subdomains-generic` to specify the path to your own subdomain wordlist. Download them from sources like: https://wordlists.assetnote.io/ and https://github.com/danielmiessler/SecLists/tree/master/Discovery/DNS

For further information, please refer to https://portswigger.net/research/listen-to-the-whispers

For further information, please refer to https://portswigger.net/research/listen-to-the-whispers
If it still makes no sense, please let me know - I want people to get the most out of this tool!
1 change: 1 addition & 0 deletions src/burp/BurpExtender.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) {

// param-guess only
//guessSettings.importSettings(globalSettings);
guessSettings.register("quantitative diff keys", "time", "Use timing info to detect parameters. Disable this to make Param Miner faster."); // this overwrites the setting from bulkScan
guessSettings.register("learn observed words", false);
guessSettings.register("skip boring words", true, "When mining headers, don't check for well known and typically not very exciting headers");
guessSettings.register("only report unique params", false, "Only report a parameter with a given name once, regardless of how many endpoints are scanned");
Expand Down
18 changes: 17 additions & 1 deletion src/burp/DiscoveredParam.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package burp;

import burp.api.montoya.core.ByteArray;
import burp.api.montoya.http.message.HttpRequestResponse;
import burp.api.montoya.http.message.requests.HttpRequest;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -103,6 +107,8 @@ public void report() {

String typeName = BulkUtilities.getNameFromType(type);
String title = "Secret input: " + typeName;
String detail = "Unlinked parameter identified. ";

if (!cachePoisoned && canSeeCache) {
title = "Secret uncached input: " + typeName;
}
Expand All @@ -117,13 +123,23 @@ public void report() {

if (dynamicOnly) {
title += " [dynamic-only]";
detail += "This parameter only causes a response difference when using a fresh value. This suggests that it may be included in the server's cache key. Consider trying cache poisoning attacks on the target. ";
}

if (magicIP) {
title += " [magic-ip]";
}

BulkUtilities.callbacks.addScanIssue(BulkUtilities.reportReflectionIssue(evidence.toArray(new Attack[2]), baseRequestResponse, title, "Unlinked parameter identified."));
if (!BulkUtilities.isBurpPro()) { // || Utilities.globalSettings.getBoolean("report to organizer")
// todo add some details on the attributes to look at here
// HttpRequest directRequest = HttpRequest.httpRequest(directService, ByteArray.byteArray(evidence.get(0).getFirstRequest().getRequest()));
// HttpRequestResponse resp = Utilities.montoyaApi.http().sendRequest(directRequest);
// Scan.reportToOrganiser(title, null, detail, Collections.singletonList(resp));
// todo just need one that doesn't have a null response?
//Lensmine.sendToOrganiser(Utilities.buildMontoyaResp(evidence.get(0).), detail);
}

BulkUtilities.callbacks.addScanIssue(BulkUtilities.reportReflectionIssue(evidence.toArray(new Attack[2]), baseRequestResponse, title, detail));
}


Expand Down
7 changes: 6 additions & 1 deletion src/burp/Lenscrack.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@ public class Lenscrack extends Scan {
Lenscrack(String name) {
super(name);
scanSettings.register("overlong-detection", true, "Use overlong dns labels for detection");
scanSettings.register("auto-scan for proxyable destinations", false, "If wildcard-routing is detected, try to enumerate accessible domains. To configure related settings, run 'Identify proxyable destinations'");
scanSettings.register("auto-scan for proxyable destinations", true, "If wildcard-routing is detected, try to enumerate accessible domains. To configure related settings, run 'Identify proxyable destinations'");
scanSettings.register("mining: filter 500s", true, "Don't report hostnames that return a 50X status");
scanSettings.register("subdomains-builtin", true, "Use the builtin wordlist to discover interesting proxyable destinations");
scanSettings.register("subdomains-generic", "", "/path/to/wordlist");
scanSettings.register("subdomains-specific", "", "Format: /subdomains/$domain. Read https://github.com/PortSwigger/param-miner/proxy.md for further info.");
scanSettings.register("external subdomain lookup", false, "Look up subdomains using columbus.elmasy.com. Warning: this discloses the top-level private domain that you are targeting.");
scanSettings.register("I read the docs", false, "Read the docs at https://github.com/PortSwigger/param-miner/proxy.md then check this box to stop nagging me to read the docs.");
}

static String TARGETHEADER = "Host";
Expand Down
6 changes: 3 additions & 3 deletions src/burp/Lensmine.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public class Lensmine extends Scan {
public Lensmine(String name) {
super(name);
scanSettings.register("mining: filter 500s", true, "Don't report hostnames that return a 50X status");
scanSettings.register("subdomains-builtin", true, "");
scanSettings.register("subdomains-builtin", true, "Use the builtin wordlist to discover interesting proxyable destinations");
scanSettings.register("subdomains-generic", "", "/path/to/wordlist");
scanSettings.register("subdomains-specific", "", "/subdomains/$domain");
scanSettings.register("subdomains-specific", "", "Format: /subdomains/$domain. Read https://github.com/PortSwigger/param-miner/proxy.md for further info.");
scanSettings.register("external subdomain lookup", false, "Look up subdomains using columbus.elmasy.com. Warning: this discloses the top-level private domain that you are targeting.");
scanSettings.register("I read the docs", false, "Stop nagging me to read the docs.");
scanSettings.register("I read the docs", false, "Read the docs at https://github.com/PortSwigger/param-miner/proxy.md then check this box to stop nagging me to read the docs.");
}

static MineFindings mineSubdomains(byte[] req, IHttpService service, String domain, int maxDomainsToCheck) {
Expand Down
17 changes: 15 additions & 2 deletions src/burp/ParamGuesser.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;

import static burp.Lenscrack.reportPairs;


class SimpleScan implements Runnable, IExtensionStateListener {

Expand Down Expand Up @@ -292,8 +294,9 @@ private ArrayList<Attack> guessParams(ParamAttack state) {
}
}


Probe validParam = new Probe("Found unlinked param: " + submission, 4, submission);
String title = "Found unlinked param: " + submission;

Probe validParam = new Probe(title, 4, submission);
validParam.setEscapeStrings(Keysmith.permute(submission), Keysmith.permute(submission, false));
validParam.setRandomAnchor(false);
validParam.setPrefix(Probe.REPLACE);
Expand All @@ -305,12 +308,22 @@ private ArrayList<Attack> guessParams(ParamAttack state) {
continue;
}

// // if timing evidence only, double-confirm
// if (true) {
// AttackPair pair = new AttackPair(title, submission, submission+"z", true);
// pair.attempt(baseRequestResponse, injector.getInsertionPoint());
// if (pair.valid()) {
// reportPairs("Time-based param detection: "+submission, "", "", baseRequestResponse.getRequest(), pair.result);
// }
// }

state.alreadyReported.add(submission);
BulkUtilities.reportedParams.add(submission);
state.alreadyReported.add(submission.split("~", 2)[0]);
BulkUtilities.reportedParams.add(submission.split("~", 2)[0]);
BulkUtilities.out("Identified parameter on " + targetURL + ": " + submission);


DiscoveredParam discoveredParam = new DiscoveredParam(confirmed, injector, submission, failAttack, paramGuess, baseRequestResponse);
discoveredParam.exploreAndReport();
base = state.updateBaseline();
Expand Down
19 changes: 7 additions & 12 deletions src/burp/TimeInjector.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package burp;

import burp.api.montoya.http.message.params.HttpParameter;
import burp.api.montoya.http.message.requests.HttpRequest;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;

Expand All @@ -26,16 +21,16 @@ List<IScanIssue> doScan(IHttpRequestResponse baseRequestResponse, IScannerInsert

// todo scan path-params for double URL encoding?

attacks.creatAttackPair("Rest", baseValue+"%23"+canary, baseValue+"%21"+canary);
//attacks.createAttackPair("Rest", baseValue+"%23"+canary, baseValue+"%21"+canary);
//attacks.creatAttackPair("EL-RCE", baseValue+"${\"x\"}", baseValue+"${\"x\"\"}");
//attacks.creatAttackPair("URL-v3", baseValue+"#"+canary, baseValue+"$"+canary);
attacks.creatAttackPair("Escape-sequence-cb", canary+"\\u0061", canary+"\\v0061");
attacks.creatAttackPair("Double-quote", canary+"x\"\\yz", canary+"x\\\"z");
attacks.creatAttackPair("Single-quote", canary+"x'\\z", canary+"x\\'z");
attacks.creatAttackPair("SQL-apos", canary+"x''z", canary+"x'z'z");
attacks.createAttackPair("Escape-sequence-cb", canary+"\\u0061", canary+"\\v0061");
attacks.createAttackPair("Double-quote", canary+"x\"\\yz", canary+"x\\\"z");
attacks.createAttackPair("Single-quote", canary+"x'\\z", canary+"x\\'z");
attacks.createAttackPair("SQL-apos", canary+"x''z", canary+"x'z'z");
//
//
attacks.creatAttackPair("XML Entity-cb", canary+"&amp;", canary+"&amx;");
attacks.createAttackPair("XML Entity-cb", canary+"&amp;", canary+"&amx;");
//attacks.creatAttackPair("XML quote", "x\" y='", "x'\" y=\"");
//attacks.creatAttackPair("SQL LIKE", "a%", "Z%");
//attacks.creatAttackPair("SQL LIKEDUD", "!", "[!]");
Expand Down Expand Up @@ -102,7 +97,7 @@ public AttackPairFactory(IHttpRequestResponse baseRequestResponse, IScannerInser
}
IScannerInsertionPoint iScannerInsertionPoint;

AttackPair creatAttackPair(String title, String left, String right) {
AttackPair createAttackPair(String title, String left, String right) {
AttackPair pair = new AttackPair(title, left, right, true);
pairs.put(title, pair);
pair.attempt(baseRequestResponse, iScannerInsertionPoint);
Expand Down
4 changes: 4 additions & 0 deletions src/burp/ValueProbes.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
public class ValueProbes
{
static boolean triggersPingback(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) {
if (!BulkUtilities.isBurpPro()) {
return false;
}

String collab = BasicCollab.getPayload();
Resp resp = Scan.request(baseRequestResponse.getHttpService(), insertionPoint.buildRequest(collab.getBytes()));
if (BasicCollab.checkPayload(collab.split("[.]")[0])) {
Expand Down

0 comments on commit 712b0f2

Please sign in to comment.