ronin-masscan 0.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.document +4 -0
  3. data/.github/workflows/ruby.yml +47 -0
  4. data/.gitignore +14 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +11 -0
  7. data/.ruby-version +1 -0
  8. data/.yardopts +1 -0
  9. data/COPYING.txt +165 -0
  10. data/ChangeLog.md +10 -0
  11. data/Gemfile +40 -0
  12. data/README.md +204 -0
  13. data/Rakefile +43 -0
  14. data/bin/ronin-masscan +34 -0
  15. data/data/completions/ronin-masscan +83 -0
  16. data/data/templates/script.rb.erb +43 -0
  17. data/gemspec.yml +42 -0
  18. data/lib/ronin/masscan/cli/command.rb +40 -0
  19. data/lib/ronin/masscan/cli/commands/completion.rb +61 -0
  20. data/lib/ronin/masscan/cli/commands/convert.rb +133 -0
  21. data/lib/ronin/masscan/cli/commands/dump.rb +194 -0
  22. data/lib/ronin/masscan/cli/commands/grep.rb +235 -0
  23. data/lib/ronin/masscan/cli/commands/import.rb +94 -0
  24. data/lib/ronin/masscan/cli/commands/new.rb +203 -0
  25. data/lib/ronin/masscan/cli/commands/print.rb +162 -0
  26. data/lib/ronin/masscan/cli/commands/scan.rb +206 -0
  27. data/lib/ronin/masscan/cli/filtering_options.rb +312 -0
  28. data/lib/ronin/masscan/cli/importable.rb +68 -0
  29. data/lib/ronin/masscan/cli/port_list.rb +102 -0
  30. data/lib/ronin/masscan/cli.rb +50 -0
  31. data/lib/ronin/masscan/converter.rb +129 -0
  32. data/lib/ronin/masscan/converters/csv.rb +108 -0
  33. data/lib/ronin/masscan/converters/json.rb +142 -0
  34. data/lib/ronin/masscan/converters.rb +54 -0
  35. data/lib/ronin/masscan/exceptions.rb +47 -0
  36. data/lib/ronin/masscan/importer.rb +214 -0
  37. data/lib/ronin/masscan/root.rb +28 -0
  38. data/lib/ronin/masscan/version.rb +26 -0
  39. data/lib/ronin/masscan.rb +114 -0
  40. data/man/ronin-masscan-completion.1 +76 -0
  41. data/man/ronin-masscan-completion.1.md +78 -0
  42. data/man/ronin-masscan-convert.1 +37 -0
  43. data/man/ronin-masscan-convert.1.md +40 -0
  44. data/man/ronin-masscan-dump.1 +116 -0
  45. data/man/ronin-masscan-dump.1.md +94 -0
  46. data/man/ronin-masscan-grep.1 +56 -0
  47. data/man/ronin-masscan-grep.1.md +59 -0
  48. data/man/ronin-masscan-import.1 +52 -0
  49. data/man/ronin-masscan-import.1.md +57 -0
  50. data/man/ronin-masscan-new.1 +78 -0
  51. data/man/ronin-masscan-new.1.md +70 -0
  52. data/man/ronin-masscan-print.1 +53 -0
  53. data/man/ronin-masscan-print.1.md +56 -0
  54. data/man/ronin-masscan-scan.1 +86 -0
  55. data/man/ronin-masscan-scan.1.md +84 -0
  56. data/man/ronin-masscan.1 +61 -0
  57. data/man/ronin-masscan.1.md +58 -0
  58. data/ronin-masscan.gemspec +62 -0
  59. data/scripts/setup +161 -0
  60. metadata +168 -0
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-masscan - A Ruby library and CLI for working with masscan.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-masscan is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-masscan is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-masscan. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/masscan/version'
22
+ require 'ronin/core/cli/help/banner'
23
+
24
+ require 'command_kit/commands'
25
+ require 'command_kit/commands/auto_load'
26
+ require 'command_kit/options/version'
27
+
28
+ module Ronin
29
+ module Masscan
30
+ #
31
+ # The `ronin-masscan` command-line interface (CLI).
32
+ #
33
+ # @api private
34
+ #
35
+ class CLI
36
+
37
+ include CommandKit::Commands
38
+ include CommandKit::Commands::AutoLoad.new(
39
+ dir: "#{__dir__}/cli/commands",
40
+ namespace: "#{self}::Commands"
41
+ )
42
+ include CommandKit::Options::Version
43
+ include Core::CLI::Help::Banner
44
+
45
+ command_name 'ronin-masscan'
46
+ version Ronin::Masscan::VERSION
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-masscan - A Ruby library and CLI for working with masscan.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-masscan is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-masscan is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-masscan. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/masscan/converters'
22
+
23
+ require 'masscan/output_file'
24
+
25
+ module Ronin
26
+ module Masscan
27
+ #
28
+ # Handles converting masscan scan file into other formats.
29
+ #
30
+ # Supports the following formats:
31
+ #
32
+ # * JSON
33
+ # * CSV
34
+ #
35
+ # @api public
36
+ #
37
+ module Converter
38
+ # Mapping of file extension names to formats.
39
+ #
40
+ # @api private
41
+ FILE_FORMATS = {
42
+ '.json' => :json,
43
+ '.csv' => :csv
44
+ }
45
+
46
+ #
47
+ # Converts an masscan scan file into another format.
48
+ #
49
+ # @param [String] src
50
+ # The input masscan scan file path.
51
+ #
52
+ # @param [String] dest
53
+ # The output file path.
54
+ #
55
+ # @param [:binary, :list, :json, :ndjson, nil] input_format
56
+ # The explicit format of the input masscan scan file.
57
+ # If not specified the input format will be inferred from the file's
58
+ # extension.
59
+ #
60
+ # @param [:json, :csv] format
61
+ # The format to convert the masscan scan file into. If not specified
62
+ # it will be inferred from the output file's extension.
63
+ #
64
+ # @api public
65
+ #
66
+ def self.convert_file(src,dest, input_format: nil,
67
+ format: infer_format_for(dest))
68
+ scan_file = if input_format
69
+ ::Masscan::OutputFile.new(src, format: input_format)
70
+ else
71
+ ::Masscan::OutputFile.new(src)
72
+ end
73
+
74
+ converter = Converters[format]
75
+
76
+ File.open(dest,'w') do |output|
77
+ converter.convert(scan_file,output)
78
+ end
79
+ end
80
+
81
+ #
82
+ # Converts parsed masscan scan file into the desired format.
83
+ #
84
+ # @param [::Masscan::OutputFile] masscan_file
85
+ # The masscan scan file to convert.
86
+ #
87
+ # @param [IO, nil] output
88
+ # Optional output to write the converted output to.
89
+ #
90
+ # @param [:json, :csv] format
91
+ # The desired convert to convert the parsed masscan scan file to.
92
+ #
93
+ # @return [IO, String]
94
+ # The converted masscan scan file.
95
+ #
96
+ # @api public
97
+ #
98
+ def self.convert(masscan_file,output=nil, format: )
99
+ if output
100
+ Converters[format].convert(masscan_file,output)
101
+ else
102
+ output = StringIO.new
103
+ convert(masscan_file,output, format: format)
104
+ output.string
105
+ end
106
+ end
107
+
108
+ #
109
+ # Infers the output format from the output file's extension.
110
+ #
111
+ # @param [String] path
112
+ # The output file name.
113
+ #
114
+ # @return [:json, :csv]
115
+ # The conversion format.
116
+ #
117
+ # @raise [ArgumentError]
118
+ # The format could not be inferred from the path's file extension.
119
+ #
120
+ # @api private
121
+ #
122
+ def self.infer_format_for(path)
123
+ FILE_FORMATS.fetch(File.extname(path)) do
124
+ raise(ArgumentError,"cannot infer output format from path: #{path.inspect}")
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-masscan - A Ruby library and CLI for working with masscan.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-masscan is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-masscan is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-masscan. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'masscan/output_file'
22
+ require 'csv'
23
+
24
+ module Ronin
25
+ module Masscan
26
+ module Converters
27
+ #
28
+ # Handles converting masscan scan files into CSV.
29
+ #
30
+ # @api private
31
+ #
32
+ module CSV
33
+ #
34
+ # Converts the masscan scan file to CSV.
35
+ #
36
+ # @param [::Masscan::OutputFile] masscan_file
37
+ # The opened masscan scan file.
38
+ #
39
+ # @param [StringIO, IO] output
40
+ # Optional output stream to write the CSV to.
41
+ #
42
+ def self.convert(masscan_file,output)
43
+ masscan_file_to_csv(masscan_file,output)
44
+ end
45
+
46
+ #
47
+ # Converts a masscan scan file to CSV.
48
+ #
49
+ # @param [::Masscan::OutputFile] masscan_file
50
+ # The masscan scan file to convert to CSV.
51
+ #
52
+ # @param [StringIO, IO] output
53
+ # The optional output to write the CSV to.
54
+ #
55
+ #
56
+ def self.masscan_file_to_csv(masscan_file,output)
57
+ masscan_file_to_rows(masscan_file) do |row|
58
+ output << ::CSV.generate_line(row)
59
+ end
60
+
61
+ return output
62
+ end
63
+
64
+ # CSV rows header.
65
+ HEADER = %w[type status.status status.protocol status.port status.reason status.ttl status.ip status.timestamp banner.protocol banner.port banner.ip banner.timestamp banner.app_protocol banner.payload]
66
+
67
+ #
68
+ # Converts an opened masscan scan file to a series of rows.
69
+ #
70
+ # @param [::Masscan::OutputFile] masscan_file
71
+ # The opened masscan scan file.
72
+ #
73
+ # @yield [row]
74
+ # The given block will be passed each row.
75
+ #
76
+ # @yieldparam [Array] row
77
+ # A row to be converted to CSV.
78
+ #
79
+ def self.masscan_file_to_rows(masscan_file)
80
+ yield HEADER
81
+
82
+ masscan_file.each do |record|
83
+ yield record_to_row(record)
84
+ end
85
+ end
86
+
87
+ def self.record_to_row(record)
88
+ case record
89
+ when ::Masscan::Status
90
+ status_record_to_row(record)
91
+ when ::Masscan::Banner
92
+ banner_record_to_row(record)
93
+ else
94
+ raise(NotImplementedError,"unable to convert masscan record: #{record.inspect}")
95
+ end
96
+ end
97
+
98
+ def self.status_record_to_row(status)
99
+ ['status', status.status, status.protocol, status.port, status.reason.join(','), status.ttl, status.ip, status.timestamp]
100
+ end
101
+
102
+ def self.banner_record_to_row(banner)
103
+ ['banner', nil, nil, nil, nil, nil, nil, nil, banner.protocol, banner.port, banner.ip, banner.timestamp, banner.app_protocol, banner.payload]
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-masscan - A Ruby library and CLI for working with masscan.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-masscan is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-masscan is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-masscan. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'masscan/output_file'
22
+ require 'json'
23
+
24
+ module Ronin
25
+ module Masscan
26
+ module Converters
27
+ #
28
+ # Handles converting masscan scan files into JSON.
29
+ #
30
+ # @api private
31
+ #
32
+ module JSON
33
+ #
34
+ # Converts the masscan scan file to JSON.
35
+ #
36
+ # @param [::Masscan::OutputFile] masscan_file
37
+ # The opened masscan scan file.
38
+ #
39
+ # @param [IO, StringIO] output
40
+ # Optional output stream to write the JSON to.
41
+ #
42
+ def self.convert(masscan_file,output)
43
+ masscan_file_to_json(masscan_file,output)
44
+ end
45
+
46
+ #
47
+ # Converts the masscan scan file to JSON.
48
+ #
49
+ # @param [::Masscan::OutputFile] masscan_file
50
+ # The opened masscan scan file.
51
+ #
52
+ # @param [IO, StringIO] output
53
+ # Optional output stream to write the JSON to.
54
+ #
55
+ def self.masscan_file_to_json(masscan_file,output)
56
+ ::JSON.dump(masscan_file_as_json(masscan_file),output)
57
+ end
58
+
59
+ #
60
+ # Converts a masscan scan file into JSON representation.
61
+ #
62
+ # @param [::Masscan::OutputFile] output_file
63
+ # The opened masscan file.
64
+ #
65
+ # @return [Array<Hash{Symbol => Object}>]
66
+ # The JSON representation of the masscan scan file.
67
+ #
68
+ def self.masscan_file_as_json(output_file)
69
+ output_file.each.map do |record|
70
+ record_as_json(record)
71
+ end
72
+ end
73
+
74
+ #
75
+ # Converts a masscan record into a JSON representation.
76
+ #
77
+ # @param [::Masscan::Status, ::Masscan::Banner] record
78
+ # The masscan status or banner record to convert.
79
+ #
80
+ # @return [Hash{Symbol => Object}]
81
+ # The JSON representation of the record.
82
+ #
83
+ def self.record_as_json(record)
84
+ case record
85
+ when ::Masscan::Status
86
+ status_as_json(record)
87
+ when ::Masscan::Banner
88
+ banner_as_json(record)
89
+ else
90
+ raise(NotImplementedError,"unable to convert masscan record: #{record.inspect}")
91
+ end
92
+ end
93
+
94
+ #
95
+ # Converts a masscan status record into a JSON representation.
96
+ #
97
+ # @param [::Masscan::Status] status
98
+ # The masscan status record to convert.
99
+ #
100
+ # @return [Hash{Symbol => Object}]
101
+ # The JSON representation of the record.
102
+ #
103
+ def self.status_as_json(status)
104
+ hash = {
105
+ status: status.status,
106
+ protocol: status.protocol,
107
+ port: status.port,
108
+ reason: status.reason,
109
+ ttl: status.ttl,
110
+ ip: status.ip,
111
+ timestamp: status.timestamp
112
+ }
113
+
114
+ # omit the `mac` field if it's nil
115
+ hash[:mac] = status.mac if status.mac
116
+
117
+ return hash
118
+ end
119
+
120
+ #
121
+ # Converts a masscan record into a JSON representation.
122
+ #
123
+ # @param [::Masscan::Banner] banner
124
+ # The masscan banner record to convert.
125
+ #
126
+ # @return [Hash{Symbol => Object}]
127
+ # The JSON representation of the record.
128
+ #
129
+ def self.banner_as_json(banner)
130
+ {
131
+ protocol: banner.protocol,
132
+ port: banner.port,
133
+ ip: banner.ip,
134
+ timestamp: banner.timestamp,
135
+ app_protocol: banner.app_protocol,
136
+ payload: banner.payload
137
+ }
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-masscan - A Ruby library and CLI for working with masscan.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-masscan is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-masscan is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-masscan. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/masscan/converters/json'
22
+ require 'ronin/masscan/converters/csv'
23
+
24
+ module Ronin
25
+ module Masscan
26
+ #
27
+ # @api private
28
+ #
29
+ module Converters
30
+ # Mapping of formats to converter modules.
31
+ FORMATS = {
32
+ json: JSON,
33
+ csv: CSV
34
+ }
35
+
36
+ #
37
+ # Fetches the converter for the given format.
38
+ #
39
+ # @param [:json, :csv] format
40
+ #
41
+ # @return [Converters::JSON, Converters::CSV]
42
+ # The converter module.
43
+ #
44
+ # @raise [ArgumentError]
45
+ # The given format is unsupported.
46
+ #
47
+ def self.[](format)
48
+ FORMATS.fetch(format) do
49
+ raise(ArgumentError,"unsupported format: #{format.inspect}")
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-masscan - A Ruby library and CLI for working with masscan.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-masscan is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-masscan is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-masscan. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ module Ronin
22
+ module Masscan
23
+ #
24
+ # Base class for all {Ronin::Masscan} exceptions.
25
+ #
26
+ # @api public
27
+ #
28
+ class Exception < RuntimeError
29
+ end
30
+
31
+ #
32
+ # Indicates that the `masscan` command is not installed.
33
+ #
34
+ # @api public
35
+ #
36
+ class NotInstalled < Exception
37
+ end
38
+
39
+ #
40
+ # Indicates that the `masscan` scan failed.
41
+ #
42
+ # @api public
43
+ #
44
+ class ScanFailed < Exception
45
+ end
46
+ end
47
+ end