Using the SANS DShield REST API

The SANS announced the availability of the Microsoft Patch Data on the 5th of April.
They have actually added both a REST API and a new web interface.

I’ve written a tiny module that uses the 3 Dshield REST API methods and made sure you can bind the resulting functions together. The last piece of the puzzle is a function to get the 2nd Tuesday of a month.

The module is available in a github repository and in the PowerShell Gallery

To get a nice display of Microsoft security bulletins, you can do:

(Get-SecondTuesday -Year 2016 -Month 04).ToString('yyyy-MM-dd') |
Get-SansMSPatchDay | Select @{l='Bulletin';e={$_.Id}},title,
 @{l='Components Affected';e={$_.affected}},
 @{l='kb';e={$_.kb -as [string]}},
 @{l='Known Exploits';e={
  switch($_.exploits) {
   'yes' { $true}
   'no'  {$false}
   default {}
}},severity,clients,servers | Out-GridView -Title "April, 2016"

NB1: The long select properties list aims only to force the KB property to be displayed as a string by Out-GridView. There’s no problem in the console with the raw json format.
NB2: Next month, you can also omit the -Year and -Month parameters of the Get-SecondTuesday function. By default this function returns the second Tuesday of the current month as a datetime object.

Now that we have seen how to use the functions each month.

Let’s say we want to do something more complicated and get an overview of what happened last year.

First store dates formatted the way the REST API expects them:

# Summary for 2015
$2015BTDates = 1..12 | ForEach-Object {
    (Get-SecondTuesday -Year 2015 -Month $_).ToString('yyyy-MM-dd')


Pull all the bulletins from 2015 and store the info in a variable:

# Get Bulletins
$2015Bulletins = $2015BTDates | Get-SansMSPatchDay

We also see above the first bulletin MS15-001 and the last one MS15-135.

Sure there were 135 bulletins in 2015? Actually No! The following tells us that there were only 133 bulletins 😎

# Total bulletins in 2015
$2015Bulletins.Id | Measure


How many bulletins have addressed one or more known vulnerabilities exploited in the wild?

# Only known exploits
$2015Bulletins | Where 'exploits' -eq 'yes' |
Select -Property Id | Measure


19 known exploits over how many vulnerabilities fixed by these bulletins?

# Get CVEs
$2015CVEs  = $2015Bulletins | Get-SansMSPatchCVE

# Total CVEs
$2015CVEs | Select -expand cve | Sort -Unique | Measure


"{0:P2}" -f $(19/220)

That makes 8.64%

What months got the most bulletins released?:

# Total bulletins per month in 2015
1..12 | ForEach-Object {
        Month = $_ ;
        Bulletins = $(
            (Get-SecondTuesday -Year 2015 -Month $_).ToString('yyyy-MM-dd') | 
            Get-SansMSPatchDay | Select -Expand Id 
} | Select Month,Bulletins,
@{l='Count';e={ $_.Bulletins | Measure-Object | Select -Expand Count}}


How many vulnerabilities were addressed each month?

# Total CVEs per month in 2015
1..12 | ForEach-Object {
        Month = $_ ;
        CVEs = $(
            (Get-SecondTuesday -Year 2015 -Month $_).ToString('yyyy-MM-dd') | 
            Get-SansMSPatchDay | Get-SansMSPatchCVE | Select -Expand cve
} | Select Month,CVEs,
@{l='Count';e={ $_.CVEs |  Sort -Unique | Measure-Object | Select -Expand Count}}


Let’s go crazy and retrieve from all the SANS data (almost 10 years) and filter out what bulletins were rated “PATCH NOW” by the SANS:

2006..2016 | ForEach-Object {
    $Y = $_
    1..12 | ForEach-Object {
        $M = $_
        Get-SecondTuesday -Year $Y -Month $M
} | ForEach-Object {

    Write-Verbose -Message "Query MS Patch Day API of SANS for date: $($_.ToString('yyyy-MM-dd'))" -Verbose
    $_.ToString('yyyy-MM-dd') | Get-SansMSPatchDay
} | Where { $_.clients -eq 'patch now' -or $_.servers -eq 'patch now' } | 
Select Id,Title,affected,
    @{l='kb';e={$_.kb -as [string]}},
    @{l='Known Exploits';e={
        switch($_.exploits) {
            'yes' { $true}
            'no'  {$false}
            default {}
    }},severity,clients,servers | ogv

NB1: you’ll see inconsistencies when affected components get named. You’ve got for example: IE, MSIE or Internet Explorer.
NB2: the SANS bulletin id’s are not numbered the same way Microsoft did before 2010. You’ve got MS90-32 instead of MS09-032 for example.

Don’t blame the SANS, they did a nice job by providing these REST API methods.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s