Very simple diff of two Qualys Scans

Document created by Busby on Feb 4, 2018
Version 1Show Document
  • View in full screen mode

As a note I did download the scan not the report and then remove the first few lines above the column titles from the CSV.

 

Just something quick and dirty but you should be able to expand a lot.

 

Here is the code

Once you save code below to something like Qualys-diff you can execute:

Qualys-diff -qualys_rpt_1 scan_1.csv -qualys_rpt_2 scan_2.csv

 

Let me know if you have any questions.

 

param (
    [Parameter(Mandatory = $true)]
    [System.String]$qualys_rpt_1,
    [Parameter(Mandatory = $true)]
    [System.String]$qualys_rpt_2
)

 

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
Clear-Host
if ($PSVersionTable.PSVersion.Major -lt 5)
{
    Write-Error "Minimum Version of Powershell is version 5 you have Version $($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor) Installed; try to install: https://www.microsoft.com/en-us/download/details.aspx?id=54616"
    exit
}
else
{
    Write-Warning "Powershell Version $($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor) detected; we can run!"
}

 

function qualysdiff
{
    [CmdletBinding(SupportsShouldProcess = $false)]
    param
    (
        [Parameter(Mandatory = $true)]
        [System.String]$rpt1,
        [Parameter(Mandatory = $true)]
        [System.String]$rpt2
    )
    [System.Collections.Hashtable]$ObjHashtbl_rpt1 = @{ }
    [System.Collections.Hashtable]$ObjHashtbl_rpt2 = @{ }
    [System.Collections.Hashtable]$diff_rpt1 = @{ }
    [System.Collections.Hashtable]$diff_rpt2 = @{ }
    
    #these will serve to store some "temp" data for us
    
    
    [System.Object[]]$raw_rpt1 = Import-Csv $rpt1
    [System.Object[]]$raw_rpt2 = Import-Csv $rpt2
    
    #Now that I have the RAW data in memory I need a way to compare rpt1 and rpt2
    #This will be a very very simple compare just to illustrate
    #with time I could make this much more robust but would probably use something like XML/JSON to do more.
    
    foreach ($record in $raw_rpt1) { $ObjHashtbl_rpt1.Add("$($record.ip):$($record.QID):$($record.Port)", $record.title) }
    foreach ($record in $raw_rpt2) { $ObjHashtbl_rpt2.Add("$($record.ip):$($record.QID):$($record.Port)", $record.title) }
    
    #OK, Now we have the data is a "nicer" data structure, we can utilize some of the methods.
    #We will just go through and if a key is not located in the other then it is unique between scans.
    foreach ($record_key in $ObjHashtbl_rpt1.Keys)
    {
        if (-not ($ObjHashtbl_rpt2.ContainsKey($record_key)))
        {
            #Data in Scan #1 not in Scan #2    
            $diff_rpt1.Add($record_key, $ObjHashtbl_rpt1.$record_key)
        }
    }
    
    foreach ($record_key in $ObjHashtbl_rpt2.Keys)
    {
        if (-not ($ObjHashtbl_rpt1.ContainsKey($record_key)))
        {
            #Data in Scan #2 not in Scan #1
            $diff_rpt2.Add($record_key, $ObjHashtbl_rpt2.$record_key)
        }
    }
    return ($diff_rpt1, $diff_rpt2)
}

 

function writediff
{
    [CmdletBinding(SupportsShouldProcess = $false)]
    param
    (
        [Parameter(Mandatory = $true)]
        [System.String]$rpttitle,
        [Parameter(Mandatory = $true)]
        [System.String]$rpttitle2,
        [Parameter(Mandatory = $true)]
        [System.String]$key,
        [Parameter(Mandatory = $true)]
        [System.String]$vulntitle
    )
    $keypart = $key.split(":")
    Write-Output "Scan ($rpttitle) found QID $($keypart[1]) [$($vulntitle)] on Host $($keypart[0]):$($keypart[2]) and was not found in scan $($rpttitle2)"
}

 

function Main
{
    if (-not (Test-Path -Path $qualys_rpt_1))
    {
        Write-Error "Data File [$qualys_rpt_1] not located; terminating!"
    }
    elseif (-not (Test-Path -Path $qualys_rpt_2))
    {
        Write-Error "Data File [$qualys_rpt_2] not located; terminating!"
    }
    else
    {
        Write-Host "Doing a Diff between Report 1 [$qualys_rpt_1] and Report 2 [$qualys_rpt_2]"
        ($diff_1, $diff_2) = qualysdiff -rpt1 $qualys_rpt_1 -rpt2 $qualys_rpt_2
        
        if ($diff_1.count -gt 0)
        {
            foreach ($record_key in $diff_1.keys)
            {
                writediff -rpttitle $qualys_rpt_1 -rpttitle2 $qualys_rpt_2 -key $record_key -vulntitle $diff_1.$record_key
            }
        }
        else
        {
            Write-Output "No Delta identified!"
        }
        
        if ($diff_2.Count -gt 0)
        {
            foreach ($record_key in $diff_2.keys)
            {
                writediff -rpttitle $qualys_rpt_2 -rpttitle2 $qualys_rpt_1 -key $record_key -vulntitle $diff_2.$record_key
            }
            
        }
        else
        {
            Write-Output "No Delta identified!"
        }
        
        
    }
    
}

 

. Main

3 people found this helpful

Attachments

    Outcomes