Skip to content

Get-PSTenableSeverity -Severity 'All with Info' doesn't return everything #16

Description

@swampmandu

Using the 'All with Info' option doesn't seem to return more than Critical findings. I moved $CurrentStartOffset = 0 inside the foreach loop to get this far. When it tries to filter for Info objects, the server returns a 500 error. Does this function correctly for you?

Expected Behavior

Returns 0-4 severity level information.

Current Behavior

$all = Get-PSTenableSeverity -Severity 'All with Info'
4 3 2 1 0
Running 4
PreJSON:
{
    "sourceType":  "cumulative",
    "query":  {
                  "endOffset":  2147483647,
                  "filters":  [
                                  {
                                      "operator":  "=",
                                      "value":  "4",
                                      "filterName":  "severity"
                                  }
                              ],
                  "startOffset":  0,
                  "type":  "vuln",
                  "tool":  "listvuln"
              },
    "sortDir":  "DESC",
    "type":  "vuln",
    "sortField":  "basescore"
}

Line Count: 8384
CurrentStartOffset: 2147483647
Max records: 0
PreJSON:
{
    "sourceType":  "cumulative",
    "query":  {
                  "endOffset":  4294967294,
                  "filters":  [
                                  {
                                      "operator":  "=",
                                      "value":  "4",
                                      "filterName":  "severity"
                                  }
                              ],
                  "startOffset":  2147483647,
                  "type":  "vuln",
                  "tool":  "listvuln"
              },
    "sortDir":  "DESC",
    "type":  "vuln",
    "sortField":  "basescore"
}

Line Count: 0
Running 3
PreJSON:
{
    "sourceType":  "cumulative",
    "query":  {
                  "endOffset":  2147483647,
                  "filters":  [
                                  {
                                      "operator":  "=",
                                      "value":  "3",
                                      "filterName":  "severity"
                                  }
                              ],
                  "startOffset":  0,
                  "type":  "vuln",
                  "tool":  "listvuln"
              },
    "sortDir":  "DESC",
    "type":  "vuln",
    "sortField":  "basescore"
}

Line Count: 125810
CurrentStartOffset: 2147483647
Max records: 0
PreJSON:
{
    "sourceType":  "cumulative",
    "query":  {
                  "endOffset":  4294967294,
                  "filters":  [
                                  {
                                      "operator":  "=",
                                      "value":  "3",
                                      "filterName":  "severity"
                                  }
                              ],
                  "startOffset":  2147483647,
                  "type":  "vuln",
                  "tool":  "listvuln"
              },
    "sortDir":  "DESC",
    "type":  "vuln",
    "sortField":  "basescore"
}

Line Count: 0
Running 2
PreJSON:
{
    "sourceType":  "cumulative",
    "query":  {
                  "endOffset":  2147483647,
                  "filters":  [
                                  {
                                      "operator":  "=",
                                      "value":  "2",
                                      "filterName":  "severity"
                                  }
                              ],
                  "startOffset":  0,
                  "type":  "vuln",
                  "tool":  "listvuln"
              },
    "sortDir":  "DESC",
    "type":  "vuln",
    "sortField":  "basescore"
}

Line Count: 260503
CurrentStartOffset: 2147483647
Max records: 0
PreJSON:
{
    "sourceType":  "cumulative",
    "query":  {
                  "endOffset":  4294967294,
                  "filters":  [
                                  {
                                      "operator":  "=",
                                      "value":  "2",
                                      "filterName":  "severity"
                                  }
                              ],
                  "startOffset":  2147483647,
                  "type":  "vuln",
                  "tool":  "listvuln"
              },
    "sortDir":  "DESC",
    "type":  "vuln",
    "sortField":  "basescore"
}

Line Count: 0
Running 1
PreJSON:
{
    "sourceType":  "cumulative",
    "query":  {
                  "endOffset":  2147483647,
                  "filters":  [
                                  {
                                      "operator":  "=",
                                      "value":  "1",
                                      "filterName":  "severity"
                                  }
                              ],
                  "startOffset":  0,
                  "type":  "vuln",
                  "tool":  "listvuln"
              },
    "sortDir":  "DESC",
    "type":  "vuln",
    "sortField":  "basescore"
}

