How to write a Groovy scriptlet for asset tagging

Document created by Parag Baxi on Aug 5, 2013Last modified by Nick Williams on Nov 11, 2017
Version 12Show Document
  • View in full screen mode

Read first, important

This documents how to create a Groovy scriptlet. I recommend using only if you are confident of all of the following:

  1. Understand the load/strain tagging puts on the platform.
  2. Understand the code.
  3. Can successfully modify the code on your own to fit your needs.
  4. Understand groovy scriptlets may break from a change, although we try very hard to avoid this.
  5. You would need to check the box to re-evaulate rule on save in order to apply the tags retroactively.
  6. If applicable, each tag created should have the ignore case checkbox enabled.

 

Resources

  1. http://groovy-lang.org/documentation.html

 

How it works

All dynamic tags are run against every type of asset in the subscription. This includes and may not be limited to:

  • Scanners
  • VM hosts
  • Web applications

 

Example: Parse results of QID

Let's start with building from scratch a scriptlet from our internal library:

Date: Time to scan takes over 30 minutes

 

Complete Code

Complete Groovy code below:

// Skip testing on non-VM hosts.
if(asset.getAssetType()!=Asset.AssetType.HOST) return false;

// Tag if scan time for host takes longer than threshold_minutes minutes.
threshold_minutes = 30

// Obtain results for QID 45038.
host_scan_time = asset.resultsForQid(45038L);

// return false if the asset doesn't have QID 45038
// or the results for some reason is not the expected length
if(host_scan_time == null || host_scan_time.length() <= 16)
return false;

// Parse for duration.
host_scan_time = host_scan_time.substring(15,host_scan_time.indexOf(' seconds'));

// Convert number of seconds to integer;
host_scan_time = host_scan_time.toInteger()

return host_scan_time > (threshold_minutes*60);




 

Syntax Explanation

First let's start with syntax. Each line in the code above is a unique command or comment.

  • Lines that start with "//" are comments. For example, the first line is a comment:

    // Skip testing on non-VM hosts.




  • All other lines are commands. For example, the second line is a command:

    if(asset.getAssetType()!=Asset.AssetType.HOST) return false;




  • The "asset" variable is a special variable. It is the current asset (webapp, VM host, scanner) being tested.
  • The "return" command is a special command. It returns a value, either "true" or "false", to QualysGuard. A "true" value will apply the tag, while a "false" value will remove, or not apply the tag.

 

Important: Skip inapplicable hosts

The development team has optimized the platform to be fast and scalable for tagging. The predefined (not Groovy scriplets) dynamic tagging dropdowns are especially fast since they have been optimized for tagging:

download.png

 

We want to take great care when writing Groovy scriptlets as they are not optimized. Running tests against all types of hosts unnecessarily can likely affect the speed of the platform, hence, it's important to target the type of host want to tag.

 

The first two lines test the type of host and will exit the Groovy scriptlet if the type of host is inapplicable. This should always be at the top of your Groovy scriptlet to efficiently test only hosts that should be tested.

  • When your target host to tag is a VM host, use the following code:

    // Skip testing on any non-VM hosts.

    if(asset.getAssetType()!=Asset.AssetType.HOST) return false;




  • When your target host to tag is a web application, use the following code:

    // Skip testing on any non-webapps.

    if(asset.getAssetType()!=Asset.AssetType.WEBAPP) return false;




 

Retrieve results of a QID

This Groovy scriptlet is based on whether a VM host's scan time from the automatic database is longer than a certain threshold. It's important to note that this data is taken from automatic database, so the QID must be included in the option profile for a specific scan to be included.

 

Code:


// Obtain results for QID 45038.

host_scan_time = asset.resultsForQid(45038L);




 

Note the "L" after the QID number, this is required.

 

Let's add this code to our first set of code that skips non-VM hosts. Our code now looks like this:


// Skip testing on non-VM hosts.

if(asset.getAssetType()!=Asset.AssetType.HOST) return false;

// Tag if scan time for host takes longer than threshold_minutes minutes.

threshold_minutes = 30

// Obtain results for QID 45038.

host_scan_time = asset.resultsForQid(45038L);




 

Return value to preview test.

This code is missing an important component for VM hosts. There is no value being returned that is telling QualysGuard to apply or not apply a tag! Let's add a return value of host_scan_time so that we can see what the results contain.

 

Now our code looks like this:


// Skip testing on non-VM hosts.

if(asset.getAssetType()!=Asset.AssetType.HOST) return false;

// Tag if scan time for host takes longer than threshold_minutes minutes.

threshold_minutes = 30

// Obtain results for QID 45038.

host_scan_time = asset.resultsForQid(45038L);

return host_scan_time




 

In order to view the host_scan_time variable's value, we will leverage the "Test Rule Applicability on Selected Hosts" feature. First we need to add an asset.

 

In the TAM subscription, let's add host win7-34-247 by typing it the text box labelled "Add Asset:", then click on the host from the dropdown.

download (1).png

 

Now that this asset has been added for testing, let's see what the host_scan_time value is. Click on the gear icon next to the host you want to see the script's returned value.

download (2).png

 

You should see a box pop up titled, "Groovy Rule Test Results".

download (3).png

 

This is actual data stored in the results section of QID 45038 for host win7-34-247. Pretty cool, huh?

 

You can copy and paste the returned text to see the entire value:


"Scan duration: 5286 seconds\n\nStart time: Wed, Jul 31 2013, 02:15:36 GMT\n\nEnd time: Wed, Jul 31 2013, 03:43:42 GMT"




 

More work to do here... comments welcome.

6 people found this helpful

Attachments

    Outcomes