Before you being you need to know some small tricks
- if the script fails, it will be disabled. Look at the icon after the run.
- scripts can be activated and deactivate in the policy menu. During the development it is good to disable all other rules and test only the active scripts.
- you need to import some Java classes in Java Script (ECMAScrip Rhino). Rhino gives you the possibility to use Java classes in you Java Script parts and this is very powerful.
- If you don't know which Java classes you need, have look at ZAP sources
- Like ever script most useful way is try and error. You do not have in ZAP big debugging possibilities besides println.
I used ECMAScript (JavaSript) - Rhino but in previous blogs I used python, so feel free.
Here the important part of the script
Adding a custom header
// set a additional Header httpRequestHeader = msg.getRequestHeader(); httpRequestHeader.setHeader("additonalHeader","valueHeader"); msg.setRequestHeader(httpRequestHeader);
Adding a custom URL parameter
// add URL params importClass(org.apache.commons.httpclient.URI); uri=httpRequestHeader.getURI(); query=uri.getQuery(); // check if query string is empty if (query!="") { query=query+"&testParam=Values"; } else { query=query+"testParam=Value"; } newURI=org.apache.commons.httpclient.URI(uri.getScheme() , null , uri.getHost(),uri.getPort(), uri.getPath(), query, uri.getFragment()); httpRequestHeader.setURI(newURI);
adding a custom test (new line) to POST requests
// append a new line to the HttpBody importClass(org.zaproxy.zap.network.HttpRequestBody); if (msg.getRequestHeader().getMethod()=="POST") { newBody=org.zaproxy.zap.network.HttpRequestBody(msg.getRequestBody().toString() + "\nMy Added HttpBody"); msg.setRequestBody(newBody); }After you send the packet
check if the response body contains some string
// get response Body rsp=msg.getResponseBody().toString(); // see if conatins certain string if (rsp.indexOf("Potental attack")>-1) { println('The response body contains the dangerous sting ""');you can clone the request again and send second packet if the attack you are testing consist of multiple packets
A small example with all part can be seen below:
Enjoy
importClass(org.zaproxy.zap.network.HttpRequestBody); importClass(org.apache.commons.httpclient.URI); function scanNode(as, msg) { // Debugging can be done using println like this // importPackage(org.apache.commons.httpclient.URI); println('scan called for url=' + msg.getRequestHeader().getURI().toString()); // Copy requests before reusing them msg = msg.cloneRequest(); // set a additional Header httpRequestHeader = msg.getRequestHeader(); httpRequestHeader.setHeader("additonalHeader","valueHeader"); msg.setRequestHeader(httpRequestHeader); uri=httpRequestHeader.getURI(); query=uri.getQuery(); // check if query string is empty if (query!="") { query=query+"&testParam=Values"; } else { query=query+"testParam=Value"; } newURI=org.apache.commons.httpclient.URI(uri.getScheme() , null , uri.getHost(),uri.getPort(), uri.getPath(), query, uri.getFragment()); httpRequestHeader.setURI(newURI); // append a new line to the HttpBody if (msg.getRequestHeader().getMethod()=="POST") { newBody=org.zaproxy.zap.network.HttpRequestBody(msg.getRequestBody().toString() + "\nMy Added HttpBody"); msg.setRequestBody(newBody); } // sendAndReceive(msg, followRedirect, handleAntiCSRFtoken) as.sendAndReceive(msg, false, false); // get response Body rsp=msg.getResponseBody().toString(); // see if conatins certain string if (rsp.indexOf("opengraphprotoco")>-1) { println('The response body contains the sting "opengraphprotoco"'); // sending a second messge // Copy requests before reusing them msgSecond = msg.cloneRequest(); // set a additional Header httpRequestHeader = msgSecond.getRequestHeader(); httpRequestHeader.setHeader("additonalHeader-Second","valueHeader-Second"); msgSecond.setRequestHeader(httpRequestHeader); as.sendAndReceive(msgSecond, false, false); // get response Header rspSecond=msgSecond.getResponseHeader().toString(); // see if conatins certain string if (rspSecond.indexOf("Server: nginx")>-1) { // raise an Alert // raiseAlert(risk, int confidence, String name, String description, String uri, // String param, String attack, String otherInfo, String solution, String evidence, // int cweId, int wascId, HttpMessage msg) // risk: 0: info, 1: low, 2: medium, 3: high // confidence: 0: falsePositive, 1: low, 2: medium, 3: high, 4: confirmed as.raiseAlert(1, 1, 'My Test Vulnarability ', 'My Test vulnarability', msg.getRequestHeader().getURI().toString(), query, 'Your attack', 'Any other info', 'The solution ', '', 0, 0, msg); } } // Test the responses and raise alerts as below msg.add // Check if the scan was stopped before performing lengthy tasks if (as.isStop()) { return } // Do lengthy task... }