Line Count: 12831
CurrentStartOffset: 2147483647
Max records: 0
PreJSON:
{
    "sourceType":  "cumulative",
    "query":  {
                  "endOffset":  4294967294,
                  "filters":  [
                                  {
                                      "operator":  "=",
                                      "value":  "1",
                                      "filterName":  "severity"
                                  }
                              ],
                  "startOffset":  2147483647,
                  "type":  "vuln",
                  "tool":  "listvuln"
              },
    "sortDir":  "DESC",
    "type":  "vuln",
    "sortField":  "basescore"
}

Line Count: 0
Running 0
PreJSON:
{
    "sourceType":  "cumulative",
    "query":  {
                  "endOffset":  2147483647,
                  "filters":  [
                                  {
                                      "operator":  "=",
                                      "value":  "0",
                                      "filterName":  "severity"
                                  }
                              ],
                  "startOffset":  0,
                  "type":  "vuln",
                  "tool":  "listvuln"
              },
    "sortDir":  "DESC",
    "type":  "vuln",
    "sortField":  "basescore"
}

Invoke-RestMethod : The remote server returned an error: (500) Internal Server Error.
At C:\Users\*\Documents\WindowsPowerShell\Modules\pstenable\0.2.4\private\Invoke-PSTenableRest.ps1:65 char:9
+         Invoke-RestMethod @RestMethodParams
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Possible Solution

Steps to Reproduce (for bugs)

My modified version of Get-PSTenableSeverity with some poor man's debugging:

