Qualys API client examples

Document created by Parag Baxi on Oct 3, 2013Last modified by Jeff Leggett on Feb 22, 2017
Version 44Show Document
  • View in full screen mode

Note: This is unsupported.

 


Purpose

This is a community driven document to demonstrate examples of how to connect to the Qualys API using various platforms.

 

C#, RestSharp

The open source library assists in making calls to all API versions:

http://restsharp.org/

 

API v1

Sample code:

 


using System;

using System.Collections.Generic;

using System.Xml;

using System.Xml.Linq;

using System.Linq;

using System.Text;

using RestSharp;



// Set up REST client to connect to US Platform 1.

var client = new RestClient("
https://qualysapi.qualys.com
");


// Set up credentials.

client.Authenticator = new HttpBasicAuthenticator("username", "password");

//

// GET request

// See QualysGuard version.

//

var request = new RestRequest("msp/about.php");

IRestResponse response = client.Execute(request);

// Response contains the XML file.


Console.WriteLine (response.Content);


//

// POST request.

// Download raw scan results of scan/1234567890.12345.

//

// This method does not work!

// var request_post = new RestRequest ("msp/scan_report.php", Method.POST);

// request_post.AddParameter("ref", "scan/1390453521.15910");

//

// This method does work.

var endpoint =  String.Format("msp/scan_report.php?{0}={1}",

          "ref", "scan/1234567890.12345");

var request_post = new RestRequest (endpoint, Method.POST);

response = client.Execute(request_post);

// Print out headers to see remaining calls against API limits.

foreach (var header in response.Headers){

          Console.WriteLine(header);

}

// Print scan results.

Console.WriteLine(response.Content)





 

API v2

Sample code:

 


using System;

using System.Collections.Generic;

using System.Xml;

using System.Xml.Linq;

using System.Linq;

using System.Text;

using RestSharp;



// Set up REST client to connect to US Platform 1.

var client = new RestClient("
https://qualysapi.qualys.com
");


// Set up credentials.

client.Authenticator = new HttpBasicAuthenticator("username", "password");

//

// v2 GET request.


// Print out scans that ended in error.

//

var request = new RestRequest("api/2.0/fo/scan/", Method.GET);

// Add header, reqiured for v2 API.

request.AddHeader("X-Requested-With", "RestSharp");

request.AddParameter("action", "list");

response = client.Execute(request);

var xml_text = response.Content;

// Let's see where we are on our API limit. Do we need to throttle our script?

foreach (var header in response.Headers){

          Console.WriteLine(header);

}

Console.WriteLine ("\n(Press enter to continue.)");

pause_me = Console.ReadLine();

//

// Parse the XML to make it actionable.

//

// Load XML string.

XDocument xdoc = XDocument.Parse(xml_text);

// Parse XML for each scan.

var scans = from scan in xdoc.Descendants ("SCAN")

            select new {

          scan_ref = (string)scan.Element ("REF"),

          title = (string)scan.Element ("TITLE"),

          status = (string)scan.Element("STATUS").Element("STATE")

};





// Print out each scan reference, title, and status.

// Join the data into a string.

StringBuilder result = new StringBuilder();

//Loop through results

foreach (var scan in scans)

{

          result.AppendLine(scan.scan_ref + "  " + scan.title + "  " + scan.status);

}

Console.WriteLine(result.ToString());





// Print only scans that ended in error.

StringBuilder error_result = new StringBuilder();

//Loop through results

foreach (var scan in scans)

{

          if (scan.status == "Error") {

                    error_result.AppendLine (scan.scan_ref + "  " + scan.title + "  " + scan.status);

          }

}

Console.WriteLine(error_result.ToString());





 

Go Language Example

AM API

Go lends itself very well to Qualys' REST based API's - it includes builtin library support for HTTP and XML parsing.  Further it's built in concurrency support will make multi threaded apps easy to use as well.  Here's an initial example of using Go with the Asset Management API's

package main

import (
"encoding/base64"
"encoding/xml"
"flag"
"fmt"
"io/ioutil"
"net/http"
)

func Get_Credential_Hash(User string, Password string) string {

return base64.StdEncoding.EncodeToString([]byte(User + ":" + Password))
}

func Get_Command_Line_Args() (string, string, string) {
/* Get cmd line paramters */
UserPtr := flag.String("User", "BOGUS", "Qualys Account User Name")
PasswordPtr := flag.String("Password", "BOGUS", "Qualys Account password")
APIURLPtr := flag.String("API URL", "https://qualysapi.qualys.com/", "Qualys API endpoint")
flag.Parse()
return *UserPtr, *PasswordPtr, *APIURLPtr
}

func QAPI_Hostasset_Count() int {

type Hostasset_Count struct {
ResponseCode string `xml:"responseCode"`
Count int `xml:"count"`
}
User, Password, APIURL := Get_Command_Line_Args()
encodedcred := Get_Credential_Hash(User, Password)

url := APIURL + "qps/rest/2.0/count/am/hostasset/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-requested-with", "GOLANG")
req.Header.Add("authorization", "Basic "+encodedcred)
/* req.Header.Add() */
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
/* fmt.Println(res)
fmt.Println(string(body)) */
var c Hostasset_Count
xml.Unmarshal(body, &c)
if c.ResponseCode == "SUCCESS" {
return c.Count
} else {
return -1
}
}

func main() {

var numassets int
numassets = QAPI_Hostasset_Count()
if numassets >= 0 {
fmt.Println("Numnber of Assets:", numassets)
}
}
 

Groovy, httpbuilder's RESTClient

This open source package assists in making calls to all API versions.

 

API v1

Sample code:

 


import groovyx.net.http.RESTClient

// Set up REST client.

def qgc = new RESTClient('
https://qualysapi.qualys.com/msp/
')


// Set headers.

qgc.defaultRequestHeaders.'X-Requested-With' = 'Groovy'

qgc.auth.basic 'username', 'password'

// Optional: Force response handler to pass raw text to pass onto a parser like SAX.

//qgc.parser.'application/xml' = qgc.parser.'text/plain'

// Call API via GET.

def response = qgc.get(path:'about.php')

// Store body of data separately.

def xml = response.getData()





 

API v2

Sample code:

 


TODO





 

WAS API

Sample code:

 


TODO





 

AM API

Sample code:

 


TODO







 

Perl, LWP

The open source library assists in making calls to all API versions.

API v1 and v2

Sample code:

 


use LWP;                # retrieving data via HTTPS



# Set base url to US Pod 1.

my $APIURL = "qualysguard.qualys.com"



# retrieves Scan_history for the account and saves to file

my $url = "
https://$APIURL/api/2.0/fo/asset/host/?action=list&details=All&ag_titles=All+Compliance&no_vm_scan_since=2013-12-07
";




# Set creds.

my $username = "username";

my $passwd = "password";



# Set up request headers.

my $browser = LWP::UserAgent->new;

$browser->default_headers->header('X-Requested-With' => 'Sample');

$browser->agent("libwww - script");



# Send GET request.

my $request = HTTP::Request->new( GET=>$url );

$request->authorization_basic($username, $passwd);

my $response = $browser->request($request);

my $content = $response->content;



## Save to file.

open( XMLOUT, ">output.xml" );

print XMLOUT $content;

close( XMLOUT );





 

WAS API

Sample code:

 


TODO





 

AM API

Sample code:

 


TODO





 

PHP 5+, SimpleQAPI class

This community published package by Peter Stiehl assists in making calls to the API:

Simple PHP Qualys API class

API v1 and v2

Sample code:

 


$params = array('qlogin' => 'Qualys login',

                'connectTimeout' => 10',

                'timeout' => 59',

                'qpassword' => 'Qualys Password',

                'qdomain' => 'Qualys domain without HTTP', // For example 'qualysapi.qualys.com'

                'plogin' => 'Proxy login',

                'ppassword' => 'Proxy password',

                'headers' => array('X-Requested-With: SimpleQAPI'),

   
         

'purl' => '
http://proxy.to.use
',


             

'pport' => 'port number');

$SimpleQAPI = new SimpleQAPI($params);

// You have to use the login() method to be able to launch the view_xxx_list() methods

// For each request the answer is stored in $SimpleQAPI->resp

$SimpleQAPI->login();

// This should print : 201x-xx-xxTxx:xx:xxZ Logged in

echo $SimpleQAPI->resp;

$SimpleQAPI->logout();





 

WAS API

Sample code:

 


TODO





 

PHP 4+, curl

Initialize a cURL session from PHP: http://www.php.net/manual/en/function.curl-exec.php

API v1 and v2

Sample code:

 


<?php

$username=ENTER_YOUR_USERNAME;

$password=ENTER_YOUR_PASSWORD;

$ch = curl_init();

$cookieJar = dirname(__FILE__) . '/cookie.txt';

curl_setopt($ch, CURLOPT_URL, "
https://qualysapi.qualys.com/api/2.0/fo/session/
");


curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Requested-With: PHP curl
'));

curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieJar);

curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, "action=login&username=$username&password=$password");

$result = curl_exec ($ch) or die(curl_error($ch));

echo $result;

echo curl_error($ch);

$ch = curl_init ("
https://qualysapi.qualys.com/api/2.0/fo/appliance/
");


curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Requested-With: PHP curl'));

curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookieJar);

curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, "action=list&output_mode=full");

