Today we are going to play with the analysis API endpoint of Tenable.sc using filters directly, no pre-saved queries. That gives us the same flexibility as working on the GUI.
The tricky part is getting the structure of the requests right; I’ll give a detailed explanation of how to do it in PowerShell so you don’t have to suffer yourself π
As usual, I’m going to use PowerShell for the whole process.
FILTERS
To build the request, first we build the filters object -where we actually define which data we want to obtain in our request, which it has to be an array of hash tables - dictionaries. We need 1 dictionary per filter, with 3 keys - which are case sensitive.
- operator: =, >, <. >=, <=
- value: actual value to filter by
- filterName: one of the filters available in analysis endpoint to base the search on.
Some of the most useful filters are: cveID, cvssV3BaseScore, dnsName, exploitAvailable, familyID, firstSeen, ip, lastSeen, mitigatedStatus, patchPublished, pluginID, pluginName, pluginText, pluginType, port, protocol, repositoryIDs, severity, tcpport, udpport, ExploitAvailable (true or false), severity [0(Info), 1(low), 2(medium), 3(high), 4(critical)]
Example
Filter example to get all vulnerabilities seen in the last seven days with severity critical and exploits available:
$filters = @(
@{"filterName"="lastSeen"; "operator"="="; "value"="0:7"},
@{"filterName"="severity"; "operator"="="; "value"="4"},
@{"filterName"="exploitAvailable"; "operator"="="; "value"="true"}
)
This would be equivalent to this in the GUI:
QUERY
We have a filter, let’s do the query now. The query is a hash table or dictionary with the following keys:
- tool: this is the view in the Analysis tab. The one with more information is vulndetails
This is the complete list of tools: cceipdetail, cveipdetail, iavmipdetail, iplist, listmailclients, listservices, listos, listsoftware, listsshservers, listvuln, listwebclients, listwebservers, sumasset, sumcce, sumclassa, sumclassb, sumclassc, sumcve, sumdnsname, sumfamily, sumiavm, sumid, sumip, summsbulletin, sumprotocol, sumremediation, sumseverity, sumuserresponsibility, sumport, trend, vulndetails, vulnipdetail, vulnipsummary
And these are the ones I most use: iplist, vulndetails(Vulnerability Detail List ), vulnipsummary, listvuln(Vulnerability List), sumid(Vulnerability Summary)
- sourceType: cumulative or patched - Optional, patched means mitigated database.
- type: Set always to vuln
- createdTime, modifiedTime: Set always to 0
- name, description, context: can be set to an empty string
- sortField: Optional, which field you’d like to sort output
- startOffset, endOffset: number of records to retrieve from the total that match the filters, if you want all results use something like 0 and 9999
- filters: here goes the object we created before.
Example
Example query to get the vulnerabilities matching our filter from avobe: last 7 days, critical, exploit available.
# We use the 'vulndetails' tool to get the most data back
$query = @{"tool"="vulndetails";
"createdTime"=0;
"modifiedTime"=0;
"name"="";
"description"="";
"type"="vuln";
"sortDir"="desc";
"context"="";
"startOffset"=0;
"endOffset"=5000;
"sortField"="severity";
"filters"=$filters
}
BODY
We have the query with the filter set, next step is the body for the POST request. This is another hash table with following keys:
- sourceType: cumulative or patched
- type: in our case alway vuln
- sortDir: asc or desc - Not mandatory
- sortField: any valid field returned in results of query ( i.e. severity) - Not necessary but if present must be accompanied of sortDir
Then we have to convert to JSON to send to the API endpoint.
Example
Example of body to make the request with the query we just built
$body = @{"sourceType"="cumulative";"type"="vuln";"query"=$query} | ConvertTo-Json -Compress -Depth 5
REQUEST
We have the body, let’s make the actual request. For the login process details, refer to previous post about the topic
$scURL = 'https://192.168.5.12'
$accessKey = $env:TENABLE_ACCESS
$secretKey = $env:TENABLE_SECRET
#request headers
$headers = @{}
$headers.Add("x-apikey", "accessKey=$accessKey;secretKey=$secretKey")
# request
$request = Invoke-RestMethod -Uri $scURL/rest/analysis -Method Post -Headers $headers -Body $body -UseBasicParsing | select -ExpandProperty "response" | select -ExpandProperty "results"
And we can see the contents of the output in one of the records retrieved:
Conclusion
Now we can convert the output to CSV or any other format to process the data. We can play with the filters as well to obtain any data as we would in the GUI; I hope you found this useful π.
For a practical example of using the analysis endpoint, you can see how to find which known exploited vulnerabilities - as provided by CISA - are in your scan data following this post