function Get-PSTenableSeverity {
    <#
    .SYNOPSIS
        Retrieves all vulnerabilities that are Critical, High, Medium, or Low in Tenable.
    .DESCRIPTION
        This function provides a way to retrieve all vulnerabilities in Tenable that are Critical, High,
        Medium, or Low.  
        Revision 0.1, Sept 2019, jwmoss
        Revision 0.2, Nov 2019, aarong1234 
    .INPUTS
        None
    .PARAMETER Severity
        Option for any of "Critical", "High", "Medium", "Low", "All", "All with Info". Defaults to "Critical","High".  All with Info will get ALL vuln data
    .PARAMETER MaxRecords
        Option for maximum records (rows of data) that should be requested (as a throttle), Default is 0 (all records) [note: sorted by score, descending]
    .PARAMETER Detailed
        Option to enable detailed data. Defaults to Summary Data. To determine how detailed the resulting data is by querying Tenable.sc "Vulnerability Summary" versus "Vulnerability Detail"
    .OUTPUTS
        PSCustomObject
    .NOTES
        None
    .EXAMPLE
        Get-PSTenableSeverity -Severity "Critical"
        Retrieves all critical vulnerabilities, Summary Data [sorted by vprscore (note:Very OLD plugins dont have a VPR Scores)]
    .EXAMPLE
        Get-PSTenableSeverity -Detailed
        Retrieves all critical and high vulnerabilities, Detailed Data (return Tenable.sc Vulnerability Detail data instead of summary) [sorted by vprscore (note:Very OLD plugins dont have a VPR Scores)]
    .EXAMPLE 
        Get-PSTenableSeverity -Severity "High","Medium" -Maxrecords 200
        Retrieves high and medium vulnerabilities, up to 200 records, Summary Data [sorted by vprscore (note:Very OLD plugins dont have a VPR Scores)]
    .EXAMPLE
        Get-PSTenableSeverity -Severity "All" -Detailed
        Retrieves all non-info vulnerabilities, Detailed data [sorted by vprscore (note:Very OLD plugins dont have a VPR Scores)]
    #>
    [CmdletBinding()]
    param (
        [Parameter(Position = 0, Mandatory = $false)]
        [ValidateSet(
            'Critical',
            'High',
            'Medium',
            'Low',
            'Info',
            'All',
            'All with Info'

        )]
        [string[]]
        $Severity,
        
        [Parameter(Position = 1, Mandatory = $false)]
        [int]$MaxRecords = 0,

        [Parameter(Mandatory = $false)]
        [ValidateSet($true,$false)]
        [switch]
        $Detailed
        
    )

    begin {

        $TokenExpiry = Invoke-PSTenableTokenStatus
       # write-host $TokenExpiry
        if ($TokenExpiry -eq $True) {Invoke-PSTenableTokenRenewal}

        if (-not $Severity) {
            $ID = @("4","3") #Magic Numbers for Critical & High
        } elseif ($Severity -contains "All with Info") {
            $ID = @("4","3","2","1","0") #all but info
        } elseif ($Severity -contains "All") { #if $severity has both All and All with Info.. All with Info will take precedence
            $ID = @("4","3","2","1")
        } else { #if Severity has All or All with info, other values are ignored
            $ID = @() 
            switch ($Severity) {
                "Critical" { $ID += "4" }
                "High" { $ID += "3" }
                "Medium" { $ID += "2" }
                "Low" { $ID += "1" }
                "Info" { $ID += "0" }
            }
        }
        $ID = $ID | Sort-Object -Descending
				Write-host "$ID"
				#Write-host "$Severity"
    }

    process {
        $APIresults = @()
        #$CurrentStartOffset = 0

        $ID | ForEach-Object { #because of lack of useful sorting data (scores, time) within a severity in summary data... we are going to query severities in order
            $Sev = $_
            Write-host "Running $Sev"
            $CurrentStartOffset = 0

            Do {
                if ($MaxRecords -ne 0 -and $MaxRecords -lt ($CurrentStartOffset + 2147483647)) { 
                    $CurrentEndOffset = $MaxRecords
                } else {
                    $CurrentEndOffset = ($CurrentStartOffset + 2147483647)
                }

                $PreJSON = @{
                    "type"       = "vuln"
                    "sourceType" = "cumulative"
                    "sortField"    = "basescore"
                    "sortDir"      = "DESC"
                    "query"      = @{
                        "type"         = "vuln"
                        "startOffset"  = $CurrentStartOffset
                        "endOffset"    = $CurrentEndOffset
                        "tool"         = & {if ($Detailed) {"vulndetails"} else {"listvuln"}}
                    }
                }
                if ($ID) { 
                    $PreJSON.query.add("filters",[array]@{
                        "filterName"   = "severity"
                        "operator"     = "="
                        "value"        = "$Sev"
                    })
                } 
                
     						$zJSON = $(ConvertTo-Json $PreJSON -depth 5)
								Write-host "PreJSON:"
								$zJSON | Out-String | Write-Host
                $Splat = @{
                    Method   = "Post"
                    Body     = $(ConvertTo-Json $PreJSON -depth 5)
                    Endpoint = "/analysis"
                }
                #Note: initially I was paginating every 2000, but frankly it was super inefficient, now we paginate on sizeof(Int32) 
                $ThisResults = Invoke-PSTenableRest @Splat | Select-Object -ExpandProperty Response | Select-Object -ExpandProperty Results
                $lcount = $ThisResults | out-string | measure -line
                $lcount = $lcount.lines
                Write-Host "Line Count: $lcount"
                if ($ThisResults) { #non zero records came back
                    $APIresults += $Thisresults
                    #move pagination line (if you it is ever hit)
                    $CurrentStartOffset = $CurrentEndOffset
                    Write-host "CurrentStartOffset: $CurrentStartOffSet"
                    Write-host "Max records: $Maxrecords"
                    if ($Maxrecords -and ($CurrentStartOffset -ge $MaxRecords)) {$ThisResults = $Null} # we don't need to loop anymore
                    #$ThisResults = $Null
                }
            } While ($ThisResults)
        }

        $APIresults | Sort-object vprscore,basescore -Descending

    }

    end {
    }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions