A while back I got an email from Perry, one of our readers who was having a problem using my cvescan script, which I covered in a 3 part story back in 2021:
The problem was simple, the script had just stopped working. The NVD API version 1.0 had been retired in Dec 2023, and of course I had no idea. A quick visit to their website got me the details of this change:
Anyway - this turned into a simple enough set of changes for my script, but some fundamental changes to the API itself. Full docs for the API start here:
First, they moved from an open restful API to one that (they say) requires an API key (more on this later). This takes care of change notifications in future, because you have to register to get a key. Watch your spam folder, Outlook helpfully placed the email with the registration link in it in my Junk Email folder.
The original call in the NVD 1.0 API to collect CVE's for a specific product IOD (CPE) is:
$request = "https://services.nvd.nist.gov/rest/json/cves/1.0?modStartDate=" + $StartDate + "&cpeMatchString=" + $app.cpe
$CVEs = (invoke-webrequest $request | ConvertFrom-Json).result.CVE_items.cve.CVE_data_meta.id
Similarly, the NVD 1.0 API call to collect the metadtaa for a specific CVE:
$request = "https://services.nvd.nist.gov/rest/json/cve/1.0/" + $CVE.CVE
$cvemetadata = (invoke-webrequest $request) | convertfrom-json
In the version 2 API, let's construct an example call, looking for CVE's in Windows 10. For a review of CPE's, check out the first 3 parts of this story. I often "feed" CVEScan by collecting CPE's using nmap for instance. Anyway, back to constructing the request:
$cpematchstring = "cpe:2.3:o:microsoft:windows_10:1607:*:*:*:*:*:*:*"
$request = "https://services.nvd.nist.gov/rest/json/cves/2.0?cpeName=" + $cpematchstring
Now let's make the call and look at the fields we get back:
(invoke-webrequest $request | ConvertFrom-Json) | gm
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
format NoteProperty string format=NVD_CVE
resultsPerPage NoteProperty int resultsPerPage=2000
startIndex NoteProperty int startIndex=0
timestamp NoteProperty string timestamp=2024-04-23T17:40:15.370
totalResults NoteProperty int totalResults=2574
version NoteProperty string version=2.0
vulnerabilities NoteProperty Object[] vulnerabilities=System.Object[]
Now let's look at the vulnerability list, picking just a random item in the list:
$v = (invoke-webrequest $request | ConvertFrom-Json).vulnerabilities
$v[7].cve
id : CVE-2016-0170
sourceIdentifier : [email protected]
published : 2016-05-11T01:59:10.027
lastModified : 2018-10-12T22:11:24.817
vulnStatus : Modified
descriptions : {@{lang=en; value=GDI in Microsoft Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7
SP1, Windows 8.1, Windows Server 2012 Gold and R2, Windows RT 8.1, and Windows 10 Gold and 1511
allows remote attackers to execute arbitrary code via a crafted document, aka "Windows Graphics
Component RCE Vulnerability."}, @{lang=es; value=GDI en Microsoft Windows Vista SP2, Windows Server
2008 SP2 y R2 SP1, Windows 7 SP1, Windows 8.1, Windows Server 2012 Gold y R2, Windows RT 8.1 y
Windows 10 Gold y 1511 permite a atacantes remotos ejecutar c??digo arbitrario a trav??s de un
documento manipulado, tambi??n conocido como "Windows Graphics Component RCE Vulnerability".}}
metrics : @{cvssMetricV30=System.Object[]; cvssMetricV2=System.Object[]}
weaknesses : {@{[email protected]; type=Primary; description=System.Object[]}}
configurations : {@{nodes=System.Object[]}}
references : {@{url=http://packetstormsecurity.com/files/137096/Microsoft-Windows-gdi32.dll-ExtEscape-Buffer-Over
flow.html; [email protected]}, @{url=http://www.securityfocus.com/bid/89864;
[email protected]}, @{url=http://www.securitytracker.com/id/1035823;
@{url=https://docs.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-055;
There's no need for a second call, all the NVD metadata is in the returned data for that first call! You can just keep parsing as deep as you want until you get the exact fields that you want! For instance, if we just want the CVE list:
$cvelist = $v.id
$cvelist
CVE-2013-3900
CVE-2015-6184
CVE-2016-0088
... and so on
Or if you wanted the CVE list and the last modified date:
$datelist = (invoke-webrequest $request | ConvertFrom-Json).vulnerabilities.cve | select id,lastModified
$datelist
id lastModified
-- ------------
CVE-2013-3900 2022-11-02T15:15:43.850
CVE-2015-6184 2018-10-12T22:10:41.470
CVE-2016-0088 2018-10-12T22:11:00.707
CVE-2016-0089 2018-10-12T22:11:00.910
.. and so on
Sticking with our favourite item lucky 7, the description would be:
$v[7].cve.descriptions[0].value
GDI in Microsoft Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8.1, Windows Server 2012 Gold and R2, Windows RT 8.1, and Windows 10 Gold and 1511 allows remote attackers to execute arbitrary code via a crafted document, aka "Windows Graphics Component RCE Vulnerability."
To get exploitability and import scores for both version 2 and version 3 of the CVSS Metric:
$v[7].cve.metrics.cvssmetricv2
ource : [email protected]
type : Primary
cvssData : @{version=2.0; vectorString=AV:N/AC:M/Au:N/C:C/I:C/A:C; accessVector=NETWORK;
accessComplexity=MEDIUM; authentication=NONE; confidentialityImpact=COMPLETE;
integrityImpact=COMPLETE; availabilityImpact=COMPLETE; baseScore=9.3}
baseSeverity : HIGH
exploitabilityScore : 8.6
impactScore : 10.0
acInsufInfo : False
obtainAllPrivilege : False
obtainUserPrivilege : False
obtainOtherPrivilege : False
userInteractionRequired : True
$v[7].cve.metrics.cvssmetricv2.impactscore
10.0
$v[7].cve.metrics.cvssmetricv2.exploitabilityscore
8.6
And for v3:
$v[7].cve.metrics.cvssmetricv30
source : [email protected]
type : Primary
cvssData : @{version=3.0; vectorString=CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H; attackVector=NETWORK;
attackComplexity=LOW; privilegesRequired=NONE; userInteraction=REQUIRED; scope=UNCHANGED;
confidentialityImpact=HIGH; integrityImpact=HIGH; availabilityImpact=HIGH; baseScore=8.8;
baseSeverity=HIGH}
exploitabilityScore : 2.8
impactScore : 5.9
$v[7].cve.metrics.cvssmetricv30.exploitabilityscore
2.8
$v[7].cve.metrics.cvssmetricv30.impactscore
5.9
$v[7].cve.metrics.cvssmetricv30.cvssdata
version : 3.0
vectorString : CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
attackVector : NETWORK
attackComplexity : LOW
privilegesRequired : NONE
userInteraction : REQUIRED
scope : UNCHANGED
confidentialityImpact : HIGH
integrityImpact : HIGH
availabilityImpact : HIGH
baseScore : 8.8
baseSeverity : HIGH
$v[7].cve.metrics.cvssmetricv30.cvssdata.basescore
8.8
Going back to collect the URL references:
$v[7].cve.references | fl
url : http://packetstormsecurity.com/files/137096/Microsoft-Windows-gdi32.dll-ExtEscape-Buffer-Overflow.html
source : [email protected]
url : http://www.securityfocus.com/bid/89864
source : [email protected]
url : http://www.securitytracker.com/id/1035823
source : [email protected]
url : https://docs.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-055
source : [email protected]
So, for just the URLs:
$v[7].cve.references.url
http://packetstormsecurity.com/files/137096/Microsoft-Windows-gdi32.dll-ExtEscape-Buffer-Overflow.html
http://www.securityfocus.com/bid/89864
http://www.securitytracker.com/id/1035823
https://docs.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-055
The API key? So far I haven't needed it. This may just be a way of the NVD folks getting a list of the developers that use their API (with email addresses), so that they can tell us in advance when API 2.1 or 3.0 is about to be released(?) If it is, I'm 100% OK with that, I WANT to know in advance if someone else is going to break my code!
As always, I'll update my cvescan script in the next few days to match the new API, you can find it in my github then at https://github.com/robvandenbrink
If you have used external APIs in your code, then had the API unexpectedly change on you and bite you, please use our comment form and share the details (if your NDA permits?)
===============
Rob VandenBrink
[email protected]