【问题标题】:String comparison from XML failing来自 XML 的字符串比较失败
【发布时间】:2012-09-04 08:50:00
【问题描述】:

我目前正在使用 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,结果相同。

【问题讨论】:

  • 要么使用 ISE 调试并确定 $cveID 的值在该行之前是什么,要么只是将 $cveID 放在 $nvdxml.nvd.entry 上方的脚本中。 ? ...在我看来,$cveID 没有您期望的价值。
  • 我正在使用 ISE 进行调试,并已验证 $cveID 具有正确的值。我什至尝试在即时窗口中设置 $cveID,然后正常执行针对 XML 的查询,但仍然失败。
  • 如果没有 CSV 文件,很难判断发生了什么,所以我在这里推测一下。看起来您正在比较 CSV 文件的两个属性(即 $_."cve-id"$vid)。您不想比较 CSV 中的一个和 XML 中的另一个吗?此外,根据名称,$vid 可能是一个数组 ($vid = $_."Vulnerability CVE IDs")。如果这是真的,那么看起来您正在尝试将一个值与一个数组进行比较(即$_."cve-id" -eq $vid)。
  • 我确实想比较 XML 和 CSV 文件中的数据。当我使用$nvdxml.nvd.entry | where { $_."cve-id" -eq $cveID } 时,$_."cve-id" 指的是来自$nvdxml.nvd.entry 的管道输出的结果。关于 $vid 是一个数组,我不明白这是怎么可能的。当我在$vid$_."Vulnerability CVE IDs"上使用.gettype()时,它返回一个String类型。

标签: powershell powershell-2.0


【解决方案1】:

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

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

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

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

$entry = $entriesByID[$vid]

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-05
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多