Friday, March 7, 2014

Active scan scripts for OWASP ZAP Porxy; examples

The ZAP Security proxy (The OWASP Zed Attack Proxy ) is an excellent tool for penetration testing. A significant part of ZAP is active scanning for known vulnerabilities, like SQL injection etc. The active scan rules are "some how hidden", thus encoded in the plugins in Java and not editable on the fly. If you want to change them you will have to start programming  plugins. The easy solution: you may use scan scripts to create your scan pattern. The active  scripts run automatically during the scan. You may activate them per rule with right click and/or globally using the active scan configuration as shown on the picture down (ZAP version 2.3).




If you are not familiar with the ZAP source code and you need fast way to add your own pattern, then you may struggle a lot. For this reason, here are some examples. The examples are written jpython, which is personal choice.

The example refers ZAP v2.3.

Set an additional HTTP Header


you need to add the code within your scan function. Here jpython template. 

def scan(sas, msg, param, value):

  # Copy requests before reusing them
  msg = msg.cloneRequest();

  # set a Http Header
  httpRequestHeader = msg.getRequestHeader();
  httpRequestHeader.setHeader("additonalHeader","valueHeader");
  msg.setRequestHeader(httpRequestHeader);

Append URL Query parameter with the following 


import org.apache.commons.httpclient.URI; # append URL Query parameter
...
...
  uri=httpRequestHeader.getURI();
  query=uri.getQuery();

  # check if query string is empty 
  if not query=="":
   query=query+"&testParam=Values";
  else:
   query=query+"testParam=Value"; 
  newURI=org.apache.commons.httpclient.URI(uri.getScheme() , None , uri.getHost(),
  uri.getPort(), uri.getPath(), query, uri.getFragment());
  httpRequestHeader.setURI(newURI); 

New Http Body of POST request 


import org.zaproxy.zap.network.HttpRequestBody;
...
...
 # set a new HttpBody of POST reqest
  if msg.getRequestHeader().getMethod()=="POST":
   newBody=org.zaproxy.zap.network.HttpRequestBody("My New HttpBody");
   msg.setRequestBody(newBody);

Append  to existing HTTP Body 


import org.zaproxy.zap.network.HttpRequestBody;

...
...
  # 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);

Please Note that if you put Body to GET request, the script will fail with timeout.

If you are puzzled where to put all these snippets,here is following hole scrip.

Note: The script down do not simulates attack or has general purpose. It shows how embedded code parts in default template with minimal change.

"""
The scan function will typically be called for every parameter in every URL and Form for every page 

Note that new active scripts will initially be disabled
Right click the script in the Scripts tree and select "enable"  
"""
import org.zaproxy.zap.network.HttpRequestBody;
import org.apache.commons.httpclient.URI;

def scan(sas, msg, param, value):


  # Copy requests before reusing them
  msg = msg.cloneRequest();

  # set a additional Header
  httpRequestHeader = msg.getRequestHeader();
  httpRequestHeader.setHeader("additonalHeader","valueHeader");
  msg.setRequestHeader(httpRequestHeader);

  # append URL Query parameter
  uri=httpRequestHeader.getURI();
  query=uri.getQuery();

  # check if query string is empty 
  if not query=="":
   query=query+"&MyParam=Value";
  else:
   query=query+"MyParam=Value";

  newURI=org.apache.commons.httpclient.URI(uri.getScheme() , None , uri.getHost(), uri.getPort(), uri.getPath(), query, uri.getFragment());
  httpRequestHeader.setURI(newURI);  

  # set a new HttpBody of the reqest
  if msg.getRequestHeader().getMethod()=="POST":
   newBody=org.zaproxy.zap.network.HttpRequestBody("My New HttpBody");
   msg.setRequestBody(newBody);

  # 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);

  print('Custom scan called for url=' + msg.getRequestHeader().getURI().toString());

  # sendAndReceive(msg, followRedirect, handleAntiCSRFtoken)
  sas.sendAndReceive(msg, True, False);

  # Test the response here, and make other requests as required
  if (True):
   # Change to a test which detects the vulnerability
    # raiseAlert(risk, int reliability, 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
    # reliability: 0: falsePassitive, 1: suspicious, 2: warning
 
    sas.raiseAlert(1, 1, 'Active Vulnerability title', 'Full description', 
    msg.getRequestHeader().getURI().toString(), 
      param, 'Your attack', 'Any other info', 'The solution ', '', 0, 0, msg);

Enjoy your ZAP scripts