Closed MihaiOnofrei closed 4 years ago
Hi @MihaiOnofrei. The API does not directly provide this capability without retrieving the vulnerabilities for each asset individually (/api/3/assets/{id}/vulnerabilities). However, a SQL query report could be generated, downloaded, and parsed to obtain this data using significantly fewer API requests.
We have an example of the report creation, generation, and download process here: https://github.com/rapid7/vm-console-client-python/blob/master/samples/generate_sql_report.py
Unfortunately, both /api/3/assets/{id}/vulnerabilities and generated reports do not provide enough information about the vulnerabilities as the '/api/3/vulnerabilities' does.
I need to gather at least the fields: description, severity, categories, modified and some href for each vulnerability that affects an asset. Do you have any suggestion on what is the fastest way to achieve this via the API?
Current version I have is creating multiple async requests to get all the vulnerabilities( 500 per request) until I find the ones I need. The API does not support any filtering to access only the elements I need.
I think that a query similar to the one below may get you the data that you require (albeit with a bit of additional processing of list columns). It could be modified to filter for specific assets/vulnerabilities.
WITH urls AS (
SELECT
v.vulnerability_id,
vr.reference
FROM
dim_vulnerability v
JOIN dim_vulnerability_reference vr USING (vulnerability_id)
WHERE vr.source = 'URL'
), cves AS (
SELECT
v.vulnerability_id,
vr.reference
FROM
dim_vulnerability v
JOIN dim_vulnerability_reference vr USING (vulnerability_id)
WHERE vr.source = 'CVE'
)
SELECT
da.asset_id,
da.host_name,
da.ip_address,
dos.description AS operating_system,
dv.title,
htmltotext(dv.description) AS description,
dv.severity,
round(dv.cvss_score::numeric, 2) AS cvss_score,
string_agg(DISTINCT dvc.category_name, ',') AS categories,
string_agg(DISTINCT urls.reference, ',') AS urls,
string_agg(DISTINCT cves.reference, ',') AS cves
FROM dim_asset da
JOIN dim_operating_system dos USING (operating_system_id)
JOIN fact_asset_vulnerability_finding favf USING (asset_id)
JOIN dim_vulnerability dv USING (vulnerability_id)
JOIN dim_vulnerability_category dvc USING (vulnerability_id)
JOIN urls USING (vulnerability_id)
JOIN cves USING (vulnerability_id)
GROUP BY da.asset_id, da.host_name, da.ip_address, dos.description,
dv.title, dv.description, dv.severity, dv.cvss_score;
The results from that query are as follows:
As Tyler mentioned, using a query is likely your best option when trying to retrieve very specific information - especially in such large quantity. A sample script of creating and generating a report can be found here: https://github.com/rapid7/vm-console-client-python/blob/master/samples/generate_sql_report.py. Hope this helps!
Issues and Contributing
When entering /vulnerability/listing.jsp on my rapid7 instance i get 830 vulnerabilities that affect assets.
When requesting the vulnerabilities with the api i get 150k listings. There is no method to fetch only the vulnerabilities that affect assets.
It the same behavior from the UI achievable with this api?