Module: Ronin::Nmap::Importer

Defined in:
lib/ronin/nmap/importer.rb

Overview

Handles importing a parsed nmap XML file into ronin-db.

Examples

require 'ronin/nmap/importer'

Ronin::DB.connect
Ronin::Nmap::Importer.import_file('scan.xml') do |record|
  puts "Imported #{record.inspect}!"
end

Constant Summary collapse

IP_VERSIONS =

Mapping of nmap XML IP address types to IP versions.

{
  ipv4: 4,
  ipv6: 6
}

Class Method Summary collapse

Class Method Details

.import(xml) {|imported| ... } ⇒ Array<Ronin::DB::IPAddress>

Imports the parsed nmap XML into the database.

An imported IP address, MAC address, host name, or open port.

Parameters:

  • xml (::Nmap::XML)

    The parsed nmap XML document.

Yields:

  • (imported)

    If a block is given, it will be passed the imported database records.

Yield Parameters:

  • imported (Ronin::DB::IPAddress, Ronin::DB::MACAddress, Ronin::DB::HostName, Ronin::DB::Port, Ronin::DB::Service, Ronin::DB::OpenPort)

Returns:

  • (Array<Ronin::DB::IPAddress>)

    If no block was given, then an Array of imported IP addresses will be returned.



87
88
89
90
91
92
93
# File 'lib/ronin/nmap/importer.rb', line 87

def self.import(xml,&block)
  return enum_for(__method__,xml).to_a unless block

  xml.each_up_host do |host|
    import_host(host,&block)
  end
end

.import_address(address) {|imported| ... } ⇒ Ronin::DB::IPAddress, Ronin::DB::MACAddress

Imports and IP address or a MAC address into the database.

Parameters:

  • address (::Nmap::XML::Address)

    The nmap XML address object.

Yields:

  • (imported)

    If a block is given, it will be passed the imported address.

Yield Parameters:

  • imported (Ronin::DB::IPAddress, Ronin::DB::MACAddress)

    The imported IP address or MAC address record.

Returns:

  • (Ronin::DB::IPAddress, Ronin::DB::MACAddress)

    The imported IP address or MAC address.



264
265
266
267
268
269
# File 'lib/ronin/nmap/importer.rb', line 264

def self.import_address(address,&block)
  case address.type
  when :ipv4, :ipv6 then import_ip_address(address,&block)
  when :mac         then import_mac_address(address,&block)
  end
end

.import_addresses(host) {|imported| ... } ⇒ (Array<Ronin::DB::IPAddress>, Array<Ronin::DB::MACAddress>)

Imports the addresses for a host.

Parameters:

  • host (::Nmap::XML::Host)

Yields:

  • (imported)

    If a block is given, it will be passed the imported database records.

Yield Parameters:

  • imported (Ronin::DB::IPAddress, Ronin::DB::MACAddress)

    An imported IP address or MAC address.

Returns:

  • ((Array<Ronin::DB::IPAddress>, Array<Ronin::DB::MACAddress>))

    The imported IP addresses and MAC addresses.



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/ronin/nmap/importer.rb', line 221

def self.import_addresses(host,&block)
  imported_ip_addresses  = []
  imported_mac_addresses = []

  host.each_address do |address|
    case (imported_address = import_address(address,&block))
    when DB::IPAddress
      imported_ip_addresses << imported_address
    when DB::MACAddress
      imported_mac_addresses << imported_address
    end
  end

  # associate any imported MAC addresses with the imported IP addresses
  imported_mac_addresses.each do |imported_mac_address|
    imported_ip_addresses.each do |imported_ip_address|
      DB::IPAddressMACAddress.transaction do
        DB::IPAddressMACAddress.find_or_create_by(
          mac_address: imported_mac_address,
          ip_address:  imported_ip_address
        )
      end
    end
  end

  return imported_ip_addresses, imported_mac_addresses
end

.import_file(path) {|imported| ... } ⇒ Array<Ronin::DB::IPAddress>

Parses the nmap XML file and imports it's contents into the database.

An imported IP address, MAC address, host name, or open port.

Parameters:

  • path (String)

    The path to the nmap XML file to parse and import.

Yields:

  • (imported)

    If a block is given, it will be passed the imported database records.

Yield Parameters:

  • imported (Ronin::DB::IPAddress, Ronin::DB::MACAddress, Ronin::DB::HostName, Ronin::DB::Port, Ronin::DB::Service, Ronin::DB::OpenPort)

Returns:

  • (Array<Ronin::DB::IPAddress>)

    If no block was given, then an Array of imported IP addresses will be returned.



62
63
64
# File 'lib/ronin/nmap/importer.rb', line 62

def self.import_file(path,&block)
  import(::Nmap::XML.open(path),&block)
end

.import_host(host) {|imported| ... } ⇒ Array<Ronin::DB::IPAddress>

Imports an nmap host into the database.

An imported IP address, MAC address, host name, or open port.

Parameters:

  • host (::Nmap::XML::Host)

Yields:

  • (imported)

    If a block is given, it will be passed the imported database records.

Yield Parameters:

  • imported (Ronin::DB::IPAddress, Ronin::DB::MACAddress, Ronin::DB::HostName, Ronin::DB::Port, Ronin::DB::Service, Ronin::DB::OpenPort)

Returns:

  • (Array<Ronin::DB::IPAddress>)


113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/ronin/nmap/importer.rb', line 113

