Module: ScanDB::Nmap

Includes:
LibXML
Defined in:
lib/scandb/nmap.rb

Class Method Summary collapse

Class Method Details

.import_xml(path, &block) ⇒ Object

Imports scan information from a Nmap XML scan file, specified by the path. Returns an Array of Host objects. If a block is given it will be passed the newly created Host object.

Nmap.import_xml('path/to/scan.xml')
# => [...]


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/scandb/nmap.rb', line 41

def Nmap.import_xml(path,&block)
  doc = XML::Document.file(path)
  host_count = 0

  doc.find("/nmaprun/host[status[@state='up']]").each do |host|
    ip = host.find_first("address[@addr and @addrtype='ipv4']")['addr']
    new_host = Host.first_or_create(:ip => ip)

    host.find('hostnames/hostname').each do |hostname|
      new_host.names << HostName.first_or_create(
        :name => hostname['name']
      )
    end

    host.find('os/osclass').each do |osclass|
      new_os_class = OSClass.first_or_create(
        :type => osclass['type'],
        :vendor => osclass['vendor'],
        :family => osclass['osfamily'],
        :version => osclass['osgen']
      )

      new_host.os_class_guesses.first_or_create(
        :accuracy => osclass['accuracy'].to_i,
        :os_class_id => new_os_class.id,
        :host_id => new_host.id
      )
    end

    host.find('os/osmatch').each do |osmatch|
      new_os_match = OSMatch.first_or_create(
        :name => osmatch['name']
      )

      new_host.os_match_guesses.first_or_create(
        :accuracy => osmatch['accuracy'].to_i,
        :os_match_id => new_os_match.id,
        :host_id => new_host.id
      )
    end

    host.find('ports/port').each do |port|
      new_port = Port.first_or_create(
        :number => port['portid'].to_i,
        :protocol => port['protocol'].to_sym
      )

      new_service = Service.first_or_create(
        :name => port.find_first('service[@name]')['name']
      )

      new_host.scanned_ports.first_or_create(
        :status => port.find_first('state[@state]')['state'].to_sym,
        :service_id => new_service.id,
        :port_id => new_port.id,
        :host_id => new_host.id
      )
    end

    new_host.save
    host_count += 1

    block.call(new_host) if block
  end

  return host_count
end