0

I have a block of output that looks like this:

- KB3167679 (MS16-101) (2 vulnerabilities)The following CVEs would be covered: 
CVE-2016-3300, CVE-2016-3237
- KB3114340 (MS16-099) (16 vulnerabilities)The following CVEs would be covered: 
CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, 
CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, 
CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, 
CVE-2014-6362

I'm able to get the KB and MS values easily but I'm having a harder time pulling all the CVE numbers that follow. Is it possible to split my output based on the string "- " so that I'll get strings like this:

- KB3167679 (MS16-101) (2 vulnerabilities)The following CVEs would be covered: 
CVE-2016-3300, CVE-2016-3237
- KB3114340 (MS16-099) (16 vulnerabilities)The following CVEs would be covered: 
CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, 
CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, 
CVE-2016-3313, CVE-2016-3315, CVE-2016-3316, CVE-2016-3317, CVE-2016-3318, 
CVE-2014-6362

From here I think I could do a regex with -AllMatches to get what I want.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
Tchotchke
  • 399
  • 1
  • 2
  • 18

2 Answers2

0

I would unwrap the lines, so that all your records are single lines beginning with a hyphen, then split the string at newlines.

'...' -replace '([:,])\n', '$1 ' -split '\n'

Pipe your input through Out-String first if it's not a single string.

Use Select-String with a regular expression CVE-\d{4}-\d{4,} and the parameter -AllMatches (as you suspected).

... | Select-String 'CVE-\d{4}-\d{4,}' -AllMatches |
    ForEach-Object { $_.Matches.Value }
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
0

I assume you'd want to preserve the relationship between the KB/MS identifier and the CVE codes.

For that purpose, I would populate a hashtable, by simply reading the text line by line, updating the key every time a KB line is encountered:

# This hashtable will hold our data
$CVECoverage = @{}

$KB = 'Unknown'

# Read file line by line
Get-Content D:\test\nessus.txt |ForEach-Object {

    # Check if line is a "header" line, grab the KB/MS ID
    if($_ -like '- *')
    {
        $KB = $_.Substring(2, $_.IndexOf(')') - 1)

        # If we don't already have a record of CVEs for this KB, create a new array
        if(-not $CVECoverage.ContainsKey($KB)){
            $CVECoverage[$KB] = @()
        }
    }
    else
    {
        # Find CVEs and add to respective hashtable entry
        foreach($CVE in $_ | Select-String -Pattern 'CVE-\d{4}-\d{4,}' -AllMatches)
        {
            $CVECoverage[$KB] += $CVE.Matches.Value
        }
    }
}

If the input is already one big string, use the following to split it into individual lines:

$bigString -split "`r?`n" |ForEach-Object { ... }
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • This did the trick! I had to modify a couple lines to account for the fact that the input was coming from a field in a CSV file (I was using Import-CSV). – Tchotchke Aug 16 '16 at 21:15