def self.import_host(host,&block)
  imported_ip_addresses, = import_addresses(host,&block)
  imported_hostnames     = import_hostnames(host,&block)

  # associate any imported host names with the imported IP addresses
  imported_hostnames.each do |imported_hostname|
    imported_ip_addresses.each do |imported_ip_address|
      DB::HostNameIPAddress.transaction do
        DB::HostNameIPAddress.find_or_create_by(
          host_name:  imported_hostname,
          ip_address: imported_ip_address
        )
      end
    end
  end

  host.each_open_port do |port|
    imported_port, imported_service = import_port(port,&block)

    # associate the imported port with the imported IP addresses
    imported_ip_addresses.each do |imported_ip_address|
      import_open_port(imported_ip_address,
                       imported_port,
                       imported_service,
                       &block)
    end
  end

  return imported_ip_addresses
end

.import_hostname(hostname) ⇒ Ronin::DB::HostName

Imports a hostname into the database.

Parameters:

  • hostname (::Nmap::XML::HostName)

    The nmap XML hostname object to import.

Returns:

  • (Ronin::DB::HostName)

    The imported host name.



201
202
203
204
205
# File 'lib/ronin/nmap/importer.rb', line 201

def self.import_hostname(hostname)
  DB::HostName.transaction do
    DB::HostName.find_or_import(hostname.name)
  end
end

.import_hostnames(host) {|imported| ... } ⇒ Array<Ronin::DB::HostName>

Imports the host names for the scanned nmap host.

Parameters:

  • host (::Nmap::XML::Host)

Yields:

  • (imported)

    If a block is given, it will be passed the imported database records.

Yield Parameters:

  • imported (Ronin::DB::HostName)

    An imported host name.

Returns:

  • (Array<Ronin::DB::HostName>)


184
185
186
187
188
189
190
# File 'lib/ronin/nmap/importer.rb', line 184

def self.import_hostnames(host)
  host.each_hostname.map do |hostname|
    imported_host_name = import_hostname(hostname)
    yield imported_host_name if block_given?
    imported_host_name
  end
end

.import_ip_address(address) {|imported| ... } ⇒ Ronin::DB::IPAddress

Imports an IP address into the database.

Parameters:

  • address (::Nmap::XML::Address)

    The nmap XML IP address object.

Yields:

  • (imported)

    If a block is given, it will be passed the imported IP address.

Yield Parameters:

  • imported (Ronin::DB::IPAddress)

    The imported IP address record.

Returns:

  • (Ronin::DB::IPAddress)

    The imported IP address.



292
293
294
295
296
297
298
299
300
301
302
# File 'lib/ronin/nmap/importer.rb', line 292

def self.import_ip_address(address,&block)
  imported_ip_address = DB::IPAddress.transaction do
                          DB::IPAddress.find_or_create_by(
                            version: IP_VERSIONS.fetch(address.type),
                            address: address.addr
                          )
                        end

  yield imported_ip_address if block_given?
  return imported_ip_address
end

.import_mac_address(address) {|imported| ... } ⇒ Ronin::DB::MACAddress

Imports an MAC address into the database.

Parameters:

  • address (::Nmap::XML::Address)

    The nmap XML MAC address object.

Yields:

  • (imported)

    If a block is given, it will be passed the imported MAC address reocrd.

Yield Parameters:

  • imported (Ronin::DB::MACAddress)

    The imported MAC address record.

Returns:

  • (Ronin::DB::MACAddress)

    The imported MAC address.



320
321
322
323
324
325
326
327
# File 'lib/ronin/nmap/importer.rb', line 320

def self.import_mac_address(address,&block)
  imported_mac_address = DB::MACAddress.transaction do
                           DB::MACAddress.find_or_import(address.addr)
                         end

  yield imported_mac_address if block_given?
  return imported_mac_address
end

.import_open_port(imported_ip_address, imported_port, imported_service) {|imported_open_port| ... } ⇒ Ronin::DB::OpenPort

Creates or updates an open port association between the imported IP address, imported port, and imported service.

Parameters:

  • imported_ip_address (Ronin::DB::IPAddress)
  • imported_port (Ronin::DB::Port)
  • imported_service (Ronin::DB::Service)

Yields:

  • (imported_open_port)

Returns:

  • (Ronin::DB::OpenPort)


156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/ronin/nmap/importer.rb', line 156

def self.import_open_port(imported_ip_address,
                          imported_port,
                          imported_service)
  imported_open_port = DB::OpenPort.transaction do
                         DB::OpenPort.find_or_create_by(
                           ip_address: imported_ip_address,
                           port:       imported_port,
                           service:    imported_service
                         )
                       end

  yield imported_open_port if block_given?
  return imported_open_port
end

.import_port(port) {|imported| ... } ⇒ Ronin::DB::Port, (Ronin::DB::Port, Ronin::DB::Service)

Import an nmap port.

Parameters:

  • port (::Nmap::XML::Port)

    The nmap port.

Yields:

  • (imported)

    If a block is given, it will be passed the imported database records.

Yield Parameters:

  • imported (Ronin::DB::Port, Ronin::DB::Service)

    An imported port or service.

Returns:

  • (Ronin::DB::Port, (Ronin::DB::Port, Ronin::DB::Service))

    The imported port and optionally the imported service.



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/ronin/nmap/importer.rb', line 344

def self.import_port(port)
  imported_port = DB::Port.transaction do
                    DB::Port.find_or_create_by(
                      protocol: port.protocol,
                      number:   port.number
                    )
                  end

  imported_service = if (service = port.service)
                       DB::Service.transaction do
                         DB::Service.find_or_create_by(
                           name: service.name
                         )
                       end
                     end

  if block_given?
    yield imported_port
    yield imported_service if imported_service
  end

  return imported_port, imported_service
end