From 3a77368e535382e3fdc47de1b85abed04de54d66 Mon Sep 17 00:00:00 2001 From: NickLech Date: Mon, 25 Nov 2024 10:01:58 +0100 Subject: [PATCH] Changed HttpReqRes to take a HttpMessage instead of a HistoryReference --- .../java/org/zaproxy/addon/migt/Check.java | 324 ++++++++---------- .../zaproxy/addon/migt/ExecutePassives.java | 2 + .../org/zaproxy/addon/migt/HTTPReqRes.java | 77 ++--- .../org/zaproxy/addon/migt/Operation.java | 19 +- .../zaproxy/addon/migt/ParsingException.java | 2 +- .../java/org/zaproxy/addon/migt/Session.java | 17 +- .../java/org/zaproxy/addon/migt/Test.java | 9 + .../java/org/zaproxy/addon/migt/Tools.java | 2 + .../org/zaproxy/addon/migt/ZAPextender.java | 181 +++------- 9 files changed, 252 insertions(+), 381 deletions(-) diff --git a/tool/src/main/java/org/zaproxy/addon/migt/Check.java b/tool/src/main/java/org/zaproxy/addon/migt/Check.java index 762a428..b1c2380 100644 --- a/tool/src/main/java/org/zaproxy/addon/migt/Check.java +++ b/tool/src/main/java/org/zaproxy/addon/migt/Check.java @@ -4,30 +4,22 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.JsonPath; -import com.networknt.schema.JsonSchema; -import com.networknt.schema.JsonSchemaException; -import com.networknt.schema.JsonSchemaFactory; -import com.networknt.schema.SpecVersion; -import com.networknt.schema.ValidationMessage; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import com.networknt.schema.*; import org.apache.commons.text.StringEscapeUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.zaproxy.addon.migt.Check.CheckOps.*; + /** - * Check Object class. This object is used in Operations to check that a parameter or some text is - * in as specified. + * Check Object class. This object is used in Operations to check that a parameter or some text is in as specified. */ public class Check extends Module { String what; // what to search @@ -112,14 +104,10 @@ public Check(JSONObject json_check) throws ParsingException { } break; case "is present": - this.op = - json_check.getBoolean("is present") - ? CheckOps.IS_PRESENT - : CheckOps.IS_NOT_PRESENT; - this.op_val = - json_check.getBoolean("is present") - ? "is present" - : "is not present"; + this.op = json_check.getBoolean("is present") ? CheckOps.IS_PRESENT : + IS_NOT_PRESENT; + this.op_val = json_check.getBoolean("is present") ? + "is present" : "is not present"; break; case "is in": this.op = CheckOps.IS_IN; @@ -153,7 +141,7 @@ public Check(JSONObject json_check) throws ParsingException { } break; case "is subset of": - this.op = CheckOps.IS_SUBSET_OF; + this.op = IS_SUBSET_OF; if (json_check.has("use variable")) { // inside "is subset of" a string with the name of the var is expected this.op_val = json_check.getString("is subset of"); @@ -168,31 +156,30 @@ public Check(JSONObject json_check) throws ParsingException { } break; case "json schema compliant": - this.op = CheckOps.JSON_SCHEMA_COMPLIANT; + this.op = JSON_SCHEMA_COMPLIANT; this.op_val = json_check.getString("json schema compliant"); break; case "matches regex": - this.op = CheckOps.MATCHES_REGEX; + this.op = MATCHES_REGEX; this.op_val = json_check.getString("matches regex"); break; case "not matches regex": - this.op = CheckOps.NOT_MATCHES_REGEX; + this.op = NOT_MATCHES_REGEX; this.op_val = json_check.getString("not matches regex"); break; case "url decode": url_decode = json_check.getBoolean("url decode"); break; default: - throw new ParsingException( - "Invalid key:\"" + key + "\" used in Check Operation"); + throw new ParsingException("Invalid key:\"" + key + "\" used in Check Operation"); } } catch (JSONException e) { throw new ParsingException("error in parsing check: " + e); } catch (ClassCastException e) { - throw new ParsingException( - "Only allowed values in arrays are Strings, if you are using integers or " - + "floats, please convert them as strings"); + throw new ParsingException("Only allowed values in arrays are Strings, if you are using integers or " + + "floats, please convert them as strings"); } + } if (regex.equals("") && what.equals("")) @@ -236,7 +223,6 @@ private boolean execute_regex(String input) throws ParsingException { Pattern p = Pattern.compile(regex); Matcher m = p.matcher(input); applicable = true; - System.out.println("Set true 1"); String val = ""; if (m.find()) { @@ -255,13 +241,14 @@ private boolean execute_regex(String input) throws ParsingException { /** * Execute the check over a message (in an Operation) * - * @param message the message to check + * @param message the message to check * @param isRequest tells if the message is a request or a response * @return the result of the check * @throws ParsingException if something wrong is found wrt the language */ - private boolean execute_http(HTTPReqRes message, boolean isRequest, List vars) - throws ParsingException { + private boolean execute_http(HTTPReqRes message, + boolean isRequest, + List vars) throws ParsingException { if (use_variable) { // if use_variable is set, substitute the value to check with the variable value @@ -294,8 +281,7 @@ private boolean execute_http(HTTPReqRes message, boolean isRequest, List va if (msg_str.isEmpty()) { applicable = true; - System.out.println("Set true 2"); - return this.op != null && op == CheckOps.IS_NOT_PRESENT; + return this.op != null && op == IS_NOT_PRESENT; } msg_str = url_decode(msg_str); @@ -307,24 +293,18 @@ private boolean execute_http(HTTPReqRes message, boolean isRequest, List va if (this.isParamCheck) { if (in == CheckIn.BODY) { - System.out.println("Error position is Check 1"); applicable = false; - throw new ParsingException( - "Invalid check operation, cannot do \"check param\" over body, " - + "use \"check_regex instead\""); + throw new ParsingException("Invalid check operation, cannot do \"check param\" over body, " + + "use \"check_regex instead\""); } - Pattern p = - this.in == CheckIn.URL - ? Pattern.compile( - "(?<=[?&]" + Pattern.quote(this.what) + "=)[^\\r\\n&]*") - : Pattern.compile( - "(?<=" + Pattern.quote(this.what) + ":\\s?)[^\\r\\n]*"); + Pattern p = this.in == CheckIn.URL ? + Pattern.compile("(?<=[?&]" + Pattern.quote(this.what) + "=)[^\\r\\n&]*") : + Pattern.compile("(?<=" + Pattern.quote(this.what) + ":\\s?)[^\\r\\n]*"); // TODO: this could be done better by using message methods Matcher m = p.matcher(msg_str); applicable = true; - System.out.println("Set true 3 <--"); String val = ""; if (m.find()) { @@ -335,16 +315,15 @@ private boolean execute_http(HTTPReqRes message, boolean isRequest, List va return do_check(val); } else { applicable = true; - System.out.println("Set true 4"); if (!msg_str.contains(this.what)) { if (this.op != null) { - return this.op == CheckOps.IS_NOT_PRESENT; + return this.op == IS_NOT_PRESENT; } else { return false; } } else { if (this.op != null) { - return this.op != CheckOps.IS_NOT_PRESENT; + return this.op != IS_NOT_PRESENT; } } } @@ -354,12 +333,11 @@ private boolean execute_http(HTTPReqRes message, boolean isRequest, List va private String url_decode(String string) { if (url_decode) { if (string.contains("+")) { - System.err.println( - "Warning! During a check on the value\"" - + ((string.length() > 10) ? string.substring(0, 9) + "..." : string) - + "\" a '+' symbol has been" - + "converted to a space, as it has been interpreted as url-encoded character. If you want to avoid" - + "this behaviour use 'url decode' tag set to false inside the check to disable url-decoding"); + System.err.println("Warning! During a check on the value\"" + + ((string.length() > 10) ? string.substring(0, 9) + "..." : string) + + "\" a '+' symbol has been" + + "converted to a space, as it has been interpreted as url-encoded character. If you want to avoid" + + "this behaviour use 'url decode' tag set to false inside the check to disable url-decoding"); } try { string = URLDecoder.decode(string, StandardCharsets.UTF_8); @@ -380,8 +358,7 @@ private boolean execute_json(List vars) throws ParsingException { DecodeOperation_API tmp = ((DecodeOperation_API) this.imported_api); if (isParamCheck) { - throw new ParsingException( - "Cannot execute a 'check param' in a json, please use 'check'"); + throw new ParsingException("Cannot execute a 'check param' in a json, please use 'check'"); } Var v = null; @@ -406,21 +383,18 @@ private boolean execute_json(List vars) throws ParsingException { String j = ""; switch (in) { - case JWT_HEADER: - { - j = tmp.jwt.header; - break; - } - case JWT_PAYLOAD: - { - j = tmp.jwt.payload; - break; - } - case JWT_SIGNATURE: - { - j = tmp.jwt.signature; - break; - } + case JWT_HEADER: { + j = tmp.jwt.header; + break; + } + case JWT_PAYLOAD: { + j = tmp.jwt.payload; + break; + } + case JWT_SIGNATURE: { + j = tmp.jwt.signature; + break; + } } // if a regex is present, execute it @@ -435,20 +409,16 @@ private boolean execute_json(List vars) throws ParsingException { try { Object found_obj = JsonPath.read(j, what); - if (op == CheckOps.IS_PRESENT | op == CheckOps.IS_NOT_PRESENT) { + if (op == IS_PRESENT | op == IS_NOT_PRESENT) { // whatever is the type of the value, if it is found return the result applicable = true; - System.out.println("Set true 5"); - return op == CheckOps.IS_PRESENT; + return op == IS_PRESENT; } if (found_obj instanceof net.minidev.json.JSONArray) { // the value is a list, allowed ops are: contains/not-contains - if (!(op == CheckOps.CONTAINS - | op == CheckOps.NOT_CONTAINS - | op == CheckOps.IS_SUBSET_OF)) { - throw new ParsingException( - "Check error, used " + op.toString() + " over a matched list"); + if (!(op == CONTAINS | op == NOT_CONTAINS | op == IS_SUBSET_OF)) { + throw new ParsingException("Check error, used " + op.toString() + " over a matched list"); } Iterator i = ((net.minidev.json.JSONArray) found_obj).iterator(); @@ -458,19 +428,19 @@ private boolean execute_json(List vars) throws ParsingException { try { String elem = String.valueOf(i.next()); new_array.add(elem); - } catch (ClassCastException e) { - throw new ParsingException( - "Cannot convert element in jwt matched array to string"); + } catch (java.lang.ClassCastException e) { + throw new ParsingException("Cannot convert element in jwt matched array to string"); } } found_array = new_array; value_is_array = true; - } else if (found_obj instanceof String) { + } else if (found_obj instanceof java.lang.String) { // the value is a string, can do all ops found = (String) found_obj; - } else if (found_obj instanceof Double | found_obj instanceof Integer) { + } else if (found_obj instanceof java.lang.Double | + found_obj instanceof java.lang.Integer) { // the value is an double or integer, convert to string found = String.valueOf(found_obj); } else if (found_obj instanceof LinkedHashMap) { @@ -481,14 +451,12 @@ private boolean execute_json(List vars) throws ParsingException { } catch (com.jayway.jsonpath.PathNotFoundException e) { applicable = true; - System.out.println("Set true 6"); - return op == CheckOps.IS_NOT_PRESENT; - } catch (ClassCastException e) { + return op == IS_NOT_PRESENT; + } catch (java.lang.ClassCastException e) { throw new ParsingException("Error in check, json matched value cast exception: " + e); } applicable = true; // at this point the path has been found so the check is applicable - System.out.println("Set true 7"); switch (op) { case IS: @@ -496,7 +464,8 @@ private boolean execute_json(List vars) throws ParsingException { case IS_NOT: return !op_val.equals(found); case CONTAINS: - if (!value_is_array) return found.contains(op_val); + if (!value_is_array) + return found.contains(op_val); else { // the matched value is an array if (!value_list.isEmpty()) { @@ -513,9 +482,10 @@ private boolean execute_json(List vars) throws ParsingException { } } case NOT_CONTAINS: - if (!value_is_array) return !found.contains(op_val); + if (!value_is_array) + return !found.contains(op_val); else { - // the matched value is an array + //the matched value is an array if (!value_list.isEmpty()) { // check against a value array for (String elem : value_list) { @@ -539,44 +509,36 @@ private boolean execute_json(List vars) throws ParsingException { return !value_list.contains(found); case IS_SUBSET_OF: if (!value_is_array) - throw new ParsingException( - "Matched single element in jwt, but should be an array when using IS SUBSET OF"); + throw new ParsingException("Matched single element in jwt, but should be an array when using IS SUBSET OF"); return value_list.containsAll(found_array); - case MATCHES_REGEX: - { - if (value_is_array) - throw new ParsingException( - "Check error: cannot execute a regex over a list"); - Pattern p = Pattern.compile(op_val); - Matcher m = p.matcher(found); - return m.find(); - } - case NOT_MATCHES_REGEX: - { - if (value_is_array) - throw new ParsingException( - "Check error: cannot execute a regex over a list"); - Pattern p = Pattern.compile(op_val); - Matcher m = p.matcher(found); - return !m.find(); + case MATCHES_REGEX: { + if (value_is_array) throw new ParsingException("Check error: cannot execute a regex over a list"); + Pattern p = Pattern.compile(op_val); + Matcher m = p.matcher(found); + return m.find(); + } + case NOT_MATCHES_REGEX: { + if (value_is_array) throw new ParsingException("Check error: cannot execute a regex over a list"); + Pattern p = Pattern.compile(op_val); + Matcher m = p.matcher(found); + return !m.find(); + } + case JSON_SCHEMA_COMPLIANT: { + JsonSchema schema = null; + JsonNode node = null; + try { + // parse the schema + schema = getJsonSchemaFromStringContent(op_val); + ObjectMapper mapper = new ObjectMapper(); + node = mapper.readTree(found); + } catch (JsonProcessingException e) { + throw new ParsingException(e.getMessage()); } - case JSON_SCHEMA_COMPLIANT: - { - JsonSchema schema = null; - JsonNode node = null; - try { - // parse the schema - schema = getJsonSchemaFromStringContent(op_val); - ObjectMapper mapper = new ObjectMapper(); - node = mapper.readTree(found); - } catch (JsonProcessingException e) { - throw new ParsingException(e.getMessage()); - } - Set errors = schema.validate(node); - return errors.isEmpty(); - } + Set errors = schema.validate(node); + return errors.isEmpty(); + } } return false; @@ -591,8 +553,7 @@ private boolean execute_json(List vars) throws ParsingException { public boolean do_check(String val_to_check) throws ParsingException { try { if (this.op == null && val_to_check.length() != 0) { - // if it passed all the splits without errors, the param is present, but no checks - // are specified + // if it passed all the splits without errors, the param is present, but no checks are specified // so result is true return true; } @@ -618,33 +579,30 @@ public boolean do_check(String val_to_check) throws ParsingException { } break; case IS_PRESENT: - return !val_to_check - .isEmpty(); // if it gets to this, the searched param is already found + return !val_to_check.isEmpty(); // if it gets to this, the searched param is already found case IS_NOT_PRESENT: return val_to_check.isEmpty(); case IS_IN: return value_list.contains(val_to_check); case IS_NOT_IN: return !value_list.contains(val_to_check); - case MATCHES_REGEX: - { - Pattern p = Pattern.compile(op_val); - Matcher m = p.matcher(val_to_check); - return m.find(); - } - case NOT_MATCHES_REGEX: - { - Pattern p = Pattern.compile(op_val); - Matcher m = p.matcher(val_to_check); - return !m.find(); - } + case MATCHES_REGEX: { + Pattern p = Pattern.compile(op_val); + Matcher m = p.matcher(val_to_check); + return m.find(); + } + case NOT_MATCHES_REGEX: { + Pattern p = Pattern.compile(op_val); + Matcher m = p.matcher(val_to_check); + return !m.find(); + } default: throw new ParsingException("Unsupported operand for Check in a message: " + op); } } catch (ArrayIndexOutOfBoundsException e) { - // e.printStackTrace(); + //e.printStackTrace(); if (this.op != null) { - if (this.op != CheckOps.IS_NOT_PRESENT) { + if (this.op != IS_NOT_PRESENT) { return false; } } else { @@ -657,14 +615,15 @@ public boolean do_check(String val_to_check) throws ParsingException { /** * Executes the given check (without API). Used to match messages with msg_types usually. * - * @param message the message to check + * @param message the message to check * @param isRequest if the message is a request or a response * @return the result of the check (passed or not passed) */ - public boolean execute(HTTPReqRes message, boolean isRequest, List vars) - throws ParsingException { + public boolean execute(HTTPReqRes message, + boolean isRequest, + List vars) throws ParsingException { + - System.out.println("entrato in execute senza API"); result = execute_http(message, isRequest, vars); return result; } @@ -675,14 +634,13 @@ public boolean execute(HTTPReqRes message, boolean isRequest, List vars) * @param vars the variables of the actual operation (test) */ public void execute(List vars) throws ParsingException { - System.out.println("entrato in execute con API"); if (imported_api instanceof Operation_API) { // If is inside a standard Operation - result = - execute_http( - ((Operation_API) imported_api).message, - ((Operation_API) imported_api).is_request, - vars); + result = execute_http( + ((Operation_API) imported_api).message, + ((Operation_API) imported_api).is_request, + vars + ); } else if (imported_api instanceof DecodeOperation_API) { // if inside a decode operation switch (((DecodeOperation_API) imported_api).type) { @@ -690,10 +648,10 @@ public void execute(List vars) throws ParsingException { result = execute_json(vars); break; case NONE: - // TODO + //TODO break; case XML: - // TODO + //TODO break; } } @@ -713,20 +671,18 @@ public String toString() { } public String toStringExtended() { - String template = - "Check:\n" - + "\tWhat: %s\n" - + "\tIs it a param check? %b\n" - + "\tregex: %s\n" - + "\tWhere: %s\n" - + "\tOp: %s\n" - + "\tOp val: %s\n" - + "\tValue list: %s\n" - + "\tUse variable: %b\n" - + "\tUrl decode: %b\n"; - - return String.format( - template, + String template = "Check:\n" + + "\tWhat: %s\n" + + "\tIs it a param check? %b\n" + + "\tregex: %s\n" + + "\tWhere: %s\n" + + "\tOp: %s\n" + + "\tOp val: %s\n" + + "\tValue list: %s\n" + + "\tUse variable: %b\n" + + "\tUrl decode: %b\n"; + + return String.format(template, StringEscapeUtils.escapeJava(what), isParamCheck, StringEscapeUtils.escapeJava(regex), @@ -738,8 +694,7 @@ public String toStringExtended() { url_decode); } - protected JsonSchema getJsonSchemaFromStringContent(String schemaContent) - throws ParsingException { + protected JsonSchema getJsonSchemaFromStringContent(String schemaContent) throws ParsingException { JsonSchema res = null; try { JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4); @@ -750,7 +705,9 @@ protected JsonSchema getJsonSchemaFromStringContent(String schemaContent) return res; } - /** enum containing all the possible check operations */ + /** + * enum containing all the possible check operations + */ public enum CheckOps { IS, IS_NOT, @@ -770,8 +727,7 @@ public enum CheckOps { * * @param input the input string * @return the CheckOps enum value - * @throws ParsingException if the input string does not correspond to any of the possible - * check operations + * @throws ParsingException if the input string does not correspond to any of the possible check operations */ public static CheckOps fromString(String input) throws ParsingException { if (input != null) { @@ -803,7 +759,9 @@ public static CheckOps fromString(String input) throws ParsingException { } } - /** Used in the Check operation, to specify where is the content to check. */ + /** + * Used in the Check operation, to specify where is the content to check. + */ public enum CheckIn { // standard message HEAD, @@ -837,4 +795,4 @@ public static CheckIn fromString(String input) throws ParsingException { } } } -} +} \ No newline at end of file diff --git a/tool/src/main/java/org/zaproxy/addon/migt/ExecutePassives.java b/tool/src/main/java/org/zaproxy/addon/migt/ExecutePassives.java index cf34526..6ba42b4 100644 --- a/tool/src/main/java/org/zaproxy/addon/migt/ExecutePassives.java +++ b/tool/src/main/java/org/zaproxy/addon/migt/ExecutePassives.java @@ -115,6 +115,8 @@ public void run() { public Session executePassiveTestSession(Session session) { // FIXME: session's track is assumed to be present + System.out.println("Eseguito executePassiveTestSession"); + synchronized (lock) { finished = false; } diff --git a/tool/src/main/java/org/zaproxy/addon/migt/HTTPReqRes.java b/tool/src/main/java/org/zaproxy/addon/migt/HTTPReqRes.java index 199e79e..7aa287d 100644 --- a/tool/src/main/java/org/zaproxy/addon/migt/HTTPReqRes.java +++ b/tool/src/main/java/org/zaproxy/addon/migt/HTTPReqRes.java @@ -21,7 +21,6 @@ import org.apache.http.util.CharArrayBuffer; import org.parosproxy.paros.db.DatabaseException; import org.parosproxy.paros.model.HistoryReference; -import org.parosproxy.paros.network.HtmlParameter; import org.parosproxy.paros.network.HttpHeaderField; import org.parosproxy.paros.network.HttpMalformedHeaderException; import org.parosproxy.paros.network.HttpMessage; @@ -108,11 +107,10 @@ public HTTPReqRes(byte[] request, byte[] response) { * *

--> now changed to create it from a HistoryReference * - * @param hmsg the history reference to access the message + * @param message the history reference to access the message */ - public HTTPReqRes(HistoryReference hmsg) + public HTTPReqRes(HttpMessage message) throws MalformedURLException, HttpMalformedHeaderException, DatabaseException { - HttpMessage message = hmsg.getHttpMessage(); this.isRequest = true; this.isResponse = true; @@ -132,7 +130,7 @@ public HTTPReqRes(HistoryReference hmsg) URL url = new URL(readURI); this.setRequest_url(url.toString()); - // utilizzo HttpRequestHeader perchè in teoria è solo per le richieste + // utilizzo HttpRequestHeader perchè sembra che httpmessage consenga sempre il RequestHeader HttpRequestHeader service = message.getRequestHeader(); this.setHost(service.getHostName()); this.setPort(service.getHostPort()); @@ -198,15 +196,10 @@ public HTTPReqRes(HttpMessage message, boolean isRequest, int index) { this.headers_req = toStringList(message.getRequestHeader().getHeaders()); - // changed this by adding -// for (HtmlParameter p : message.getUrlParams()) { -// this.headers_req.add(p.toString()); -// } - this.request_url = message.getRequestHeader().getURI().toString(); this.body_offset_req = message.getRequestHeader().toString().length(); - // set host infogetHttpService + // set host info getHttpService HttpRequestHeader service = message.getRequestHeader(); this.setHost(service.getHostName()); this.setPort(service.getHostPort()); @@ -261,45 +254,6 @@ public static List parse_url_query_no_decoding( return list; } - // public HttpMessage replaceBurpMessage(HttpMessage message) throws - // HttpMalformedHeaderException, URIException { - // if (isRequest) { - // message.setRequestHeader(Req_header); - // message.setRequestBody(Req_body); - // - // } - // if (isResponse) { - // message.setResponseHeader(Res_header); - // message.setResponseBody(Res_body); - // } - // if (host != null && port != 0 && protocol != null) { - // if (protocol == "https"){ - // message.getRequestHeader().setSecure(true); - // } else { - // message.getRequestHeader().setSecure(false); - // } - // - // org.apache.commons.httpclient.URI origialURI = new - // org.apache.commons.httpclient.URI(request_url, true); - // - // org.apache.commons.httpclient.URI newURI = new org.apache.commons.httpclient.URI( - // origialURI.getScheme(), - // null, - // host, - // port, - // origialURI.getPath(), - // origialURI.getQuery(), - // origialURI.getFragment() - // ); - // - // //set host and port values by changing the URI - // message.getRequestHeader().setURI(newURI); - // - // - // } - // return message; - // } - public String getUrlHeader() { if (!isRequest) throw new RuntimeException("called getUrlHeader on a response message"); @@ -1019,25 +973,39 @@ public void updateHeadersWHurl() throws RuntimeException { * @return true or false, if matched or not respectively */ public boolean matches_msg_type(MessageType msg_type, boolean is_request) { - System.out.println("eseguito matches_msg_type"); + System.out.println("Checks are:"); + for(Check c : msg_type.checks){ + System.out.println(c.toStringExtended()); + } boolean matchedMessage = false; try { /* If the response message name is searched, the getByResponse will be true. * so messageIndex have to search for the request, and then evaluate the response */ if (msg_type.getByResponse) { - if (!isResponse) return false; // both request and response have to be present + System.out.println("-------------> First if"); + if (!isResponse){ + System.out.println("-------------> return false since both request and response have to be present"); + return false; // both request and response have to be present + } matchedMessage = Tools.executeChecks( msg_type.checks, this, true, new ArrayList<>() // TODO: fix ); + System.out.println("-------------> First if end"); } else if (msg_type.getByRequest) { - if (!isResponse) return false; // both request and response have to be present + System.out.println("-------------> Second if"); + if (!isResponse){ + System.out.println("-------------> return false since both request and response have to be present"); + return false; // both request and response have to be present + } matchedMessage = Tools.executeChecks( msg_type.checks, this, false, new ArrayList<>() // TODO: fix ); + System.out.println("-------------> Second if end"); } else { + System.out.println("-------------> Third if"); // this check is done to avoid matching request messages when intercepting a // response if (is_request != msg_type.msg_to_process_is_request) return false; @@ -1050,9 +1018,10 @@ public boolean matches_msg_type(MessageType msg_type, boolean is_request) { msg_type.isRequest, new ArrayList<>() // TODO: fix ); + System.out.println("-------------> Third if end"); } } catch (Exception e) { - e.printStackTrace(); + System.err.println(e.getMessage()); } System.out.println("return di matches_msg_type is " + matchedMessage); return matchedMessage; diff --git a/tool/src/main/java/org/zaproxy/addon/migt/Operation.java b/tool/src/main/java/org/zaproxy/addon/migt/Operation.java index 0927947..4578b21 100644 --- a/tool/src/main/java/org/zaproxy/addon/migt/Operation.java +++ b/tool/src/main/java/org/zaproxy/addon/migt/Operation.java @@ -1,12 +1,13 @@ package org.zaproxy.addon.migt; -import static org.zaproxy.addon.migt.Tools.buildStringWithVars; -import static org.zaproxy.addon.migt.Tools.executeChecks; -import static org.zaproxy.addon.migt.Tools.executeDecodeOps; -import static org.zaproxy.addon.migt.Tools.executeEditOps; -import static org.zaproxy.addon.migt.Tools.executeMessageOperations; -import static org.zaproxy.addon.migt.Tools.findParentDiv; -import static org.zaproxy.addon.migt.Tools.getVariableByName; +import static org.zaproxy.addon.migt.Tools.*; +//import static org.zaproxy.addon.migt.Tools.buildStringWithVars; +//import static org.zaproxy.addon.migt.Tools.executeChecks; +//import static org.zaproxy.addon.migt.Tools.executeDecodeOps; +//import static org.zaproxy.addon.migt.Tools.executeEditOps; +//import static org.zaproxy.addon.migt.Tools.executeMessageOperations; +//import static org.zaproxy.addon.migt.Tools.findParentDiv; +//import static org.zaproxy.addon.migt.Tools.getVariableByName; import java.util.ArrayList; import java.util.List; @@ -439,6 +440,9 @@ public void setAPI(Operation_API api) { } public void execute() { + + System.out.println("Entrato in execute"); + if (!preconditions.isEmpty()) { try { applicable = @@ -485,6 +489,7 @@ public void execute() { // The order of execution is very important try { applicable = true; + System.out.println("Set true 22"); executeMessageOperations(this); if (!applicable | !result) return; executeEditOps(this, api.vars); diff --git a/tool/src/main/java/org/zaproxy/addon/migt/ParsingException.java b/tool/src/main/java/org/zaproxy/addon/migt/ParsingException.java index 1b695bf..46b6c40 100644 --- a/tool/src/main/java/org/zaproxy/addon/migt/ParsingException.java +++ b/tool/src/main/java/org/zaproxy/addon/migt/ParsingException.java @@ -2,7 +2,7 @@ /** Exception raised when the parsing of the language fails */ public class ParsingException extends Exception { - private static final long serialVersionUID = 1L; +// private static final long serialVersionUID = 1L; /** * Raised when there is a problem in the parsing of the json diff --git a/tool/src/main/java/org/zaproxy/addon/migt/Session.java b/tool/src/main/java/org/zaproxy/addon/migt/Session.java index 60fc4e7..ec07a84 100644 --- a/tool/src/main/java/org/zaproxy/addon/migt/Session.java +++ b/tool/src/main/java/org/zaproxy/addon/migt/Session.java @@ -101,21 +101,22 @@ public SessionTrackAction next() { * the message is checked against some common file extension and if it is matched it is * discarded * - * @param hmsg the message to be added + * @param msg the message to be added * @param filter specify if filtering is enabled * @return the added message */ - public HTTPReqRes addMessage(HistoryReference hmsg, boolean filter) + public HTTPReqRes addMessage(HttpMessage msg, boolean filter) throws URISyntaxException, MalformedURLException, HttpMalformedHeaderException, DatabaseException { HTTPReqRes res = null; - HttpMessage message = hmsg.getHttpMessage(); + if (filter) { - String forURI = message.getRequestHeader().getURI().toString(); - URI uri = new URI(forURI); - String url = uri.toURL().toString(); +// String forURI = message.getRequestHeader().getURI().toString(); +// URI uri = new URI(forURI); +// String url = uri.toURL().toString(); + String url = msg.getRequestHeader().getPrimeHeader(); url = url.split("\\sHTTP")[0]; Pattern pattern = Pattern.compile( @@ -124,11 +125,11 @@ public HTTPReqRes addMessage(HistoryReference hmsg, boolean filter) Matcher matcher = pattern.matcher(url); if (!matcher.find()) { - res = new HTTPReqRes(hmsg); + res = new HTTPReqRes(msg); messages.add(res); } } else { - res = new HTTPReqRes(hmsg); + res = new HTTPReqRes(msg); messages.add(res); } return res; diff --git a/tool/src/main/java/org/zaproxy/addon/migt/Test.java b/tool/src/main/java/org/zaproxy/addon/migt/Test.java index 338ad58..a90e4c1 100644 --- a/tool/src/main/java/org/zaproxy/addon/migt/Test.java +++ b/tool/src/main/java/org/zaproxy/addon/migt/Test.java @@ -442,8 +442,15 @@ public void logTest(String log_folder) { * @param msg_types the message types used by the test * @return true if a test is passed, false otherwise */ + + //jump here -- remove this comment + public boolean execute(List messageList, List msg_types) throws ParsingException { + + System.out.println("Entrato in execute di Test"); + + int i, j; boolean res = true; @@ -483,6 +490,8 @@ public boolean execute(List messageList, List msg_types } } + System.out.println("About to return --> " + res); + return res; } diff --git a/tool/src/main/java/org/zaproxy/addon/migt/Tools.java b/tool/src/main/java/org/zaproxy/addon/migt/Tools.java index 3b418d7..2e18059 100644 --- a/tool/src/main/java/org/zaproxy/addon/migt/Tools.java +++ b/tool/src/main/java/org/zaproxy/addon/migt/Tools.java @@ -34,9 +34,11 @@ public static boolean executeChecks( System.out.println("eseguito executeChecks"); for (Check c : checks) { if (!c.execute(message, isRequest, vars)) { + System.out.println("executeChecks will return false"); return false; } } + System.out.println("executeChecks will return true"); return true; } diff --git a/tool/src/main/java/org/zaproxy/addon/migt/ZAPextender.java b/tool/src/main/java/org/zaproxy/addon/migt/ZAPextender.java index 294abc1..30b55cf 100644 --- a/tool/src/main/java/org/zaproxy/addon/migt/ZAPextender.java +++ b/tool/src/main/java/org/zaproxy/addon/migt/ZAPextender.java @@ -62,12 +62,6 @@ private AbstractPanel getStatusPanel(GUIclass _mainPane_) { statusPanel.setName("MIG-T"); statusPanel.setIcon(new ImageIcon(getClass().getResource("/resources/logofbk1.png"))); - // //setup output stream in Burp - // OutputStream stdOut = callbacks.getStdout(); - // OutputStream stdErr = callbacks.getStderr(); - // printStream = new PrintStream(stdOut); - // errorStream = new PrintStream(stdErr); - // this should allow you to test the operation but could // Imply redirection // of all ZAP stderr and stdout to our panel @@ -78,8 +72,6 @@ private AbstractPanel getStatusPanel(GUIclass _mainPane_) { printStream = new PrintStream(stdOut); errorStream = new PrintStream(stdErr); - // TODO: this should not be needed, it's a duplicate - // mainPane = new GUIclass(); _mainPane_.messageViewer = new ReqResPanel(); _mainPane_.splitPane.setRightComponent(mainPane.messageViewer); @@ -93,42 +85,6 @@ private AbstractPanel getStatusPanel(GUIclass _mainPane_) { return statusPanel; } - // This is the starting Burp code, replaced by the hook function - - // public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { - // System.out.println("Initializing extension"); - // - // this.callbacks = callbacks; - // helpers = callbacks.getHelpers(); - // - // callbacks.setExtensionName("MIG Testing tool"); - // - // //The UI is created - // SwingUtilities.invokeLater(() -> { - // // setup output stream - // OutputStream stdOut = callbacks.getStdout(); - // OutputStream stdErr = callbacks.getStderr(); - // - // printStream = new PrintStream(stdOut); - // errorStream = new PrintStream(stdErr); - // - // mainPane = new Main(); - // mainPane.callbacks = callbacks; - // mainPane.messageViewer = callbacks.createMessageEditor(mainPane.controller, - // false); - // mainPane.splitPane.setRightComponent(mainPane.messageViewer.getComponent()); - // - // - // // add the custom tab to Burp's UI - // callbacks.addSuiteTab(/*BurpExtender.*/this); - // - // // register ourselves as an HTTP listener - // callbacks.registerProxyListener(/*BurpExtender.*/this); - // //callbacks.registerHttpListener(BurpExtender.this); - // }); - // - // - // } @Override public boolean canUnload() { @@ -150,12 +106,10 @@ public String getDescription() { @Override public boolean onHttpRequestSend(HttpMessage msg) { - boolean messageIsRequest; - if (msg.getRequestHeader().isEmpty()) { - messageIsRequest = false; - } else { - messageIsRequest = true; - } + boolean messageIsRequest = true; + +// getView().getOutputPanel().append("\nInside RequestSent \n msg.getRequestHeader = " + msg.getRequestHeader() + +// "\nmsg.getResponseHeader = " + msg.getResponseHeader()); try { HistoryReference historyRef = @@ -164,9 +118,8 @@ public boolean onHttpRequestSend(HttpMessage msg) { HistoryReference.TYPE_TEMPORARY, msg); msg.setHistoryRef(historyRef); - } catch (HttpMalformedHeaderException e) { - throw new RuntimeException(e); - } catch (DatabaseException e) { + } catch (HttpMalformedHeaderException | DatabaseException e) { + System.err.println(e.getMessage()); throw new RuntimeException(e); } @@ -178,36 +131,6 @@ public boolean onHttpRequestSend(HttpMessage msg) { // proxy_message.getMessageReference() msg.getHistoryRef().getHistoryId()); - getView() - .getOutputPanel() - .append( - "\n\n ////////////////////////////////////////////////////////// \n\n Processing message header --> " - + msg.getRequestHeader() - + "\n\n --------------------------------------------------------------- \n\n Single headers \n"); - - if (message.isRequest) { - getView() - .getOutputPanel() - .append(msg.getRequestHeader().getPrimeHeader() + "\n\n-------------------------------------\n"); - - for (HttpHeaderField s : msg.getRequestHeader().getHeaders()) { - getView() - .getOutputPanel() - .append(s.toString() + "\n\n-------------------------------------\n"); - } - } else if (message.isResponse) { - getView() - .getOutputPanel() - .append(msg.getResponseHeader().getPrimeHeader() + "\n\n-------------------------------------\n"); - - for (HttpHeaderField s : msg.getResponseHeader().getHeaders()) { - getView() - .getOutputPanel() - .append(s.toString() + "\n\n-------------------------------------\n"); - } - } - - System.out.println("mainPane.INTERCEPT_ENABLED = " + mainPane.INTERCEPT_ENABLED); if (mainPane.INTERCEPT_ENABLED) { // /* Check at which port of the proxy the message has been received @@ -226,8 +149,7 @@ public boolean onHttpRequestSend(HttpMessage msg) { MessageType.getFromList( mainPane.messageTypes, mainPane.actual_operation.getMessageType()); } catch (Exception e) { - e.printStackTrace(); - System.out.println("Error position is ZAPextender 0"); + System.err.println("error ZapExtender 1: \n" + e.getMessage()); mainPane.actual_operation.applicable = false; } @@ -250,53 +172,50 @@ public boolean onHttpRequestSend(HttpMessage msg) { // TO BE SENT } } catch (Exception e) { - e.printStackTrace(); - System.out.println("Error position is ZAPextender 1"); + System.err.println("error ZapExtender 2: \n" + e.getMessage()); mainPane.actual_operation.applicable = false; } } } } + + + //questo pezzo in teoria non viene mai eseguito visto che messageIsRequest è true if (mainPane.recording) { if (!messageIsRequest) { // do not remove synchronized (mainPane.interceptedMessages) { + try { - HistoryReference historyRef = - new HistoryReference( - Model.getSingleton().getSession(), - HistoryReference.TYPE_TEMPORARY, - msg); - mainPane.interceptedMessages.add(new HTTPReqRes(historyRef)); + mainPane.interceptedMessages.add(new HTTPReqRes(msg, messageIsRequest, msg.getHistoryRef().getHistoryId())); +// getView().getOutputPanel().append( +// "The intercepted messages list is long = " + mainPane.interceptedMessages.size() + "and contains:\n\n" + +// mainPane.interceptedMessages.get(mainPane.interceptedMessages.size()-1).getUrl() + "\n\n" + +// mainPane.interceptedMessages.get(mainPane.interceptedMessages.size()-1).Res_header + "\n\n" + +// mainPane.interceptedMessages.get(mainPane.interceptedMessages.size()-1).Req_header + "\n\n -------------------------------------- \n"); +// System.out.println("interceptedMessages size after add = " + mainPane.interceptedMessages.size()); if (mainPane.defaultSession != null) { - mainPane.defaultSession.addMessage(historyRef, mainPane.FILTERING); + mainPane.defaultSession.addMessage(msg, mainPane.FILTERING); } - - } catch (HttpMalformedHeaderException e) { - throw new RuntimeException(e); - } catch (DatabaseException e) { - throw new RuntimeException(e); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } catch (URISyntaxException e) { + } catch (MalformedURLException | DatabaseException | URISyntaxException | + HttpMalformedHeaderException e) { + System.err.println("error ZapExtender 5: \n" + e.getMessage()); throw new RuntimeException(e); } } } } - return true; } @Override public boolean onHttpResponseReceive(HttpMessage msg) { - boolean messageIsRequest; - if (msg.getRequestHeader().isEmpty()) { - messageIsRequest = false; - } else { - messageIsRequest = true; - } + boolean messageIsRequest = false; + + + getView().getOutputPanel().append("\nInside ResponseReceive \n msg.getRequestHeader = " + msg.getRequestHeader() + + "\nmsg.getResponseHeader = " + msg.getResponseHeader()); try { HistoryReference historyRef = @@ -342,8 +261,7 @@ public boolean onHttpResponseReceive(HttpMessage msg) { MessageType.getFromList( mainPane.messageTypes, mainPane.actual_operation.getMessageType()); } catch (Exception e) { - e.printStackTrace(); - System.out.println("Error position is ZAPextender 2"); + System.err.println("error ZapExtender 3: \n" + e.getMessage()); mainPane.actual_operation.applicable = false; } @@ -362,35 +280,37 @@ public boolean onHttpResponseReceive(HttpMessage msg) { // TO BE SENT } } catch (Exception e) { - e.printStackTrace(); - System.out.println("Error position is ZAPextender 3"); + System.err.println("error ZapExtender 4: \n" + e.getMessage()); mainPane.actual_operation.applicable = false; } } } } + + if (mainPane.recording) { + //questo check viene superato -- rimuovi questo commento if (!messageIsRequest) { // do not remove synchronized (mainPane.interceptedMessages) { + try { - HistoryReference historyRef = - new HistoryReference( - Model.getSingleton().getSession(), - HistoryReference.TYPE_TEMPORARY, - msg); - mainPane.interceptedMessages.add(new HTTPReqRes(historyRef)); + mainPane.interceptedMessages.add(new HTTPReqRes(msg, messageIsRequest, msg.getHistoryRef().getHistoryId())); + getView().getOutputPanel().append( + "\n\n" + mainPane.interceptedMessages.get(mainPane.interceptedMessages.size() - 1).getHeadersString(false) + + "\n\n"); +// getView().getOutputPanel().append( +// "The intercepted messages list is long = " + mainPane.interceptedMessages.size() + "and contains:\n\n" + +// mainPane.interceptedMessages.get(mainPane.interceptedMessages.size()-1).getUrl() + "\n\n" + +// mainPane.interceptedMessages.get(mainPane.interceptedMessages.size()-1).Res_header + "\n\n" + +// mainPane.interceptedMessages.get(mainPane.interceptedMessages.size()-1).Req_header + "\n\n -------------------------------------- \n"); +// System.out.println("interceptedMessages size after add = " + mainPane.interceptedMessages.size()); if (mainPane.defaultSession != null) { - mainPane.defaultSession.addMessage(historyRef, mainPane.FILTERING); + mainPane.defaultSession.addMessage(msg, mainPane.FILTERING); } - - } catch (HttpMalformedHeaderException e) { - throw new RuntimeException(e); - } catch (DatabaseException e) { - throw new RuntimeException(e); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } catch (URISyntaxException e) { + } catch (MalformedURLException | DatabaseException | URISyntaxException | + HttpMalformedHeaderException e) { + System.err.println("error ZapExtender 5: \n" + e.getMessage()); throw new RuntimeException(e); } } @@ -414,6 +334,11 @@ private void processMatchedMsg(MessageType msg_type, HTTPReqRes messageInfo) { mainPane.actual_operation.setAPI( new Operation_API(messageInfo, msg_type.msg_to_process_is_request)); + + + System.out.println("Just before execute in processMatchedMsg"); + + mainPane.actual_operation.execute(); // if message has been edited inside operation update the value