diff --git a/src/main/java/burp/Utility.java b/src/main/java/burp/Utility.java index a26f1d9..4639d4c 100644 --- a/src/main/java/burp/Utility.java +++ b/src/main/java/burp/Utility.java @@ -10,11 +10,10 @@ import java.net.URI; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.text.Collator; +import java.util.regex.Pattern; import java.text.SimpleDateFormat; import java.util.*; import java.util.regex.Matcher; -import java.util.regex.Pattern; public class Utility { @@ -93,15 +92,29 @@ public static byte[] signRequest(IHttpRequestResponse messageInfo, for (String signedHeader : signedHeaderList){ canonicalHeaders.append(signedHeader.toLowerCase()).append(':').append(headerMap.get(signedHeader)).append('\n'); } - + //pw.println(canonicalHeaders.toString()); byte[] request = messageInfo.getRequest(); String body = ""; + String notUnicode = "[^\\u0000-\\u007F]+"; String payloadHash; if (!requestInfo.getMethod().equals("GET")){ int bodyOffset = requestInfo.getBodyOffset(); - body = new String(request, bodyOffset, request.length - bodyOffset, "UTF-8").trim(); + body = hexToString(bytesToHex(Arrays.copyOfRange(request, bodyOffset, request.length))); + if(!body.matches(notUnicode)) { + char[] chars = body.toCharArray(); + String sanitize = ""; + for (int i = 0; i < chars.length; ++i) { + String test = Character.toString(chars[i]); + if (Pattern.matches(notUnicode, test)) { + sanitize = sanitize.concat(URLEncoder.encode(test, StandardCharsets.UTF_8.toString())); + } else { + sanitize = sanitize.concat(test); + } + } + body = sanitize; + } payloadHash = Hashing.sha256().hashString(body, StandardCharsets.UTF_8).toString().toLowerCase(); } else { @@ -109,6 +122,19 @@ public static byte[] signRequest(IHttpRequestResponse messageInfo, } String canonicalUri = requestInfo.getUrl().getPath(); + if(!canonicalUri.matches(notUnicode)) { + char[] chars = canonicalUri.toCharArray(); + String sanitize = ""; + for (int i = 0; i < chars.length; ++i) { + String test = Character.toString(chars[i]); + if (Pattern.matches(notUnicode, test)) { + sanitize = sanitize.concat(URLEncoder.encode(test, StandardCharsets.UTF_8.toString())); + } else { + sanitize = sanitize.concat(test); + } + } + canonicalUri = sanitize; + } //pw.println(canonicalUri); URI uri = new URI(canonicalUri); uri = uri.normalize(); @@ -136,6 +162,19 @@ public static byte[] signRequest(IHttpRequestResponse messageInfo, if (Strings.isNullOrEmpty(canonicalQueryString)){ canonicalQueryString = ""; } + if(!canonicalQueryString.matches(notUnicode)) { + char[] chars = canonicalQueryString.toCharArray(); + String sanitize = ""; + for (int i = 0; i < chars.length; ++i) { + String test = Character.toString(chars[i]); + if (Pattern.matches(notUnicode, test)) { + sanitize = sanitize.concat(URLEncoder.encode(test, StandardCharsets.UTF_8.toString())); + } else { + sanitize = sanitize.concat(test); + } + } + canonicalQueryString = sanitize; + } String[] sorted = canonicalQueryString.split("&"); Arrays.sort(sorted); @@ -169,7 +208,7 @@ public static byte[] signRequest(IHttpRequestResponse messageInfo, } } canonicalQueryString = String.join("", cleanup); - + //pw.println(canonicalQueryString); //canonicalQueryString = canonicalQueryString.replace(":","%3A").replace("/","%2F").replace(" ", "%20"); String canonicalRequest = requestInfo.getMethod() + '\n' + encodedCanonicalUri + '\n' + canonicalQueryString + '\n' + @@ -178,8 +217,8 @@ public static byte[] signRequest(IHttpRequestResponse messageInfo, String algorithm = "AWS4-HMAC-SHA256"; String stringToSign = algorithm + '\n' + amzdate + '\n' + credScope + '\n' + Hashing.sha256().hashString(canonicalRequest, StandardCharsets.UTF_8).toString().toLowerCase(); - pw.println(canonicalRequest); - pw.println(stringToSign); + //pw.println(canonicalRequest); + //pw.println(stringToSign); byte[] signingKey = getSignatureKey(secretKey, dateStampString, region, service); String signature = DatatypeConverter.printHexBinary(HmacSHA256(stringToSign, signingKey)); @@ -187,6 +226,19 @@ public static byte[] signRequest(IHttpRequestResponse messageInfo, newHeaders.add("Authorization: " + algorithm + ' ' + "Credential=" + accessKey + '/' + credScope + ", " + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature.toLowerCase()); newHeaders.add("X-Amz-Date: " + amzdate); + if(!newHeaders.get(0).matches(notUnicode)) { + char[] chars = newHeaders.get(0).toCharArray(); + String sanitize = ""; + for (int i = 0; i < chars.length; ++i) { + String test = Character.toString(chars[i]); + if (Pattern.matches(notUnicode, test)) { + sanitize = sanitize.concat(URLEncoder.encode(test, StandardCharsets.UTF_8.toString())); + } else { + sanitize = sanitize.concat(test); + } + } + newHeaders.set(0, sanitize); + } return helpers.buildHttpMessage(newHeaders, body.getBytes()); } @@ -220,4 +272,25 @@ private static String getSignedHeaders(String authHeader){ return signedHeaders; } + private static String bytesToHex(byte[] bytes) { + char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + } + return new String(hexChars); + } + private static String hexToString(String hex){ + StringBuilder sb = new StringBuilder(); + StringBuilder temp = new StringBuilder(); + for( int i=0; i