Tuesday, 17 January 2017

Getting Qualys asset scan information via PowerShell

We use Qualys Vulnerability Management at work to scan our assets for vulnerabilities.  I needed to identify which assets hadn't been scanned in a long time.  This could be done through the web interface by going to Assets->Asset Search and searching for assets with a Last Scan Date not within X days.  But I needed to work with the results in PowerShell for further automation tasks

The Qualys API is pretty will documented here (version 1) and here (version 2).  I'm going to use version 2 of the API as that's the latest supported version at time of writing

I'm also using PowerShell version 4 as that's what I've currently got installed on my workstation & automation server



First, lets setup some variables to hold our Qualys platform name & username/password details


Then we need to do some things to create the appropriate HTTP headers which the API expects, configure the number of hosts we want information back about and eventually use PowerShell's Invoke-WebRequest to make the API request


At this point, $HttpResponse is a HtmlWebResponseObject which has a property called 'Content'.  This contains the data the Qualys server sent to us following our request


The $HttpResponse.Content is a string which is difficult to work with.  However, as we requested Qualys to return the data in XML format, we should be able to convert the string to an XML object:-


And now we can work with the XML much easier.  We can loop round each host and create a PowerShell objects for each host with the scan data, properly formed as we would expect in PowerShell


$HostAssets now can be worked with in PowerShell for easy sorting/searching


If you find this useful, please let me know via the comments section below

Stuart

EDIT 18/01/2016
The PowerShell code used in this post can be found here

7 comments:

  1. Very useful, crossing posting to Qualys community!

    ReplyDelete
  2. So if I wanted to use this to collect a different set of data, would I just change the QID? Is there a way for me to get Vulnerability and severity levels from this? Sorry.. I'm fairly new to Powershell.

    ReplyDelete
    Replies
    1. Hi, thnaks for your comment. Yes, if you change the QID, you would get the results for that QID. The PowerShell after that would be different to parse the result into a form you wanted.

      The vulnerability and severity levels are included in the response. For example, I used QID 105689 (EOL/Obsolete Software: Microsoft VC++ 2005 Detected) which returned the following elements:-
      <TYPE>Confirmed</TYPE>
      <SEVERITY>5</SEVERITY>


      Hope this helps

      Delete
  3. Thanks very much for your post.

    I found that using the CSV type may be easier to parse. Simply change the `output_type=XML` to `output_type=CSV` and then its already pre-formatted to parse. I used the following code, and apologies if this doesn't format correctly:

    $content = $HttpResponse.Content
    $lines = $content | select-string RESPONSE_BODY_CSV | select -ExpandProperty LineNumber
    $csv = content | select -Skip $lines[0] -First ($lines[2] - $lines[1] - 1) | Out-String | ConvertFrom-Csv

    # Provide optional filtering if required
    # $csv | ConvertFrom-QualysRecord
    $csv

    ReplyDelete
    Replies
    1. Amended script, as I had my array references incorrect:

      $content = $HttpResponse.Content

      # The 'CSV' has marker lines, so extract the body
      $lines = $content | select-string RESPONSE_BODY_CSV | select -ExpandProperty LineNumber

      # The lines above mark the beginning ($lines[0]) and end ($lines[1]) of the content
      $csv = content | select -Skip $lines[0] -First ($lines[1] - $lines[0] - 1) | Out-String | ConvertFrom-Csv

      # Provide optional filtering if required
      # $csv | ConvertFrom-QualysRecord
      $csv

      Delete
    2. Thanks for your comment. I'd overlooked CSV as a format, i'll see if I can make any of my scripts simpler in the future by using that format

      Delete