$output = curl_exec ($ch);

echo $output;

curl_close ($ch);

?>






 

WAS API

Sample code:

 


TODO





 

AM API

Sample code:

 


TODO





 

Python 2.x, qualysapi

This open source package assists in making calls to all API versions.

 

More info:

https://github.com/paragbaxi/qualysapi

API v1

Sample code:

 


import qualysapi



# Setup connection to QualysGuard API -- only perform once per script.

qgc = qualysapi.connect('config.txt')

# API v1 call: Scan the New York & Las Vegas asset groups

# The call is our request's first parameter.

call = 'scan.php'

# The parameters to append to the url is our request's second parameter.

parameters = {'scan_title': 'Go big or go home', 'asset_groups': 'New York&Las Vegas', 'option': 'Initial+Options'}

# Note qualysapi will automatically convert spaces into plus signs for API v1 & v2.

# Let's call the API and store the result in xml_output.

xml_output = qgc.request(call, parameters)

print xml_output





 

API v2

Sample code:

 


import qualysapi



# Setup connection to QualysGuard API -- only perform once per script.

qgc = qualysapi.connect('config.txt')

# API v2 call: Print out DNS name for a range of IPs.

call = '/api/2.0/fo/asset/host/'

parameters = {'action': 'list', 'ips': '10.0.0.10-10.0.0.11'}

