XML失败的字符串比较

时间:2012-08-31 16:43:01

标签: powershell powershell-v2.0

我目前正在使用PowerShell开发一个项目。该项目下载NVD数据库XML,通过单独的CSV循环以获取来自Nexpose的扫描结果,并为使用CVE编号标识的每个漏洞提取CVSS分数。

似乎将表格(字符串)中的CVE编号与XML(也是字符串)中的CVE编号匹配完全失败。我正在使用的代码如下:

clear
[xml]$nvdxml = (New-Object system.Net.WebClient).DownloadString("http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-recent.xml")
$nsmgr = New-Object System.XML.XmlNamespaceManager($nvdxml.NameTable)        
$nsmgr.AddNamespace('xsi','http://www.w3.org/2001/XMLSchema-instance')
$nsmgr.AddNamespace('vuln','http://scap.nist.gov/schema/vulnerability/0.4')
$nsmgr.AddNamespace('cvss','http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-recent.xml')
$nsmgr.AddNamespace('df','http://scap.nist.gov/schema/feed/vulnerability/2.0')
$nvdxml.SelectNodes('//vuln:product',$nsmgr) | out-null 
$nvdxml.SelectNodes('//vuln:vulnerable-configuration',$nsmgr) | out-null
$nvdxml.SelectNodes('//vuln:vulnerable-software-list',$nsmgr) | out-null
$nvdxml.SelectNodes('//default:nvd',$nsmgr) | out-null
$nvdxml.SelectNodes('//default:entry',$nsmgr) | out-null
$x = import-csv "test-report.csv" 
$items = @()

$x | where {$_."Vulnerability Test Result Code" -like "v*"} | %{
    $item = @{}
    $vid = $_."Vulnerability CVE IDs"
    $entry = ""
    $item["Vname"] = $_."Vulnerability Title"
    $item["VNode"] = $_."Asset IP Address"
    $item['VID'] = $vid
    $entry = $nvdxml.nvd.entry | where { $_."cve-id" -eq $vid } 
    $item['Score'] = $entry.cvss.base_metrics.score 
    $items += $item
    }
    $items

$ items数组包含一个具有CVE ID的漏洞,但字符串比较完全失败。当我查询对象的类型时,我得到了

You cannot call a method on a null-valued expression.
At line:25 char:19
+     $entry.GetType <<<< ()
    + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

当我为字符串分配CVE ID并尝试从该字符串的XML中获取相关漏洞时,比较不会返回任何结果;但是,当我用相同ID的带引号的字符串替换变量时,查询返回正确的结果。所以,这会失败

$cveID = "CVE-2003-1567"
$nvdxml.nvd.entry | where { $_."cve-id" -eq $cveID } 

然而,这很好用

$nvdxml.nvd.entry | where { $_."cve-id" -eq "CVE-2003-1567" }

有什么想法吗?我已经尝试将$ _。“cve-id”和$ cveID显式地转换为String,结果相同。

1 个答案:

答案 0 :(得分:0)

我会将所有条目放在哈希表中,然后通过CVE ID查找:

$entriesByID = @{ }
$nvdxml.nvd.entry | 
    ForEach-Object { $entriesByID[$_.id] = $_ }

请注意,我没有使用cve-id元素,而是使用id元素上的event属性。

然后,您可以在哈希表中查看每个条目:

$entry = $entriesByID[$vid]

如果您与原始方法结合,则可能会遇到名称空间问题。我会尝试使用SelectNodes而不是PowerShell的虚拟XML对象属性:

$entry = $nvdxml.SelectSingleNode('/nvd/entry[vuln:cve-id = "$vid"]')
# or
$entry = $nvdxml.SelectSingleNode('/nvd/entry[@id = "$vid"]')