Module: Masscan::Parsers::JSON

Extended by:
PlainText
Defined in:
lib/masscan/parsers/json.rb

Overview

Parses the masscan -oJ and masscan --output-format ndjson output formats.

Constant Summary

Constants included from PlainText

PlainText::APP_PROTOCOLS, PlainText::IP_PROTOCOLS, PlainText::REASONS, PlainText::STATUSES

Class Method Summary collapse

Methods included from PlainText

parse_app_protocol, parse_ip, parse_ip_protocol, parse_reason, parse_status, parse_timestamp

Class Method Details

.open(path) {|file| ... } ⇒ File

Opens a JSON file for parsing.

Parameters:

  • path (String)

    The path to the file.

Yields:

  • (file)

    If a block is given, it will be passed the opened file. Once the block returns, the file will be closed.

Yield Parameters:

  • file (File)

    The opened file.

Returns:

  • (File)

    If no block was given, the opened file will be returned.



36
37
38
# File 'lib/masscan/parsers/json.rb', line 36

def self.open(path,&block)
  File.open(path,&block)
end

.parse(io) {|record| ... } ⇒ Enumerator

Parses the masscan JSON or ndjson data.

Parameters:

  • io (#each_line)

    The IO object to read from.

Yields:

  • (record)

    If a block is given, it will be passed each parsed record.

Yield Parameters:

Returns:

  • (Enumerator)

    If no block is given, it will return an Enumerator.



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
# File 'lib/masscan/parsers/json.rb', line 55

def self.parse(io)
  return enum_for(__method__,io) unless block_given?

  io.each_line do |line|
    line.chomp!

    if line == "," || line == "[" || line == "]"
      # skip
    else
      json = ::JSON.parse(line)

      ip        = parse_ip(json['ip'])
      timestamp = parse_timestamp(json['timestamp'])

      if (ports_json = json['ports'])
        if (port_json = ports_json.first)
          proto  = parse_ip_protocol(port_json['proto'])
          port   = port_json['port']

          if (service_json = port_json['service'])
            service_name   = parse_app_protocol(service_json['name'])
            service_banner = service_json['banner']

            yield Banner.new(
              protocol:     proto,
              port:         port,
              ip:           ip,
              timestamp:    timestamp,
              app_protocol: service_name,
              payload:      service_banner
            )
          else
            status = parse_status(port_json['status'])
            ttl    = port_json['ttl']
            reason = parse_reason(port_json['reason'])

            yield Status.new(
              status:    status,
              protocol:  proto,
              port:      port,
              reason:    reason,
              ttl:       ttl,
              ip:        ip,
              timestamp: timestamp
            )
          end
        end
      end
    end
  end
end