Projects STRLCPY param-miner Commits 322d9388
🤬
  • ■ ■ ■ ■ ■ ■
    src/burp/HeaderMutationGuesser.java
    skipped 1 lines
    2 2  
    3 3  import org.graalvm.compiler.core.common.util.Util;
    4 4  
     5 +import java.net.URL;
    5 6  import java.nio.charset.StandardCharsets;
    6 7  import java.util.ArrayList;
    7 8  import java.util.HashMap;
    skipped 1 lines
    9 10  
    10 11  public class HeaderMutationGuesser {
    11 12   private ConfigurableSettings config;
    12  - private IHttpRequestResponse req;
     13 + private byte[] req;
    13 14   private IHttpService service;
    14 15   public HashMap<String, IHttpRequestResponse[]> evidence;
    15 16   private String[][] testHeaders;
     17 + private URL url;
    16 18  
    17 19   HeaderMutationGuesser(IHttpRequestResponse req, ConfigurableSettings config) {
    18  - this.req = req;
     20 + this.url = Utilities.getURL(req);
     21 + this.req = req.getRequest();
     22 + if (Utilities.isHTTP2(this.req)) {
     23 + this.req = Utilities.convertToHttp1(this.req);
     24 + }
    19 25   this.config = config;
    20 26   this.service = req.getHttpService();
    21 27   this.evidence = new HashMap<String, IHttpRequestResponse[]>();
    skipped 5 lines
    27 33  
    28 34   // Returns the mutation names used by HeaderMutator
    29 35   public ArrayList<String> guessMutations() {
    30  - byte[] baseReq = this.removeHeader(this.req.getRequest(), "Content-Length");
     36 + byte[] baseReq = this.removeHeader(this.req, "Content-Length");
    31 37   ArrayList<String> ret = new ArrayList<String>();
    32 38   HeaderMutator mutator = new HeaderMutator();
    33 39  
    skipped 68 lines
    102 108   Iterator<String> iterator = mutations.iterator();
    103 109   while (iterator.hasNext()) {
    104 110   String mutation = iterator.next();
    105  - String urlStr = Utilities.getURL(this.req).toString();
    106  - Utilities.out("Found mutation against " + urlStr + ": " + mutation);
     111 + Utilities.out("Found mutation against " + this.url + ": " + mutation);
    107 112   IHttpRequestResponse[] evidence = this.evidence.get(mutation);
    108 113   IHttpService service = evidence[0].getHttpService();
    109 114   Utilities.callbacks.addScanIssue(new CustomScanIssue(
    skipped 16 lines
    126 131   private IHttpRequestResponse requestHeader(byte[] baseReq, byte[] header) {
    127 132   byte[] req = this.addHeader(baseReq, header);
    128 133   req = Utilities.addCacheBuster(req, Utilities.generateCanary());
    129  - return Utilities.attemptRequest(this.service, req);
     134 + return Utilities.attemptRequest(this.service, req, true);
    130 135   }
    131 136  
    132 137   private byte[] removeHeader(byte[] req, String headerName) {
    skipped 57 lines
  • ■ ■ ■ ■ ■ ■
    src/burp/ParamGuesser.java
    skipped 30 lines
    31 31   private ParamGrabber paramGrabber;
    32 32   private ParamAttack attack;
    33 33   private ConfigurableSettings config;
     34 + private boolean forceHttp1;
    34 35  
    35 36   private byte[] staticCanary;
    36 37  
    skipped 5 lines
    42 43   this.stop = stop;
    43 44   this.taskEngine = taskEngine;
    44 45   this.config = config;
     46 + this.forceHttp1 = this.config.getBoolean("identify smuggle mutations") && this.type == Utilities.PARAM_HEADER;
    45 47   staticCanary = config.getString("canary").getBytes();
    46 48   }
    47 49  
    48  - ParamGuesser(ParamAttack attack, ThreadPoolExecutor taskEngine, ConfigurableSettings config) {
     50 + ParamGuesser(ParamAttack attack, ThreadPoolExecutor taskEngine, ConfigurableSettings config, boolean forceHttp1) {
    49 51   this.attack = attack;
    50 52   this.req = attack.getBaseRequestResponse();
    51 53   this.taskEngine = taskEngine;
    52 54   this.config = config;
     55 + this.forceHttp1 = forceHttp1;
    53 56   staticCanary = config.getString("canary").getBytes();
    54 57   }
    55 58  
    skipped 3 lines
    59 62   if (req.getResponse() == null) {
    60 63   Utilities.log("Baserequest has no response - fetching...");
    61 64   try {
    62  - req = Utilities.callbacks.makeHttpRequest(req.getHttpService(), req.getRequest());
     65 + req = Utilities.callbacks.makeHttpRequest(req.getHttpService(), req.getRequest(), this.forceHttp1);
    63 66   } catch (RuntimeException e) {
    64 67   Utilities.out("Aborting attack due to failed lookup");
    65 68   return;
    skipped 191 lines
    257 260   continue;
    258 261   }
    259 262  
    260  - Attack WAFCatcher = new Attack(Utilities.attemptRequest(service, Utilities.addOrReplaceHeader(baseRequestResponse.getRequest(), "junk-header", submission)));
    261  - WAFCatcher.addAttack(new Attack(Utilities.attemptRequest(service, Utilities.addOrReplaceHeader(baseRequestResponse.getRequest(), "junk-head", submission))));
     263 + Attack WAFCatcher = new Attack(Utilities.attemptRequest(service, Utilities.addOrReplaceHeader(baseRequestResponse.getRequest(), "junk-header", submission), this.forceHttp1));
     264 + WAFCatcher.addAttack(new Attack(Utilities.attemptRequest(service, Utilities.addOrReplaceHeader(baseRequestResponse.getRequest(), "junk-head", submission), this.forceHttp1)));
    262 265   if (!Utilities.similar(WAFCatcher, confirmParamGuess)) {
    263 266   Probe validParam = new Probe("Found unlinked param: " + submission, 4, submission);
    264 267   validParam.setEscapeStrings(Keysmith.permute(submission), Keysmith.permute(submission, false));
    skipped 55 lines
    320 323   altBase.addAttack(new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase)));
    321 324   injector.probeAttack(submission, mutation);
    322 325  
    323  - paramGrab = new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase));
     326 + paramGrab = new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase, this.forceHttp1));
    324 327   if (!Utilities.similar(altBase, paramGrab)) {
    325 328  
    326 329   if (candidates.size() > 1) {
    skipped 10 lines
    337 340   evidence[2] = paramGrab.getFirstRequest();
    338 341   Utilities.callbacks.addScanIssue(new CustomScanIssue(service, Utilities.getURL(baseRequestResponse), evidence, "Secret parameter", "Parameter name: '" + candidates + "'. Review the three requests attached in chronological order.", "Medium", "Tentative", "Investigate"));
    339 342  
    340  - altBase = new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase));
    341  - altBase.addAttack(new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase)));
    342  - altBase.addAttack(new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase)));
    343  - altBase.addAttack(new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase)));
     343 + altBase = new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase, this.forceHttp1));
     344 + altBase.addAttack(new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase, this.forceHttp1)));
     345 + altBase.addAttack(new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase, this.forceHttp1)));
     346 + altBase.addAttack(new Attack(Utilities.callbacks.makeHttpRequest(service, invertedBase, this.forceHttp1)));
    344 347   }
    345 348   }
    346 349   }
    skipped 3 lines
    350 353  
    351 354  
    352 355   state.incrStop();
    353  - taskEngine.execute(new ParamGuesser(state, taskEngine, config));
     356 + taskEngine.execute(new ParamGuesser(state, taskEngine, config, this.forceHttp1));
    354 357  
    355 358   return attacks;
    356 359   }
    skipped 418 lines
  • ■ ■ ■ ■ ■ ■
    src/burp/TriggerParamGuesser.java
    skipped 4 lines
    5 5   
    6 6  import java.awt.event.ActionEvent;
    7 7  import java.awt.event.ActionListener;
     8 +import java.nio.charset.StandardCharsets;
    8 9  import java.util.*;
    9 10  import java.util.concurrent.ThreadPoolExecutor;
    10 11   
    skipped 13 lines
    24 25   this.taskEngine = taskEngine;
    25 26   this.paramGrabber = paramGrabber;
    26 27   this.backend = backend;
    27  - this.reqs = reqs;
    28 28   this.type = type;
     29 + this.reqs = reqs;
    29 30   }
    30 31   
    31 32   public void actionPerformed(ActionEvent e) {
    skipped 18 lines
    50 51   
    51 52   ArrayList<IHttpRequestResponse> reqlist = new ArrayList<>(Arrays.asList(reqs));
    52 53   Collections.shuffle(reqlist);
     54 + 
     55 + // If guessing smuggling mutations, downgrade HTTP/2 requests to HTTP/1.1
     56 + if (config.getBoolean("identify smuggle mutations") && this.type == Utilities.PARAM_HEADER) {
     57 + Iterator iterator = reqlist.iterator();
     58 + for (int i = 0; i < reqlist.size(); i++) {
     59 + IHttpRequestResponse req = reqlist.get(i);
     60 + if (!Utilities.isHTTP2(req.getRequest())) {
     61 + continue;
     62 + }
     63 + byte[] downgraded = Utilities.convertToHttp1(req.getRequest());
     64 + String host = req.getHttpService().getHost();
     65 + int port = req.getHttpService().getPort();
     66 + String proto = req.getHttpService().getProtocol();
     67 + IHttpService service = Utilities.helpers.buildHttpService(host, port, proto);
     68 + 
     69 + IHttpRequestResponse newReq = Utilities.attemptRequest(service, downgraded, true);
     70 + reqlist.set(i, newReq);
     71 + this.reqs[i] = newReq;
     72 + }
     73 + }
    53 74   
    54 75   int cache_size = thread_count;
    55 76   if (config.getBoolean("max one per host")) {
    skipped 74 lines
Please wait...
Page is in error, reload to recover