Projects STRLCPY param-miner Commits b7ebe91a
🤬
  • albinowaxUtils-all.jar
    Binary file.
  • ■ ■ ■ ■ ■ ■
    src/burp/HeaderMutationGuesser.java
    1 1  package burp;
    2 2  
     3 +import org.graalvm.compiler.core.common.util.Util;
     4 +
    3 5  import java.nio.charset.StandardCharsets;
    4 6  import java.util.ArrayList;
    5 7  import java.util.HashMap;
    skipped 168 lines
  • ■ ■ ■ ■ ■ ■
    src/burp/HeaderMutator.java
    1  -package burp;
    2  -
    3  -import java.io.ByteArrayOutputStream;
    4  -import java.io.IOException;
    5  -import java.nio.charset.StandardCharsets;
    6  -import java.util.ArrayList;
    7  -import java.util.Arrays;
    8  -import java.util.Iterator;
    9  -
    10  -public class HeaderMutator {
    11  - public ArrayList<String> mutations;
    12  -
    13  - HeaderMutator() {
    14  - this.mutations = new ArrayList<String>();
    15  -
    16  - this.registerMutation("nospace");
    17  - this.registerMutation("underscore");
    18  - this.registerMutation("cr-hyphen");
    19  - this.registerMutation("letter-hyphen");
    20  -
    21  - this.registerMutation("linePrefixSpace");
    22  - this.registerMutation("linePrefixTab");
    23  - this.registerMutation("linePrefixVTab");
    24  - this.registerMutation("linePrefixNull");
    25  -
    26  - this.registerMutation("lineAppendixNull");
    27  -
    28  - this.registerMutation("colonPreNull");
    29  - this.registerMutation("colonPreSpace");
    30  - this.registerMutation("colonPreTab");
    31  - this.registerMutation("colonPreVTab");
    32  - this.registerMutation("colonPreCR");
    33  - this.registerMutation("colonPreLF");
    34  - this.registerMutation("colonPreJunk");
    35  -
    36  - this.registerMutation("colonPostNull");
    37  - this.registerMutation("colonPostSpace");
    38  - this.registerMutation("colonPostTab");
    39  - this.registerMutation("colonPostVTab");
    40  - this.registerMutation("colonPostCR");
    41  - this.registerMutation("colonPostLF");
    42  - this.registerMutation("colonPostJunk");
    43  -
    44  - this.registerMutation("singleQuote");
    45  - this.registerMutation("doubleQuote");
    46  -
    47  - this.registerMutation("upperCase");
    48  - this.registerMutation("lowerCase");
    49  - this.registerMutation("mixedCase");
    50  -
    51  - this.registerMutation("headerStartLF");
    52  - this.registerMutation("headerStartDoubleLF");
    53  - this.registerMutation("headerStartCR");
    54  - this.registerMutation("headerStartDoubleCR");
    55  - this.registerMutation("headerEndLF");
    56  - this.registerMutation("headerEndDoubleLF");
    57  - this.registerMutation("headerEndCR");
    58  - this.registerMutation("headerEndDoubleCR");
    59  - }
    60  -
    61  - private void registerMutation(String name) {
    62  - this.mutations.add(name);
    63  - }
    64  -
    65  - public byte[] mutate(String header, String mutation) {
    66  - String retStr = null;
    67  - byte[] ret = null;
    68  - switch (mutation) {
    69  - case "nospace":
    70  - retStr = header.replaceFirst(": ", ":");
    71  - break;
    72  -
    73  - case "underscore":
    74  - retStr = header.replaceFirst("-", "_");
    75  - break;
    76  -
    77  - case "cr-hyphen":
    78  - retStr = header.replaceFirst("-", "\r");
    79  - break;
    80  -
    81  - case "letter-hyphen":
    82  - retStr = header.replaceFirst("-", "s");
    83  - break;
    84  -
    85  - case "linePrefixSpace":
    86  - retStr = " " + header;
    87  - break;
    88  -
    89  - case "linePrefixTab":
    90  - retStr = "\t" + header;
    91  - break;
    92  -
    93  - case "linePrefixVTab":
    94  - retStr = new String(new byte[]{(byte)0x0b}) + header;
    95  - break;
    96  -
    97  - case "linePrefixNull":
    98  - retStr = new String(new byte[]{(byte)0x00}) + header;
    99  - break;
    100  -
    101  - case "lineAppendixNull":
    102  - retStr = header + new String(new byte[]{(byte)0x00});
    103  - break;
    104  -
    105  - case "colonPreNull":
    106  - retStr = header.replaceFirst(":", "\0:");
    107  - break;
    108  -
    109  - case "colonPreSpace":
    110  - retStr = header.replaceFirst(":", " :");
    111  - break;
    112  -
    113  - case "colonPreTab":
    114  - retStr = header.replaceFirst(":", "\t:");
    115  - break;
    116  -
    117  - case "colonPreVTab":
    118  - retStr = header.replaceFirst(":", new String(new byte[]{0x0b}) + ":");
    119  - break;
    120  -
    121  - case "colonPreCR":
    122  - retStr = header.replaceFirst(":", "\r:");
    123  - break;
    124  -
    125  - case "colonPreLF":
    126  - retStr = header.replaceFirst(":", "\n:");
    127  - break;
    128  -
    129  - case "colonPreJunk":
    130  - retStr = header.replaceFirst(":", " abcd:");
    131  - break;
    132  -
    133  - case "colonPostNull":
    134  - retStr = header.replaceFirst(":", ":\0");
    135  - break;
    136  -
    137  - case "colonPostSpace":
    138  - retStr = header.replaceFirst(":", ": ");
    139  - break;
    140  -
    141  - case "colonPostTab":
    142  - retStr = header.replaceFirst(":", ":\t");
    143  - break;
    144  -
    145  - case "colonPostVTab":
    146  - retStr = header.replaceFirst(":", ":" + new String(new byte[]{0x0b}));
    147  - break;
    148  -
    149  - case "colonPostCR":
    150  - retStr = header.replaceFirst(":", ":\r");
    151  - break;
    152  -
    153  - case "colonPostLF":
    154  - retStr = header.replaceFirst(":", ":\n");
    155  - break;
    156  -
    157  - case "colonPostJunk":
    158  - retStr = header.replaceFirst(":", ":abcd ");
    159  - break;
    160  -
    161  - case "singleQuote":
    162  - retStr = header.replaceFirst(":\\s*", ": '").replaceFirst("$", "'");
    163  - break;
    164  -
    165  - case "doubleQuote":
    166  - retStr = header.replaceFirst(":\\s*", ": \"").replaceFirst("$", "\"");
    167  - break;
    168  -
    169  - case "upperCase":
    170  - retStr = header.toUpperCase();
    171  - break;
    172  -
    173  - case "lowerCase":
    174  - retStr = header.toLowerCase();
    175  - break;
    176  -
    177  - case "mixedCase":
    178  - retStr = "";
    179  - for (int i = 0; i < header.length(); i++) {
    180  - char c;
    181  - if (i%2 == 0) {
    182  - c = Character.toLowerCase(header.charAt(i));
    183  - } else {
    184  - c = Character.toUpperCase(header.charAt(i));
    185  - }
    186  - retStr = retStr + c;
    187  - }
    188  - break;
    189  -
    190  - case "headerStartLF":
    191  - retStr = "Foo: Bar\n" + header;
    192  - break;
    193  -
    194  - case "headerStartDoubleLF":
    195  - retStr = "Foo: Bar\n\n" + header;
    196  - break;
    197  -
    198  - case "headerStartCR":
    199  - retStr = "Foo: Bar\r" + header;
    200  - break;
    201  -
    202  - case "headerStartDoubleCR":
    203  - retStr = "Foo: Bar\r\r" + header;
    204  - break;
    205  -
    206  - case "headerEndLF":
    207  - retStr = header + "\nFoo: Bar";
    208  - break;
    209  -
    210  - case "headerEndDoubleLF":
    211  - retStr = header + "\n\nFoo: Bar";
    212  - break;
    213  -
    214  - case "headerEndCR":
    215  - retStr = header + "\rFoo: Bar";
    216  - break;
    217  -
    218  - case "headerEndDoubleCR":
    219  - retStr = header + "\r\rFoo: Bar";
    220  - break;
    221  -
    222  - default:
    223  - Utilities.out("Unknown mutation " + mutation + " requested!");
    224  - retStr = header;
    225  - break;
    226  - }
    227  -
    228  - if (ret == null && retStr != null) {
    229  - return retStr.getBytes(StandardCharsets.UTF_8);
    230  - }
    231  - return ret;
    232  - }
    233  -
    234  - public byte[] mutateRequest(byte[] req, String mutation, String[] headers) throws IOException {
    235  - ByteArrayOutputStream ret = new ByteArrayOutputStream();
    236  -
    237  - // Get sorted header offsets, and a sorted array of their indices, sorted by the start offset of the header
    238  - ArrayList<int[]> offsets = new ArrayList<int[]>();
    239  - for (int i = 0; i < headers.length; i++) {
    240  - String header = headers[i];
    241  - if (header.contains("~")) {
    242  - header = header.split("~", 2)[0];
    243  - }
    244  - int[] offs = Utilities.getHeaderOffsets(req, header);
    245  - if (offs != null) {
    246  - offsets.add(offs);
    247  - }
    248  - }
    249  -
    250  - offsets.sort(new java.util.Comparator<int[]>(){
    251  - public int compare(int[] a, int[] b) {
    252  - return Integer.compare(a[0], b[0]);
    253  - }
    254  - });
    255  - // Copy over req to ret, replacing headers as we go
    256  - int offset = 0;
    257  - Iterator<int[]> iterator = offsets.iterator();
    258  - while (iterator.hasNext()) {
    259  - int[] markers = iterator.next();
    260  - int headerStart = markers[0];
    261  - int headerEnd = markers[2];
    262  -
    263  - // Copy up to the start of the header
    264  -
    265  - // Duplicate headers cause an issue here. However, switching offset and headerStart seems to just fix it.
    266  - if (offset >= headerStart) {
    267  - int tmp = offset;
    268  - offset = headerStart;
    269  - headerStart = tmp;
    270  - }
    271  - ret.write(Arrays.copyOfRange(req, offset, headerStart));
    272  - offset = headerEnd;
    273  -
    274  - // Copy in mutated header
    275  - byte[] headerBytes = Arrays.copyOfRange(req, headerStart, headerEnd);
    276  - String headerStr = new String(headerBytes, StandardCharsets.UTF_8);
    277  - byte[] newHeader = this.mutate(headerStr, mutation);
    278  - ret.write(newHeader);
    279  - }
    280  -
    281  - // Copy in rest of request
    282  - ret.write(Arrays.copyOfRange(req, offset, req.length));
    283  -
    284  - return ret.toByteArray();
    285  - }
    286  -}
    287  - 
  • ■ ■ ■ ■
    src/burp/ParamGuesser.java
    skipped 79 lines
    80 80  
    81 81   // Report if required
    82 82   if (mutations != null) {
    83  - Iterator<String> iterator = mutations.iterator();
    84  - while (iterator.hasNext()) {
    85  - mutationGuesser.reportMutations(mutations);
    86  - }
     83 + mutationGuesser.reportMutations(mutations);
    87 84   }
    88 85   }
    89 86  
    skipped 688 lines
  • ■ ■ ■ ■ ■ ■
    src/burp/PayloadInjector.java
    1  -package burp;
    2  - 
    3  -import org.graalvm.compiler.core.common.util.Util;
    4  - 
    5  -import java.io.IOException;
    6  -import java.nio.charset.StandardCharsets;
    7  -import java.util.ArrayList;
    8  -import java.util.Arrays;
    9  - 
    10  - 
    11  -class PayloadInjector {
    12  - 
    13  - public IHttpService getService() {
    14  - return service;
    15  - }
    16  - 
    17  - private IHttpService service;
    18  - 
    19  - public IScannerInsertionPoint getInsertionPoint() {
    20  - return insertionPoint;
    21  - }
    22  - 
    23  - private IScannerInsertionPoint insertionPoint;
    24  - 
    25  - public IHttpRequestResponse getBase() {
    26  - return base;
    27  - }
    28  - 
    29  - private IHttpRequestResponse base;
    30  - 
    31  - PayloadInjector(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) {
    32  - this.service = baseRequestResponse.getHttpService();
    33  - this.base = baseRequestResponse;
    34  - this.insertionPoint = insertionPoint;
    35  - }
    36  - 
    37  - // fixme horribly inefficient
    38  - ArrayList<Attack> fuzz(Attack baselineAttack, Probe probe) {
    39  - return fuzz(baselineAttack, probe, null);
    40  - }
    41  - 
    42  - ArrayList<Attack> fuzz(Attack baselineAttack, Probe probe, String mutation) {
    43  - ArrayList<Attack> attacks = new ArrayList<>(2);
    44  - Attack breakAttack = buildAttackFromProbe(probe, probe.getNextBreak(), mutation);
    45  - 
    46  - if (Utilities.identical(baselineAttack, breakAttack)) {
    47  - return new ArrayList<>();
    48  - }
    49  - 
    50  - for(int k=0; k<probe.getNextEscapeSet().length; k++) {
    51  - Attack doNotBreakAttack = buildAttackFromProbe(probe, probe.getNextEscapeSet()[k], mutation);
    52  - doNotBreakAttack.addAttack(baselineAttack);
    53  - if(!Utilities.identical(doNotBreakAttack, breakAttack)) {
    54  - attacks = verify(doNotBreakAttack, breakAttack, probe, k, mutation);
    55  - if (!attacks.isEmpty()) {
    56  - break;
    57  - }
    58  - }
    59  - }
    60  - 
    61  - return attacks;
    62  - }
    63  - 
    64  - private ArrayList<Attack> verify(Attack doNotBreakAttackSeed, Attack breakAttackSeed, Probe probe, int chosen_escape, String mutation) {
    65  - ArrayList<Attack> attacks = new ArrayList<>(2);
    66  - Attack mergedBreakAttack = new Attack();
    67  - mergedBreakAttack.addAttack(breakAttackSeed);
    68  - Attack mergedDoNotBreakAttack = new Attack();
    69  - mergedDoNotBreakAttack.addAttack(doNotBreakAttackSeed);
    70  - 
    71  - Attack tempDoNotBreakAttack = doNotBreakAttackSeed;
    72  - 
    73  - for(int i=0; i<Utilities.CONFIRMATIONS; i++) {
    74  - Attack tempBreakAttack = buildAttackFromProbe(probe, probe.getNextBreak(), mutation);
    75  - mergedBreakAttack.addAttack(tempBreakAttack);
    76  - 
    77  - if(Utilities.similarIsh(mergedDoNotBreakAttack, mergedBreakAttack, tempDoNotBreakAttack, tempBreakAttack)
    78  - || (probe.getRequireConsistentEvidence() && Utilities.similar(mergedDoNotBreakAttack, tempBreakAttack))) {
    79  - return new ArrayList<>();
    80  - }
    81  - 
    82  - tempDoNotBreakAttack = buildAttackFromProbe(probe, probe.getNextEscapeSet()[chosen_escape], mutation);
    83  - mergedDoNotBreakAttack.addAttack(tempDoNotBreakAttack);
    84  - 
    85  - if(Utilities.similarIsh(mergedDoNotBreakAttack, mergedBreakAttack, tempDoNotBreakAttack, tempBreakAttack)
    86  - || (probe.getRequireConsistentEvidence() && Utilities.similar(mergedBreakAttack, tempDoNotBreakAttack))) {
    87  - return new ArrayList<>();
    88  - }
    89  - 
    90  - }
    91  - 
    92  - // this final probe pair is sent out of order, to prevent alternation false positives
    93  - tempDoNotBreakAttack = buildAttackFromProbe(probe, probe.getNextEscapeSet()[chosen_escape], mutation);
    94  - mergedDoNotBreakAttack.addAttack(tempDoNotBreakAttack);
    95  - Attack tempBreakAttack = buildAttackFromProbe(probe, probe.getNextBreak(), mutation);
    96  - mergedBreakAttack.addAttack(tempBreakAttack);
    97  - 
    98  - // point is to exploit response attributes that vary in "don't break" responses (but are static in 'break' responses)
    99  - if(Utilities.similarIsh(mergedDoNotBreakAttack, mergedBreakAttack, tempDoNotBreakAttack, tempBreakAttack)
    100  - || (probe.getRequireConsistentEvidence() && Utilities.similar(mergedBreakAttack, tempDoNotBreakAttack))) {
    101  - return new ArrayList<>();
    102  - }
    103  - 
    104  - attacks.add(mergedBreakAttack);
    105  - attacks.add(mergedDoNotBreakAttack);
    106  - 
    107  - return attacks;
    108  - }
    109  - 
    110  - 
    111  - private Attack buildAttackFromProbe(Probe probe, String payload, String mutation) {
    112  - boolean randomAnchor = probe.getRandomAnchor();
    113  - byte prefix = probe.getPrefix();
    114  - 
    115  - String anchor = "";
    116  - if (randomAnchor) {
    117  - anchor = Utilities.generateCanary();
    118  - }
    119  - //else {
    120  - // payload = payload.replace("z", Utilities.generateCanary());
    121  - //}
    122  - 
    123  - String base_payload = payload;
    124  - if (prefix == Probe.PREPEND) {
    125  - payload += insertionPoint.getBaseValue();
    126  - }
    127  - else if (prefix == Probe.APPEND) {
    128  - payload = insertionPoint.getBaseValue() + anchor + payload;
    129  - }
    130  - else if (prefix == Probe.REPLACE) {
    131  - // payload = payload;
    132  - }
    133  - else {
    134  - Utilities.err("Unknown payload position");
    135  - }
    136  - 
    137  - 
    138  - IHttpRequestResponse req = buildRequest(payload, probe.useCacheBuster(), mutation);
    139  - if(randomAnchor) {
    140  - req = Utilities.highlightRequestResponse(req, anchor, anchor, insertionPoint);
    141  - }
    142  - 
    143  - return new Attack(req, probe, base_payload, anchor);
    144  - }
    145  - 
    146  - IHttpRequestResponse buildRequest(String payload, boolean needCacheBuster) {
    147  - return buildRequest(payload, needCacheBuster, null);
    148  - }
    149  - 
    150  - IHttpRequestResponse buildRequest(String payload, boolean needCacheBuster, String mutation) {
    151  - 
    152  - byte[] request = insertionPoint.buildRequest(payload.getBytes());
    153  - 
    154  - if (needCacheBuster) {
    155  - request = Utilities.addCacheBuster(request, Utilities.generateCanary());
    156  - }
    157  - 
    158  - if (mutation != null) {
    159  - HeaderMutator mutator = new HeaderMutator();
    160  - try {
    161  - byte[] newRequest = mutator.mutateRequest(request, mutation, payload.split("\\|"));
    162  - request = newRequest;
    163  - } catch (IOException e) {
    164  - Utilities.out(e.toString());
    165  - }
    166  - }
    167  - 
    168  - IHttpRequestResponse requestResponse = burp.Utilities.attemptRequest(service, request);
    169  - //Utilities.out("Payload: "+payload+"|"+baseRequestResponse.getHttpService().getHost());
    170  - 
    171  - return requestResponse;// Utilities.buildRequest(baseRequestResponse, insertionPoint, payload)
    172  - }
    173  - 
    174  - Attack probeAttack(String payload) {
    175  - return probeAttack(payload, null);
    176  - }
    177  - 
    178  - Attack probeAttack(String payload, String mutation) {
    179  - byte[] request = insertionPoint.buildRequest(payload.getBytes());
    180  - 
    181  - //IParameter cacheBuster = burp.Utilities.helpers.buildParameter(Utilities.generateCanary(), "1", IParameter.PARAM_URL);
    182  - //request = burp.Utilities.helpers.addParameter(request, cacheBuster);
    183  - //request = burp.Utilities.appendToQuery(request, Utilities.generateCanary()+"=1");
    184  - request = Utilities.addCacheBuster(request, Utilities.generateCanary());
    185  - 
    186  - if (mutation != null) {
    187  - HeaderMutator mutator = new HeaderMutator();
    188  - try {
    189  - byte[] newRequest = mutator.mutateRequest(request, mutation, payload.split("\\|"));
    190  - request = newRequest;
    191  - } catch (java.io.IOException e) {
    192  - //Utilities.out("ERROR: failed to mutate request: " + e.toString());
    193  - }
    194  - }
    195  - 
    196  - IHttpRequestResponse requestResponse = burp.Utilities.attemptRequest(service, request);
    197  - return new Attack(requestResponse, null, null, "");
    198  - }
    199  - 
    200  - 
    201  - Attack buildAttack(String payload, boolean random) {
    202  - String canary = "";
    203  - if (random) {
    204  - canary = Utilities.generateCanary();
    205  - }
    206  - 
    207  - return new Attack(buildRequest(canary+payload, !random, null), null, null, canary);
    208  - 
    209  - }
    210  - 
    211  -}
    212  - 
Please wait...
Page is in error, reload to recover