Module: Ronin::Masscan::Importer

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

Overview

Handles importing masscan output files file into ronin-db.

Examples

require 'ronin/masscan/importer'

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

Class Method Summary collapse

Class Method Details

.import(output_file) {|imported| ... } ⇒ Object

Imports the masscan output file.

Parameters:

  • output_file (::Masscan::OutputFile)

Yields:

  • (imported)

    The given block will be passed each imported database record.

Yield Parameters:

  • imported (Ronin::DB::IPAddress, Ronin::DB::Port, Ronin::DB::OpenPort)


78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/ronin/masscan/importer.rb', line 78

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

  output_file.each do |record|
    case record
    when ::Masscan::Status
      import_status(record,&block)
    when ::Masscan::Banner
      # TODO: somehow import the banner data
    else
      raise(NotImplementedError,"unable to import masscan record: #{record.inspect}")
    end
  end
end

.import_file(path, **kwargs) {|imported| ... } ⇒ Object

Imports a masscan output file into the database.

Parameters:

  • path (String)

    The path to the masscan output file.

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments for Masscan::OutputFile#initialize.

Options Hash (**kwargs):

  • :format (:binary, :list, :json, :ndjson)

    The format of the output file. If not given, the format will be inferred from the file extension.

Yields:

  • (imported)

    The given block will be passed each imported database record.

Yield Parameters:

  • imported (Ronin::DB::IPAddress, Ronin::DB::Port, Ronin::DB::OpenPort)

Raises:

  • (ArgumentError)

    The output format was not given and it cannot be inferred.



62
63
64
65
66
# File 'lib/ronin/masscan/importer.rb', line 62

def self.import_file(path,**kwargs,&block)
  output_file = ::Masscan::OutputFile.new(path,**kwargs)

  import(output_file,&block)
end

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

Imports an IP address into the database.

Parameters:

  • ip_addr (IPAddr)

    The IP address object to import.

Yields:

  • (imported)

    The given block will be passed the imported IP address record.

Yield Parameters:

  • imported (Ronin::DB::IPAddress)

    The imported IP address record.

Returns:

  • (Ronin::DB::IPAddress)

    The imported IP address record.



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/ronin/masscan/importer.rb', line 167

def self.import_ip_address(ip_addr,&block)
  ip_version = if ip_addr.ipv6? then 6
               else                  4
               end

  imported_ip_address = DB::IPAddress.transaction do
                          DB::IPAddress.find_or_create_by(
                            version: ip_version,
                            address: ip_addr.to_s
                          )
                        end

  yield imported_ip_address if block_given?
  return imported_ip_address
end

.import_open_port_status(status) {|imported| ... } ⇒ Ronin::DB::OpenPort

Imports an open port Masscan::Status record into the database.

Parameters:

  • status (::Masscan::Status)

    The Masscan::Status record.

Yields:

  • (imported)

    The given block will be passed each imported database record.

Yield Parameters:

  • imported (Ronin::DB::IPAddress, Ronin::DB::Port, Ronin::DB::OpenPort)

    An imported IP address, port number, or open port record.

Returns:

  • (Ronin::DB::OpenPort)

    The imported open port.



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/ronin/masscan/importer.rb', line 136

def self.import_open_port_status(status,&block)
  imported_ip_address = import_ip_address(status.ip,&block)
  imported_port       = import_port(status.port,status.protocol,&block)
  imported_open_port  = DB::OpenPort.transaction do
                          DB::OpenPort.find_or_create_by(
                            ip_address: imported_ip_address,
                            port:       imported_port
                          )
                        end

  imported_open_port.update(last_scanned_at: status.timestamp)

  yield imported_open_port if block_given?
  return imported_open_port
end

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

Imports the port.

Parameters:

  • port (Integer)

    The port number to import.

  • protocol (:tcp, :udp)

    The protocol of the port.

Yields:

  • (imported)

    The given block will be passed the imported port record.

Yield Parameters:

  • imported (Ronin::DB::Port)

    The imported port record.

Returns:

  • (Ronin::DB::Port)

    The imported port record.



201
202
203
204
205
206
207
208
209
210
211
# File 'lib/ronin/masscan/importer.rb', line 201

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

  yield imported_port if block_given?
  return imported_port
end

.import_status(status) {|imported| ... } ⇒ Ronin::DB::OpenPort, ...

Imports a Masscan::Status record into the database.

Parameters:

  • status (::Masscan::Status)

    The Masscan::Status record.

Yields:

  • (imported)

    The given block will be passed each imported database record.

Yield Parameters:

  • imported (Ronin::DB::IPAddress, Ronin::DB::Port, Ronin::DB::OpenPort)

    An imported IP address, port number, or open port record.

Returns:

  • (Ronin::DB::OpenPort, Ronin::DB::IPAddress, nil)

    The imported open port, or an IP address if the status was an ICMP probe, or nil if the status did not represent an open port.



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/ronin/masscan/importer.rb', line 109

def self.import_status(status,&block)
  # only import open ports
  if status.status == :open
    if status.protocol == :icmp
      # only import the IP address for ICMP statuses
      import_ip_address(status.ip,&block)
    else
      import_open_port_status(status,&block)
    end
  end
end