Thursday, 3 April 2014

Hacking ZAP #3 - Passive scan rules

One of the easiest ways to enhance ZAP is to write new passive scan rules.Passive scan
rules are used to warn the user of potential vulnerabilities that can be
detected passively - they are not allowed to make any new requests or
manipulate the requests or responses in any way.They typically run against all of the requests and responses that flow through ZAP.Passive rules run in separate background thread so that they have as little effect on performance as possible.

You can write passive scan rules dynamically using scripts, as we will see later in this series, but even then its very useful to understand some of the concepts and the underlying classes available to you.

Where to start

The easiest way to get started is to rip off an existing rule.Passive scan rules can be found in 3 locations in the zap-extensions project, depending on their status:

This is called for every response. All details of the request and response are available via the 'msg' parameter, as detailed below. The response is also available as a DOM structure via the ‘source’ parameter.

You can implement one or both of these methods depending on your requirements.

You can examine any part of the request and response in order to find potential vulnerabilities, but you must not change anything.

If you find a potential vulnerability then you can raise it via the method:

PassiveScanThread.raiseAlert(int id, Alert alert)

An HttpMessage is passed in to both of the ‘scan’ methods. This class has methods that allow you to access all aspects of the request and response, although the latter is obviously only available in scanHttpResponseReceive.

Some examples include:

msg.getRequestHeader().getMethod();

msg.getRequestHeader().getHttpCookies();

msg.getRequestHeader().getHeaders();

msg.getRequestHeader().getContentLength();

msg.getRequestBody().toString();

msg.getResponseHeader().getHeaders();

msg.getResponseHeader().getStatusCode();

msg.getResponseBody().toString();

A Source parameter is passed into scanHttpResponseReceive - this is a DOM representation of the response generated by the Jericho HTML parser.

See the Jericho documentation or the other scan rules for examples of how to access DOM elements.

There are actually a set of vulnerabilities.xml files as it is internationalized, so ZAP will read the localized version for the language the user has selected, defaulting back to English for any phrases that have not been translated.

This is therefore a quick and easy way to fill in these details, as long as the relevant vulnerability is included in that file.

It also uses the log4j Logger class to output debug messages. This is the recommended way of outputting such messages.

Note that the pluginId needs to be unique across all active and passive scan rules. The master list of ids is alert.xml

If you are just implementing the rule for your own benefit then you can hardcode the strings if you want, but internationalizing them is very simple and saves having to go back and change you code if you want to have your rule included in the ZAP Marketplace.

The code also makes use of the getLevel() method.

This returns an AlertThreshold class which indicates how strictly you should check for vulnerabilities.

The threshold returned can be one of:

LOW: This indicates you should report more potential vulnerabilities, which might mean more false positives

MEDIUM: This is the default level

HIGH: This indicates you should report fewer potential vulnerabilities, which might mean more false negatives

You do not have to use the threshold - especially as it might not be relevant for the vulnerability you are testing for, but it is also a useful way for the user to tune how the rules work and so its worth using if you can.

Building and deploying

All you need to do is run the deploy-pscanrulesAlpha target and the relevant add-on will be built and copied to the correct location, assuming you have a ZAP core project called ‘zaproxy’.

If you want to deploy to a different location then you can change it at the top of the file. ZAP automatically extracts the files specified in the manifest into a directory underneath the ZAP user directory.An knowledgeable user can manually edit these files and any changes will take affect when ZAP is restarted.

Updating the help and manifest

There are a couple more things that you can do to finish off a new rule.

The first is to add a short description of the rule to the help file: pscanalpha.html

This is not really necessary unless you want to publish your rules.

The second is to include the new class along with any files it uses in the add-on manifest: ZapAddOn.xml

ZAP uses this file to identify any files that need to be extracted.It also uses it when it downloads add-ons from the ZAP Marketplace, and adding your classes and files in here will allow ZAP to add, update and remove your rules dynamically.

A future post will cover how to contribute your code back to the ZAP community and progress it from alpha to beta and then release status.

You dont need to disable active scanning - active scanning only happens when you explicitly start it, so if you dont want to use it then dont :) Just explore you app by proxying your browser through ZAP and/or by using the ZAP spiders. Passive scanning will then be done automatically.