1

Nexpose Simple XML 結果のエクスポートを取得して解析し、必要な結果を簡単に確認できるようにきれいな形式に書き出す Ruby スクリプトを作成しようとしています。Nokogiri を使用して XML を解析しています。私の問題は、デバイスごとに、各サービスセクションを反復処理し、それぞれから名前、ポート、およびプロトコル属性を引き出すネストされたループがあることです。これは最終的に、テキスト ファイルまたは csv のいずれかのファイルに出力されます。ただし、ネストされたループは、最初のサービス セクションからこれら 3 つの属性のみを取得し、それらを繰り返し出力するようです。

サンプル入力 (これらのデバイス ブロックは複数あります):

<device address="10.x.x.1" id="20xx">
<fingerprint certainty="0.85">
<description>Microsoft Windows</description>
<vendor>Microsoft</vendor>
<family>Windows</family>
<product>Windows</product>
<version/>
<device-class>General</device-class>
<architecture/>
</fingerprint>
<vulnerabilities>
</vulnerabilities>
<services>
<service name="NTP" port="123" protocol="udp">
<vulnerabilities>
</vulnerabilities>
</service>
<service name="HTTP" port="8080" protocol="tcp">
<fingerprint certainty="0.75">
<description>Apache</description>
</device>

<device address="10.x.x.2" id="20xx">
<fingerprint certainty="0.85">
<description>Microsoft Windows</description>
<vendor>Microsoft</vendor>
<family>Windows</family>
<product>Windows</product>
<version/>
<device-class>General</device-class>
<architecture/>
</fingerprint>
<vulnerabilities>
</vulnerabilities>
<services>
<service name="DNS" port="53" protocol="udp">
<vulnerabilities>
</vulnerabilities>
</service>
<service name="HTTP" port="80" protocol="tcp">
<fingerprint certainty="0.75">
<description>Apache</description>
</device>

ルビーコード:

#! /usr/bin/env ruby

require 'rubygems'
require 'nokogiri'

doc = Nokogiri::XML(open('report.xml').read)
device = doc.xpath('//device')

device.each do |d|
 service = d.xpath('//service')
 puts d.attr('address')

 service.each do |s|
   name = s.attr('name')
   port = s.attr('port')
   protocol = s.attr('protocol')

   puts port
   puts protocol
   puts name
 end
end

望ましい出力:

10.x.x.1
123
udp
NTP
8080
tcp
HTTP

10.x.x.2
53
udp
DNS
80
tcp
HTTP

実際の出力:

123
NTP
udp
123
NTP
udp

したがって、コードは、各デバイスの各サービスのサービス ポート、名前、およびプロトコルのリストを表示する必要があります。ただし、現在のコードは、最初のサービス (123、NTP、および udp) のセットを何度も何度も出力しているようです。

ループのロジックに何か不足していますか? または、ループに何か問題がありますか? これを機能させるための助けは役に立ちます。ありがとう。

4

1 に答える 1

0

XPath コンストラクトは、ドキュメント内の任意の場所//で要素を見つけることを意味することに注意してください。デバイスに対して既にそれを行っているため、内側のループでそれを行いたくありません。

アップデート

新しい入力ドキュメントに基づいて、必要な情報を抽出する 1 つの方法を次に示します。私は、CSV を自由に使用して、Excel 対応の優れた出力ファイルを作成しました。単一の解析ループがあることに注意してください。コード:

require 'nokogiri'
require 'csv'

doc = Nokogiri::XML(open('report.xml').read)

CSV.open("devices.csv", "wb") do |csv|
  csv << ["Device", "Service", "Port", "Protocol"]
  doc.search('//service').each do |s|
    device = s.xpath('ancestor::device[1]/@address')
    name = s.attr('name')
    port = s.attr('port')
    protocol = s.attr('protocol')
    csv << [device, name, port, protocol]
  end
end

の内容は次のdevices.csvとおりです。

Device,Service,Port,Protocol
10.x.x.1,NTP,123,udp
10.x.x.1,HTTP,8080,tcp
10.x.x.2,DNS,53,udp
10.x.x.2,HTTP,80,tcp
于 2012-10-18T13:27:22.013 に答える