Skip to content

Commit

Permalink
Added support for JWT
Browse files Browse the repository at this point in the history
  • Loading branch information
JGillam committed Sep 22, 2019
1 parent d39733f commit 48d7d27
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 190 deletions.
288 changes: 106 additions & 182 deletions .idea/workspace.xml

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion src/com/professionallyevil/bc/CorrelatedParam.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,14 @@ public String getAnalysisText(ParamInstance pi, IBurpExtenderCallbacks callbacks
if(analysisText.containsKey(pi)) {
return analysisText.get(pi);
} else {
String text = ParamAnalyzer.analyze(pi, callbacks);
String text = "";
if (pi instanceof JSONParamInstance) {
String logPrefix = "This parameter was derived from a JSON object: "+ ((JSONParamInstance)pi).getParent().getName()+"\n";
text = ParamAnalyzer.analyze(pi, callbacks, logPrefix);
} else {
text = ParamAnalyzer.analyze(pi, callbacks);
}

analysisText.put(pi, text);
return text;
}
Expand Down
2 changes: 1 addition & 1 deletion src/com/professionallyevil/bc/CorrelatorEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ private void parameterFormatAnalysis() {

private void processJSON(CorrelatedParam cp) {
for(ParamInstance param: cp.uniqueParamInstances) {
if(param.getFormat() == ParamInstance.Format.JSON) {
if(param.getFormat() == ParamInstance.Format.JSON || param.getFormat() == ParamInstance.Format.JWT) {
List<JSONParamInstance> jsonParams = JSONParamParser.parseObjectString(param.decodedValue, param);
for(JSONParamInstance jsonParam: jsonParams) {
if (jsonPartParameters.containsKey(jsonParam.getName())) {
Expand Down
4 changes: 4 additions & 0 deletions src/com/professionallyevil/bc/JSONParamInstance.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public byte getType() {
return TYPE;
}

public ParamInstance getParent() {
return parent;
}

@Override
public String getName() {
return paramName;
Expand Down
2 changes: 1 addition & 1 deletion src/com/professionallyevil/bc/JSONParamParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
class JSONParamParser {

enum JSONValue {
OBJECT("^\\{(\\s*\"([^\\\"^\\\\^\\p{Cntrl}]+)\"\\s*:(\\s*((-?\\d+)|(\"[^\\\"^\\\\^\\p{Cntrl}]*\")|true|false|null|\\[.*\\]|\\{.*\\})\\s*))(,\\s*\"([^\\\"^\\\\^\\p{Cntrl}]*)\"\\s*:(\\s*((\\-?d+)|(\"[^\\\"^\\\\^\\p{Cntrl}]*\")|true|false|null|\\[.*\\]|\\{.*\\})\\s*))*\\}$");
OBJECT("^\\{(\\s*\"([^\\\"^\\\\^\\p{Cntrl}]+)\"\\s*:(\\s*((-?\\d+)|(\"[^\\\"^\\\\^\\p{Cntrl}]*\")|true|false|null|\\[.*\\]|\\{.*\\})\\s*))(,\\s*\"([^\\\"^\\\\^\\p{Cntrl}]*)\"\\s*:(\\s*((-?\\d+)|(\"[^\\\"^\\\\^\\p{Cntrl}]*\")|true|false|null|\\[.*\\]|\\{.*\\})\\s*))*\\}$");


private String regex;
Expand Down
31 changes: 27 additions & 4 deletions src/com/professionallyevil/bc/ParamAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ enum ValuePattern {
JSON_VALUE_QUICK("^(\\s*((\\d+)|(\"[\\w ]*\")|true|false|null|\\[.*\\]|\\{.*\\})\\s*)$", "PRINTABLE_CHARS"),
JSON_OBJECT(JSONParamParser.JSONValue.OBJECT.getRegex(), "PRINTABLE_CHARS", "JSON_VALUE_QUICK"),
PHP_SERIALIZED_QUICK("^([si]:\\d+:\\w+?;)(N;)|[oa]:\\d+:.*\\{.*}$"),
PHP_SERIALIZED("^((s:\\d+:\".*\";)|(i:\\d+;)|(N;)|(a:\\d+:\\{((s:\\d+:\".*?\";)|(i:\\d+;)|(N;)|(o:\\d+:\"[a-z0-9_]+\":\\d+:\\{((s:\\d+:\".*?\";)|(i:\\d+;)|(N;))*}))*})|(o:\\d+:\"[a-z0-9_]+\":\\d+:\\{((s:\\d+:\".*?\";)|(i:\\d+;)|(N;))*}))$");
PHP_SERIALIZED("^((s:\\d+:\".*\";)|(i:\\d+;)|(N;)|(a:\\d+:\\{((s:\\d+:\".*?\";)|(i:\\d+;)|(N;)|(o:\\d+:\"[a-z0-9_]+\":\\d+:\\{((s:\\d+:\".*?\";)|(i:\\d+;)|(N;))*}))*})|(o:\\d+:\"[a-z0-9_]+\":\\d+:\\{((s:\\d+:\".*?\";)|(i:\\d+;)|(N;))*}))$"),
JWT("^[A-Za-z0-9-_=]+\\.[A-Za-z0-9-_=]+\\.?[A-Za-z0-9-_.+/=]*$", "PRINTABLE_CHARS");


private Pattern pattern;
Expand Down Expand Up @@ -85,6 +86,10 @@ public static boolean isBase62Encoded(String testValue) {
}

static String analyze(ParamInstance pi, IBurpExtenderCallbacks callbacks) {
return analyze(pi, callbacks, "");
}

static String analyze(ParamInstance pi, IBurpExtenderCallbacks callbacks, String logPrefix) {
try {
String value = pi.getValue();
if (value.isEmpty() || "[EMPTY]".equals(value)) {
Expand All @@ -96,7 +101,7 @@ static String analyze(ParamInstance pi, IBurpExtenderCallbacks callbacks) {
return "Appears to be a BigIP value: " + value + "\nDecodes to: " + decodeBigIP(pi, value);
}

StringBuilder smartDecodeLog = new StringBuilder();
StringBuilder smartDecodeLog = new StringBuilder(logPrefix);
String currentValue = value;
String lastValue = "";
while (!lastValue.equals(currentValue)) {
Expand Down Expand Up @@ -165,7 +170,17 @@ private static String smartDecode(ParamInstance pi, String input, IBurpExtenderC
log.append("\n");
log.append(identify(pi, input));
return input;
}else if(ValuePattern.BASE64_ENCODED.matches(input)) {
} else if(ValuePattern.JWT.matches(input)) {
String[] parts = input.split("[\\.]");
byte[] algorithmBytes = callbacks.getHelpers().base64Decode(parts[0]);
String algorithm = callbacks.getHelpers().bytesToString(algorithmBytes);
byte[] decodedBytes = callbacks.getHelpers().base64Decode(parts[1]);
String decodedString = callbacks.getHelpers().bytesToString(decodedBytes);
pi.setFormat(ParamInstance.Format.JWT);
log.append("\nLooks to be a JWT: \n The algorithm section is: \n").append(algorithm);
log.append("\n The body section is: \n").append(decodedString);
return decodedString;
} else if(ValuePattern.BASE64_ENCODED.matches(input)) {
byte[] decodedBytes = callbacks.getHelpers().base64Decode(input);
String decodedString = callbacks.getHelpers().bytesToString(decodedBytes);
if(ValuePattern.PRINTABLE_CHARS.matches(decodedString)) {
Expand All @@ -187,6 +202,7 @@ private static String smartDecode(ParamInstance pi, String input, IBurpExtenderC
}
}


private static String identify(ParamInstance pi, String input) {
StringBuilder log = new StringBuilder();
if (isCreditCard(input)) {
Expand Down Expand Up @@ -254,7 +270,9 @@ private static String identify(ParamInstance pi, String input) {
pi.setFormat(ParamInstance.Format.HTMLFRAG);
} else if (ValuePattern.JSON_OBJECT.matches(input)) {
log.append("\nThis may be a JSON-formatted String.");
pi.setFormat(ParamInstance.Format.JSON);
if (pi.getFormat() != ParamInstance.Format.JWT) {
pi.setFormat(ParamInstance.Format.JSON);
}
} else {
pi.setFormat(ParamInstance.Format.PRINTABLE);
}
Expand Down Expand Up @@ -421,6 +439,11 @@ public static void main(String[] args) {
test("JSON 2", "{\"foo\": {\"foo1\": [1,2,3]}}", ValuePattern.JSON_OBJECT);
test("JSON 3", "{\"foo\": \"bar\", \"foo2\": [42, 99], \"foo3\": {\"secret1\": \"4242-4242-4242-4242\", \"secret2\": false}}", ValuePattern.JSON_OBJECT);
test("JSON 4", "{\"secret1\": \"4242-4242-4242-4242\", \"secret2\": false}", ValuePattern.JSON_OBJECT);
test("JWT 1", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikphc29uIEdpbGxhbSIsInNlY3JldCI6NDJ9.Yo-96trF4CAU_v-mrJLYuqigEGC3QBDul7C41RM2RL4", ValuePattern.JWT);
test("JSON 5", "{\"sub\":\"1234567890\",\"name\":\"Jason Gillam\",\"secret\":42}", ValuePattern.JSON_OBJECT);



}

}
3 changes: 2 additions & 1 deletion src/com/professionallyevil/bc/ParamInstance.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ enum Format {
HTMLFRAG("XML/HTML"),
EMPTY("Empty"),
JSON("JSON Object"),
PHP("PHP Serialized");
PHP("PHP Serialized"),
JWT("JWT");

private String title;

Expand Down

0 comments on commit 48d7d27

Please sign in to comment.