用于从 Nessus 插件输出中捕获 CVE 的正则表达式

Regex to capture CVEs from Nessus plugin output

我有一个看起来像这样的输出块:

- 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

我能够轻松获得 KB 和 MS 值,但我很难提取后面的所有 CVE 编号。是否可以根据字符串“-”拆分我的输出,以便我得到这样的字符串:

- 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

从这里我想我可以用 -AllMatches 做一个正则表达式来得到我想要的。

我会打开这些行,这样您的所有记录都是以连字符开头的单行,然后在换行符处拆分字符串。

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

如果输入不是单个字符串,请先通过 Out-String 进行输入。

使用带有正则表达式 CVE-\d{4}-\d{4,} 和参数 -AllMatchesSelect-String(如您所料)。

... | Select-String 'CVE-\d{4}-\d{4,}' -AllMatches |
    ForEach-Object { $_.Matches.Value }

我假设您希望保留 KB/MS 标识符和 CVE 代码之间的关系。

为此,我会填充一个哈希表,只需逐行读取文本,每次遇到 KB 行时更新密钥:

# 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
        }
    }
}

如果输入已经是一个大字符串,使用以下将其拆分为单独的行:

$bigString -split "`r?`n" |ForEach-Object { ... }