Nick W.
Nick W.

Reputation: 1614

Nessus IO Powershell API HTML/PDF report

When exporting PDF & HTML format reports the reports are empty, best I can tell there needs to be a report attribute but after 5 hours of running through the API and searching every which way I can think of I am not finding anything referencing that.

For those interested, this is the starting script before I started optimizing it.

https://github.com/Pwd9000-ML/NessusV7-Report-Export-PowerShell/blob/master/NessusPro_v7_Report_Exporter_Tool.ps1

add-type @" 
    using System.Net; 
    using System.Security.Cryptography.X509Certificates; 
    public class TrustAllCertsPolicy : ICertificatePolicy { 
        public bool CheckValidationResult( 
            ServicePoint srvPoint, X509Certificate certificate, 
            WebRequest request, int certificateProblem) { 
                return true; 
                } 
    } 
"@ 
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
[System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$GNR = @{
    OutputDir = "$Env:SystemDrive\Nessus\$(([DateTime]::Now).ToString("yyyy-MM-dd"))"
    StatusUri = [System.Collections.ArrayList]::new()
}

#------------------Input Variables----------------------------------------------------------------- 
$Baseurl = "https://$($env:COMPUTERNAME):8834"
$Username = <Removed>
$Password = <Removed>
$ContentType = "application/json"
$POSTMethod = 'POST' 
$GETMethod = 'GET'

#------------------Stage props to obtain session token (Parameters)-------------------------------- 
$session = @{ 
    Uri         = $Baseurl + "/session" 
    ContentType = $ContentType 
    Method      = $POSTMethod 
    Body        = convertto-json (New-Object PSObject -Property @{username = $Username; password = $Password})
} 

#------------------Commit session props for token header X-cookie---------------------------------- 
$TokenResponse = Invoke-RestMethod @session
if ($TokenResponse) { 
    $Header = @{"X-Cookie" = "token=" + $TokenResponse.token} 
} else {
    Write-nLog -Message "Error occured obtaining session token. Script Terminating... Please ensure Username and Password Correct." -Type Error -TerminatingError
} 

IF (![System.IO.Directory]::Exists($GNR.OutputDir)) {
    New-Item -Path $GNR.OutputDir  -ItemType directory -Force |Out-Null
}

#------------------Output completed scans---------------------------------------------------------- 
$Scans = (Invoke-RestMethod -Uri "$baseurl/scans" -Headers $Header -Method $GETMethod -ContentType "application/json").scans

ForEach ($Format in @("nessus","pdf")) {
    $StatusURI = [System.Collections.ArrayList]::new()
    $StatusArray = [System.Collections.ArrayList]::new()
    ForEach ($Scan in $Scans) {
        Add-Content -Path "$($GNR.OutputDir)\ScanReport.txt" -Value "$($Scan.Name) ($($Scan.status))"
        IF ($Scan.status -eq "Completed") {
            $File = (Invoke-RestMethod -URI "$baseurl/scans/$($Scan.ID)/export" -ContentType $ContentType -Headers $Header -Method $POSTMethod -Body $(convertto-json (New-Object PSObject -Property @{format = "$Format"}))).file
            [Void]$StatusArray.Add(
                [pscustomobject]@{
                    ScanName    = $scan.name
                    StatusUri   = $baseurl + "/scans" + "/" + $Scan.id + "/export/" + "$file" + "/status"
                    DownloadUri = $baseurl + "/scans" + "/" + $Scan.id + "/export/" + "$file" + "/download"
                }
            )
        }
    }
    #------------------Check Status of Export requests------------------------------------------------- 
    While ($StatusArray.StatusUri.count -GT $StatusURI.Count) {
        ForEach ($ScanStatus in $StatusArray.StatusURI) {
            IF ((Invoke-RestMethod -Uri $ScanStatus -ContentType $ContentType -Headers $Header -Method $GETMethod).status -EQ "Ready") {
                if ($StatusURI -notcontains $ScanStatus) {
                    Write-Host "Adding $ScanStatus"
                    [void]$StatusURI.Add($ScanStatus)
                }
            } Else {
                Write-nLog -Type "Info" -Message "Not all scans complete. ($($GNR.StatusURI.Count)/$($StatusArray.StatusUri.count)"
                Start-Sleep -s 5
            }
        }
    }

    #------------------Download the Reports------------------------------------------------------------ 
    $ExportUri = $StatusArray.DownloadUri
    $outputs = $StatusArray.ScanName

    foreach ($i in 0..($ExportUri.Count - 1)) {
        Write-nLog -Type Info -Message "Exporting Report: $($outputs[$i])"
        Invoke-WebRequest -Uri $ExportUri[$i] -ContentType $ContentType -Headers $Header -Method $GETMethod -OutFile "$($GNR.OutputDir)\$($outputs[$i]).$Format"                  
    }
}
#------------------Script END----------------------------------------------------------------------

Upvotes: 0

Views: 893

Answers (1)

psedge
psedge

Reputation: 1

There are several additional parameters you can set on the POST /scans/{id}/export endpoint. The important one missed here is chapters which accepts a semi-colon delimted list of the desired content sections. This must be set for exports of pdf or html types, otherwise you get an empty result.

For example, to get the executive summary, in addition to format of html/pdf/csv etc, set chapters to vuln_hosts_summary. The other available options are:

  • vuln_by_host
  • compliance_exec
  • remediations
  • vuln_by_plugin
  • compliance

Hopefully this helps the next person trying to debug empty Nessus API exports too!

For full API docs for your version check out https://{YOUR_NESSUS_INSTALL}/api

Upvotes: 0

Related Questions