xml_output = qgc.request(call, parameters)





 

WAS API

Sample code:

 


import qualysapi

from lxml import objectify



# Setup connection to QualysGuard API -- only perform once per script.

qgc = qualysapi.connect('config.txt')

# API v3 WAS call: Print out number of webapps.

call = '/count/was/webapp'

# Note that this call does not have a payload so we don't send any data parameters.

xml_output = qgc.request(call)

root = objectify.fromstring(xml_output)

# Print out count of webapps.

print root.count.text

# Prints out:

# 89

#

# API v3 WAS call: Print out number of webapps containing title 'Supafly'.

call = '/count/was/webapp'

# We can send a string XML for the data.

parameters = '<ServiceRequest><filters><Criteria operator="CONTAINS" field="name">Supafly</Criteria></filters></ServiceRequest>'

xml_output = qgc.request(call, parameters)

root = objectify.fromstring(xml_output)

# Print out count of webapps.

print root.count.text

# Prints out:

# 3

#

# API v3 WAS call: Print out number of webapps containing title 'Lightsabertooth Tiger'.

call = '/count/was/webapp'

# We can also send an lxml.builder E object.

parameters = (

    E.ServiceRequest(

        E.filters(

            E.Criteria('Lightsabertooth Tiger', field='name',operator='CONTAINS'))))

xml_output = qgc.request(call, parameters)

root = objectify.fromstring(xml_output)

# Print out count of webapps.

print root.count.text

# Prints out:

# 0

# Too bad, because that is an awesome webapp name!





 

AM API

Sample code:

 


import qualysapi

from lxml import objectify



# Setup connection to QualysGuard API -- only perform once per script.

qgc = qualysapi.connect('config.txt')

# API v3 Asset Management call: Count tags.

call = '/count/am/tag'

xml_output = qgc.request(call)

root = objectify.fromstring(xml_output)

# We can use XPATH to find the count.

print root.xpath('count')[0].text

# Prints out:

# 840

#

# API v3 Asset Management call: Find asset by name.

call = '/search/am/tag'

parameters = '''<ServiceRequest>

        <preferences>

            <limitResults>10</limitResults>

        </preferences>

        <filters>

            <Criteria field="name" operator="CONTAINS">PB</Criteria>

        </filters>

    </ServiceRequest>'''


xml_output = qgc.request(call, parameters)





 

Pagination

Sample code for v2 Host list & detection API:

 


import qualysapi

from lxml import etree, objectify

qgc = qualysapi.connect()

# Start with first host, which starts at 1.

id_min = 1

while True:

  print 'Downloading hosts from ID %d' % id_min

  xml = qgc.request('/api/2.0/fo/asset/host/', {'action': 'list', 'ips': '10.10.10.220,10.10.24.78', 'truncation_limit': '1', 'id_min': id_min})

  # Parse.

  tree = etree.fromstring(xml)

  # Iterate through each host.

  elems = tree.findall('.//HOST')

  for host in elems:

    print host.xpath('IP')[0].text

  # Set up next request, if applicable.

  try:

    url = tree.xpath('/HOST_LIST_OUTPUT/RESPONSE/WARNING/URL')[0].text

    start = url.find('id_min') + 7

    end = url.find('&',start)

    id_min = int(url[start:end])

  except IndexError, e:

    # No next url. All hosts downloaded.

    break





 

Ruby, rest-client

Leveraging the rest-client gem, it's simple to call the Qualys API.

 

API v1

Sample code:

 


require 'rest-client'

RestClient.get '
https://username:password@qualysapi.qualys.com/msp/about.phppassword@qualysapi.qualys.com/msp/about.php
password@qualysapi.qualys.com
/msp/about.phppassword@qualysapi.qualys.com
/msp/about.php'





 

API v2

Sample code:

 


TODO





 

 

WAS

Sample code:

 


TODO





 

AM

Sample code:

 


TODO





 

 

Ruby, httparty

Leveraging the httparty gem, it's simple to call the Qualys API.

 

API v1

Sample code:

 


require 'httparty'

auth = {:username => "username", :password => "password"}

HTTParty.get("
https://qualysapi.qualys.com/msp/about.php
",


    :basic_auth => auth)




 

API v2

Sample code:

 


require 'httparty'

auth = {:username => "username", :password => "password"}

HTTParty.post("
https://qualysapi.qualys.com/api/2.0/fo/scan/
",


    :basic_auth => auth,

    :query => { :action => "list" },

    :headers => { "X-Requested-With" => "ruby httparty"})





 

 

WAS

 

Sample code:

 


TODO




 

AM

Sample code:

 


TODO





 

VB.NET, vb_net_rest_sharp

This community published example by BD@Huntington assists in making calls to API v1 & API v2:

vb_net_rest_sharp

 

VB Script, getXMLFile

This community published package by Scr1ptW1zard assists in making calls to API v1 & API v2:

 

The getXMLFile subroutine takes 4 arguments:

  1. The first argument is the API version you want to use (1 or 2).
  2. The second argument is the file to store the output in.
  3. The third argument is the API call and arguments to pass.
  4. The fourth argument is the method to use when sending the data (GET or POST).

 

API v1

Sample code:

 


getXMLFile 2, xmlResponse,"about.php", "GET"






 

API v2

Sample code:

 


getXMLFile 2, xmlName,"report/?action=fetch&id=" & reportID, "POST"





 

Web browser, Chrome, Postman

This Chrome packaged app assists in making calls to all API versions.

Install and configure POSTMAN

A one time installation of POSTMAN and environment set up is required for POSTMAN to point your request to the appropriate QualysGuard platform.

 

Install POSTMAN:

  1. Download POSTMAN: getpostman.com
  2. Open POSTMAN by pointing your Chrome browser to chrome://apps/ or by clicking on the Apps shortcut link:
    chrome apps.png
  3. Open the POSTMAN packaged app:
    postman.png

Import QualysGuard API POSTMAN settings:

  1. Download QualysGuard API POSTMAN data backup.
  2. Open POSTMAN's settings dialog.
    settings.png
  3. Restore QualysGuard API configuration and sample collections:
    Data > Import data > Choose File button
    import.png
  4. Choose the QualysGuard API POSTMAN data file.

 

Configure POSTMAN's environment to match your QualysGuard platform.

  1. Identify your QualysGuard platform and download the correlating environment configuration: Identify your QualysGuard Platform.
  2. Click on "No environment" button:
    no environment.png
  3. Select your newly imported POSTMAN environment by clicking on "No environment", and clicking on the environment you imported:
    choose environment.png

How to use sample collections

In order to leverage the sample collections, your QualysGaurd credentials be applied to each reqeust. Just follow these easy steps:

  1. Add your credentials in the "Basic Auth" tab.
    postman, credentials.png
  2. Click "Refresh headers" button.
  3. Click "Normal" tab.
  4. A new headers, "Authorization" should be populated with your basic authentication value. This should look something like, "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==".
    save.png
  5. Click the Headers button to hide the headers. (optional)
  6. Click Save. Now you will not need to add your credentials to this request for future runs.
  7. Click "Send" button to send your request.

 

Windows Powershell 3.0

This is standard on Windows 8.

API v1

Sample code:

 


$username = "username"

$password = "password"

$password_base64 = ConvertTo-SecureString $password -AsPlainText -Force

$creds = New-Object System.Management.Automation.PSCredential ($username, $password_base64)

$headers = @{"X-Requested-With"="powershell"}

$url = "https://qualysapi.qualys.com/about.php
"

Invoke-RestMethod -Headers $headers -Uri $url -Method Post -Credential $creds -OutFile response.xml





 

WAS API

Sample code:

 


TODO





 

AM API

Sample code:

 


TODO





1 person found this helpful

Attachments

    Outcomes