ronin-nmap 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 +15 -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 +42 -0
  12. data/README.md +238 -0
  13. data/Rakefile +43 -0
  14. data/bin/ronin-nmap +32 -0
  15. data/data/completions/ronin-nmap +79 -0
  16. data/data/templates/script.rb.erb +58 -0
  17. data/gemspec.yml +42 -0
  18. data/lib/ronin/nmap/cli/command.rb +40 -0
  19. data/lib/ronin/nmap/cli/commands/completion.rb +61 -0
  20. data/lib/ronin/nmap/cli/commands/convert.rb +108 -0
  21. data/lib/ronin/nmap/cli/commands/dump.rb +293 -0
  22. data/lib/ronin/nmap/cli/commands/grep.rb +378 -0
  23. data/lib/ronin/nmap/cli/commands/import.rb +79 -0
  24. data/lib/ronin/nmap/cli/commands/new.rb +226 -0
  25. data/lib/ronin/nmap/cli/commands/print.rb +133 -0
  26. data/lib/ronin/nmap/cli/commands/scan.rb +233 -0
  27. data/lib/ronin/nmap/cli/filtering_options.rb +355 -0
  28. data/lib/ronin/nmap/cli/importable.rb +68 -0
  29. data/lib/ronin/nmap/cli/port_list.rb +102 -0
  30. data/lib/ronin/nmap/cli.rb +50 -0
  31. data/lib/ronin/nmap/converter.rb +114 -0
  32. data/lib/ronin/nmap/converters/csv.rb +162 -0
  33. data/lib/ronin/nmap/converters/json.rb +562 -0
  34. data/lib/ronin/nmap/converters.rb +54 -0
  35. data/lib/ronin/nmap/exceptions.rb +47 -0
  36. data/lib/ronin/nmap/importer.rb +369 -0
  37. data/lib/ronin/nmap/root.rb +28 -0
  38. data/lib/ronin/nmap/version.rb +26 -0
  39. data/lib/ronin/nmap.rb +223 -0
  40. data/man/ronin-nmap-completion.1 +76 -0
  41. data/man/ronin-nmap-completion.1.md +78 -0
  42. data/man/ronin-nmap-convert.1 +33 -0
  43. data/man/ronin-nmap-convert.1.md +36 -0
  44. data/man/ronin-nmap-dump.1 +141 -0
  45. data/man/ronin-nmap-dump.1.md +119 -0
  46. data/man/ronin-nmap-grep.1 +33 -0
  47. data/man/ronin-nmap-grep.1.md +36 -0
  48. data/man/ronin-nmap-import.1 +52 -0
  49. data/man/ronin-nmap-import.1.md +57 -0
  50. data/man/ronin-nmap-new.1 +81 -0
  51. data/man/ronin-nmap-new.1.md +73 -0
  52. data/man/ronin-nmap-print.1 +61 -0
  53. data/man/ronin-nmap-print.1.md +63 -0
  54. data/man/ronin-nmap-scan.1 +86 -0
  55. data/man/ronin-nmap-scan.1.md +84 -0
  56. data/man/ronin-nmap.1 +58 -0
  57. data/man/ronin-nmap.1.md +57 -0
  58. data/ronin-nmap.gemspec +62 -0
  59. data/scripts/setup +161 -0
  60. metadata +168 -0
@@ -0,0 +1,79 @@
1
+ # ronin-nmap completion -*- shell-script -*-
2
+
3
+ # This bash completions script was generated by
4
+ # completely (https://github.com/dannyben/completely)
5
+ # Modifying it manually is not recommended
6
+
7
+ _ronin-nmap_completions_filter() {
8
+ local words="$1"
9
+ local cur=${COMP_WORDS[COMP_CWORD]}
10
+ local result=()
11
+
12
+ if [[ "${cur:0:1}" == "-" ]]; then
13
+ echo "$words"
14
+
15
+ else
16
+ for word in $words; do
17
+ [[ "${word:0:1}" != "-" ]] && result+=("$word")
18
+ done
19
+
20
+ echo "${result[*]}"
21
+
22
+ fi
23
+ }
24
+
25
+ _ronin-nmap_completions() {
26
+ local cur=${COMP_WORDS[COMP_CWORD]}
27
+ local compwords=("${COMP_WORDS[@]:1:$COMP_CWORD-1}")
28
+ local compline="${compwords[*]}"
29
+
30
+ case "$compline" in
31
+ 'new'*'--xml-file')
32
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -A file -- "$cur" )
33
+ ;;
34
+
35
+ 'scan'*'--output')
36
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -A file -- "$cur" )
37
+ ;;
38
+
39
+ 'completion'*)
40
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_ronin-nmap_completions_filter "--print --install --uninstall")" -- "$cur" )
41
+ ;;
42
+
43
+ 'convert'*)
44
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -A file -W "$(_ronin-nmap_completions_filter "--format -F")" -- "$cur" )
45
+ ;;
46
+
47
+ 'scan'*'-o')
48
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -A file -- "$cur" )
49
+ ;;
50
+
51
+ 'import'*)
52
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -A file -W "$(_ronin-nmap_completions_filter "--db --db-uri --db-file")" -- "$cur" )
53
+ ;;
54
+
55
+ 'print'*)
56
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_ronin-nmap_completions_filter "--ip --ip-range --domain --with-os --with-ports --with-service --with-script --with-script-output --with-script-regex")" -- "$cur" )
57
+ ;;
58
+
59
+ 'dump'*)
60
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_ronin-nmap_completions_filter "--print-ips --print-hosts --print-ip-ports --print-host-ports --print-uris --ip --ip-range --domain --with-os --with-ports --with-service --with-script --with-script-output --with-script-regex --ports -p --services")" -- "$cur" )
61
+ ;;
62
+
63
+ 'scan'*)
64
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_ronin-nmap_completions_filter "--db --db-uri --db-file --sudo --output -o --output-format -F --import")" -- "$cur" )
65
+ ;;
66
+
67
+ 'new'*)
68
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_ronin-nmap_completions_filter "--parser --scanner --printing --import --xml-file --syn-scan --ports -p --target")" -- "$cur" )
69
+ ;;
70
+
71
+ *)
72
+ while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_ronin-nmap_completions_filter "--version -V help completion convert dump grep import new print scan")" -- "$cur" )
73
+ ;;
74
+
75
+ esac
76
+ } &&
77
+ complete -F _ronin-nmap_completions ronin-nmap
78
+
79
+ # ex: filetype=sh
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ronin/nmap'
4
+
5
+ <%- if @script_type == :parser -%>
6
+ <%- if @xml_file -%>
7
+ xml = Ronin::Nmap.parse(<%= @xml_file.inspect %>)
8
+ <%- else -%>
9
+ xml = Ronin::Nmap.parse(ARGV[0])
10
+ <%- end -%>
11
+ <%- else -%>
12
+ xml = Ronin::Nmap.scan do |nmap|
13
+ <%- if @xml_file -%>
14
+ nmap.xml_file = <%= @xml_file.inspect %>
15
+ <%- else -%>
16
+ # nmap.xml_file = "path/to/nmap.xml"
17
+ <%- end -%>
18
+ <%- if @syn_scan -%>
19
+ nmap.syn_scan = true
20
+ <%- else -%>
21
+ # nmap.syn_scan = true
22
+ <%- end -%>
23
+ <%- if @ports -%>
24
+ nmap.ports = <%= @ports.inspect %>
25
+ <%- else -%>
26
+ # nmap.ports = [22, 80, 443, 8000..9000]
27
+ <%- end -%>
28
+ <%- case @targets.length -%>
29
+ <%- when 0 -%>
30
+ nmap.targets = ARGV[0]
31
+ <%- when 1 -%>
32
+ nmap.targets = <%= @targets[0].inspect %>
33
+ <%- else -%>
34
+ nmap.targets = <%= @targets.inspect %>
35
+ <%- end -%>
36
+ end
37
+ <%- end -%>
38
+ <% if @features[:printing] -%>
39
+
40
+ xml.each_host do |host|
41
+ puts "[ #{host.ip} ]"
42
+
43
+ host.each_port do |port|
44
+ puts " #{port.number}/#{port.protocol}\t#{port.state}\t#{port.service}"
45
+
46
+ port.scripts.each do |id,script|
47
+ puts " [ #{id} ]"
48
+
49
+ script.output.each_line { |line| puts " #{line}" }
50
+ end
51
+ end
52
+ end
53
+ <%- end -%>
54
+ <%- if @features[:import] -%>
55
+
56
+ Ronin::DB.connect
57
+ Ronin::Nmap::Importer.import(xml)
58
+ <%- end -%>
data/gemspec.yml ADDED
@@ -0,0 +1,42 @@
1
+ name: ronin-nmap
2
+ summary: A Ruby library and CLI for working with nmap.
3
+ description: |
4
+ ronin-nmap is a Ruby library for working with nmap. ronin-nmap can parse
5
+ nmap XML, convert nmap XML into JSON or CSV, or import nmap XML into the
6
+ ronin-db database.
7
+
8
+ license: LGPL-3.0
9
+ authors: Postmodern
10
+ email: postmodern.mod3@gmail.com
11
+ homepage: https://ronin-rb.dev/
12
+ has_yard: true
13
+
14
+ metadata:
15
+ documentation_uri: https://ronin-rb.dev/docs/ronin-nmap
16
+ source_code_uri: https://github.com/ronin-rb/ronin-nmap
17
+ bug_tracker_uri: https://github.com/ronin-rb/ronin-nmap/issues
18
+ changelog_uri: https://github.com/ronin-rb/ronin-nmap/blob/main/ChangeLog.md
19
+ rubygems_mfa_required: 'true'
20
+
21
+ generated_files:
22
+ - data/completions/ronin-nmap
23
+ - man/ronin-nmap.1
24
+ - man/ronin-nmap-completion.1
25
+ - man/ronin-nmap-convert.1
26
+ - man/ronin-nmap-dump.1
27
+ - man/ronin-nmap-grep.1
28
+ - man/ronin-nmap-import.1
29
+ - man/ronin-nmap-new.1
30
+ - man/ronin-nmap-print.1
31
+ - man/ronin-nmap-scan.1
32
+
33
+ required_ruby_version: ">= 3.0.0"
34
+
35
+ dependencies:
36
+ ruby-nmap: ~> 1.0
37
+ # Ronin dependencies:
38
+ ronin-core: ~> 0.2.0.rc1
39
+ ronin-db: ~> 0.2.0.rc1
40
+
41
+ development_dependencies:
42
+ bundler: ~> 2.0
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-nmap - A Ruby library for automating nmap and importing nmap scans.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-nmap 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-nmap 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-nmap. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/nmap/root'
22
+
23
+ require 'ronin/core/cli/command'
24
+
25
+ module Ronin
26
+ module Nmap
27
+ class CLI
28
+ #
29
+ # Base class for all other `ronin-nmap` commands.
30
+ #
31
+ class Command < Core::CLI::Command
32
+
33
+ man_dir File.join(ROOT,'man')
34
+
35
+ bug_report_url 'https://github.com/ronin-rb/ronin-nmap/issues/new'
36
+
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-nmap - A Ruby library for automating nmap and importing nmap scans.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-nmap 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-nmap 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-nmap. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/nmap/root'
22
+ require 'ronin/core/cli/completion_command'
23
+
24
+ module Ronin
25
+ module Nmap
26
+ class CLI
27
+ module Commands
28
+ #
29
+ # Manages the shell completion rules for `ronin-nmap`.
30
+ #
31
+ # ## Usage
32
+ #
33
+ # ronin-nmap completion [options]
34
+ #
35
+ # ## Options
36
+ #
37
+ # --print Prints the shell completion file
38
+ # --install Installs the shell completion file
39
+ # --uninstall Uninstalls the shell completion file
40
+ # -h, --help Print help information
41
+ #
42
+ # ## Examples
43
+ #
44
+ # ronin-nmap completion --print
45
+ # ronin-nmap completion --install
46
+ # ronin-nmap completion --uninstall
47
+ #
48
+ class Completion < Core::CLI::CompletionCommand
49
+
50
+ completion_file File.join(ROOT,'data','completions','ronin-nmap')
51
+
52
+ man_dir File.join(ROOT,'man')
53
+ man_page 'ronin-nmap-completion.1'
54
+
55
+ description 'Manages the shell completion rules for ronin-nmap'
56
+
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-nmap - A Ruby library for automating nmap and importing nmap scans.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-nmap 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-nmap 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-nmap. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/nmap/cli/command'
22
+ require 'ronin/nmap/converter'
23
+
24
+ module Ronin
25
+ module Nmap
26
+ class CLI
27
+ module Commands
28
+ #
29
+ # Converts an nmap XML file to JSON or CSV.
30
+ #
31
+ # ## Usage
32
+ #
33
+ # ronin-nmap convert [--format json|csv] XML_FILE [OUTPUT_FILE]
34
+ #
35
+ # ## Option
36
+ #
37
+ # -F, --format json|csv The desired output format
38
+ # -h, --help Print help information
39
+ #
40
+ # ## Arguments
41
+ #
42
+ # XML_FILE The input XML file to parse
43
+ # OUTPUT_FILE The output file
44
+ #
45
+ class Convert < Command
46
+
47
+ usage '[--format json|csv] XML_FILE [OUTPUT_FILE]'
48
+
49
+ option :format, short: '-F',
50
+ value: {
51
+ type: [:json, :csv],
52
+ required: true
53
+ },
54
+ desc: 'The desired output format'
55
+
56
+ argument :xml_file, required: true,
57
+ desc: 'The input XML file to parse'
58
+
59
+ argument :output_file, required: false,
60
+ desc: 'The output file'
61
+
62
+ description "Converts an nmap XML file to JSON or CSV"
63
+
64
+ man_page 'ronin-nmap-convert.1'
65
+
66
+ # The desired output format.
67
+ #
68
+ # @return [:json, :csv, nil]
69
+ attr_reader :format
70
+
71
+ #
72
+ # Runs the `ronin-nmap convert` command.
73
+ #
74
+ # @param [String] xml_file
75
+ # The XML input file to parse.
76
+ #
77
+ # @param [String] output_file
78
+ # The output file to write to.
79
+ #
80
+ def run(xml_file,output_file=nil)
81
+ unless File.file?(xml_file)
82
+ print_error "no such file or directory: #{xml_file}"
83
+ exit(-1)
84
+ end
85
+
86
+ if output_file
87
+ if (format = options[:format])
88
+ Converter.convert_file(xml_file,output_file, format: format)
89
+ else
90
+ Converter.convert_file(xml_file,output_file)
91
+ end
92
+ else
93
+ unless (format = options[:format])
94
+ print_error "must specify a --format if no output file is given"
95
+ exit(-1)
96
+ end
97
+
98
+ xml = ::Nmap::XML.open(xml_file)
99
+
100
+ Converter.convert(xml,stdout, format: format)
101
+ end
102
+ end
103
+
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,293 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-nmap - A Ruby library for automating nmap and importing nmap scans.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-nmap 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-nmap 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-nmap. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/nmap/cli/command'
22
+ require 'ronin/nmap/cli/filtering_options'
23
+ require 'nmap/xml'
24
+
25
+ require 'set'
26
+
27
+ module Ronin
28
+ module Nmap
29
+ class CLI
30
+ module Commands
31
+ #
32
+ # Dumps the scanned ports from nmap XML file(s).
33
+ #
34
+ # ## Usage
35
+ #
36
+ # ronin-nmap dump [options] XML_FILE [...]
37
+ #
38
+ # ## Options
39
+ #
40
+ # --print-ips Print all IP addresses
41
+ # --print-hosts Print all hostnames
42
+ # --print-ip-ports Print IP:PORT pairs. (Default)
43
+ # --print-host-ports Print HOST:PORT pairs
44
+ # --print-uris Print URIs
45
+ # --ip IP Filters the targets by IP
46
+ # --ip-range CIDR Filter the targets by IP range
47
+ # --domain DOMAIN Filters the targets by domain
48
+ # --with-os OS Filters the targets by OS
49
+ # --with-ports {PORT | PORT1-PORT2},...
50
+ # Filter targets by port numbers
51
+ # --with-service SERVICE[,...] Filters targets by service
52
+ # --with-script SCRIPT[,...] Filters targets with the script
53
+ # --with-script-output STRING Filters targets containing the script output
54
+ # --with-script-regex /REGEX/ Filters targets containing the script output
55
+ # -p, --ports {PORT | PORT1-PORT2},...
56
+ # Filter targets by port numbers
57
+ # --services SERVICE[,...] Filters targets by service
58
+ # -h, --help Print help information
59
+ #
60
+ # ## Arguments
61
+ #
62
+ # XML_FILE ... The nmap XML file(s) to parse
63
+ #
64
+ # ## Examples
65
+ #
66
+ # ronin-nmap dump --print-ip-ports scan.xml
67
+ # ronin-nmap dump --print-ip-ports --ports 22,80,443 scan.xml
68
+ # ronin-nmap dump --print-host-ports scan.xml
69
+ # ronin-nmap dump --print-hosts --with-port 22 scan.xml
70
+ # ronin-nmap dump --print-uris scan.xml
71
+ #
72
+ class Dump < Command
73
+
74
+ usage '[options] XML_FILE [...]'
75
+
76
+ option :print_ips, desc: 'Print all IP addresses' do
77
+ @mode = :ips
78
+ end
79
+
80
+ option :print_hosts, desc: 'Print all hostnames' do
81
+ @mode = :hostnames
82
+ end
83
+
84
+ option :print_ip_ports, desc: 'Print IP:PORT pairs. (Default)' do
85
+ @mode = :ip_ports
86
+ end
87
+
88
+ option :print_host_ports, desc: 'Print HOST:PORT pairs' do
89
+ @mode = :host_ports
90
+ end
91
+
92
+ option :print_uris, desc: 'Print URIs' do
93
+ @mode = :uris
94
+ end
95
+
96
+ include FilteringOptions
97
+
98
+ option :ports, short: '-p',
99
+ value: {
100
+ type: /\A(?:\d+|\d+-\d+)(?:,(?:\d+|\d+-\d+))*\z/,
101
+ usage: '{PORT | PORT1-PORT2},...'
102
+ },
103
+ desc: 'Filter targets by port numbers' do |ports|
104
+ @ports << PortList.parse(ports)
105
+ end
106
+
107
+ option :services, value: {
108
+ type: /\A(?:[a-z]+[a-z0-9_+-]*)(?:,[a-z]+[a-z0-9_+-]*)*\z/,
109
+ usage: 'SERVICE[,...]'
110
+ },
111
+ desc: 'Filters targets by service' do |services|
112
+ @services.merge(services.split(','))
113
+ end
114
+
115
+ argument :xml_file, required: true,
116
+ repeats: true,
117
+ desc: 'The nmap XML file(s) to parse'
118
+
119
+ examples [
120
+ '--print-ip-ports scan.xml',
121
+ '--print-ip-ports --ports 22,80,443 scan.xml',
122
+ '--print-host-ports scan.xml',
123
+ '--print-hosts --with-port 22 scan.xml',
124
+ '--print-uris scan.xml'
125
+ ]
126
+
127
+ description 'Dumps the scanned ports from nmap XML file(s)'
128
+
129
+ man_page 'ronin-nmap-dump.1'
130
+
131
+ #
132
+ # Initializes the command.
133
+ #
134
+ # @param [Hash{Symbol => Object}] kwargs
135
+ # Additional keywords for the command.
136
+ #
137
+ def initialize(**kwargs)
138
+ super(**kwargs)
139
+
140
+ @mode = :ip_ports
141
+
142
+ @ports = Set.new
143
+ @services = Set.new
144
+ end
145
+
146
+ #
147
+ # Runs the `ronin-nmap dump` command.
148
+ #
149
+ # @param [Array<String>] xml_files
150
+ # The nmap XML files to parse.
151
+ #
152
+ def run(*xml_files)
153
+ xml_files.each do |xml_file|
154
+ xml = ::Nmap::XML.open(xml_file)
155
+
156
+ filter_targets(xml).each do |host|
157
+ print_target(host)
158
+ end
159
+ end
160
+ end
161
+
162
+ #
163
+ # Prints the targets.
164
+ #
165
+ # @param [::Nmap::XML::Host] host
166
+ #
167
+ def print_target(host)
168
+ case @mode
169
+ when :ips then print_ip(host)
170
+ when :hostnames then print_hostname(host)
171
+ when :ip_ports then print_ip_ports(host)
172
+ when :host_ports then print_host_ports(host)
173
+ when :uris then print_uris(host)
174
+ end
175
+ end
176
+
177
+ #
178
+ # Prints the IPs for the target.
179
+ #
180
+ # @param [::Nmap::XML::Host] host
181
+ #
182
+ def print_ip(host)
183
+ puts host.address
184
+ end
185
+
186
+ #
187
+ # Prints the host names for the target.
188
+ #
189
+ # @param [::Nmap::XML::Host] host
190
+ #
191
+ def print_hostnames(host)
192
+ if (hostname = host.hostname)
193
+ puts hostname
194
+ end
195
+ end
196
+
197
+ #
198
+ # Prints the `IP:PORT` pair for the target.
199
+ #
200
+ # @param [::Nmap::XML::Host] host
201
+ #
202
+ def print_ip_ports(host)
203
+ filter_ports(host).each do |port|
204
+ puts "#{host.address}:#{port.number}"
205
+ end
206
+ end
207
+
208
+ #
209
+ # Prints the `HOST:PORT` pair for the target.
210
+ #
211
+ # @param [::Nmap::XML::Host] host
212
+ #
213
+ def print_host_ports(host)
214
+ filter_ports(host).each do |port|
215
+ if (hostname = host.hostname)
216
+ puts "#{hostname}:#{port.number}"
217
+ end
218
+ end
219
+ end
220
+
221
+ #
222
+ # Prints the URIs for the target.
223
+ #
224
+ # @param [::Nmap::XML::Host] host
225
+ #
226
+ def print_uris(host)
227
+ filter_ports(host).each do |port|
228
+ if (port.service && port.service.name == 'http') ||
229
+ (port.number == 80)
230
+ puts URI::HTTP.build(
231
+ host: host.to_s,
232
+ port: port.number
233
+ )
234
+ elsif (port.service && port.service.name == 'https') ||
235
+ (port.number == 443)
236
+ puts URI::HTTPS.build(
237
+ host: host.to_s,
238
+ port: port.number
239
+ )
240
+ end
241
+ end
242
+ end
243
+
244
+ #
245
+ # @param [::Nmap::XML::Host] host
246
+ #
247
+ # @return [Enumerator::Lazy]
248
+ #
249
+ def filter_ports(host)
250
+ ports = host.each_open_port.lazy
251
+
252
+ unless @ports.empty?
253
+ ports = filter_ports_by_number(ports)
254
+ end
255
+
256
+ unless @services.empty?
257
+ ports = filter_ports_by_service(ports)
258
+ end
259
+
260
+ return ports
261
+ end
262
+
263
+ #
264
+ # @param [Enumerator::Lazy] ports
265
+ #
266
+ # @return [Enumerator::Lazy]
267
+ #
268
+ def filter_ports_by_number(ports)
269
+ ports.filter do |port|
270
+ @ports.any? do |port_list|
271
+ port_list.include?(port.number)
272
+ end
273
+ end
274
+ end
275
+
276
+ #
277
+ # @param [Enumerator::Lazy] ports
278
+ #
279
+ # @return [Enumerator::Lazy]
280
+ #
281
+ def filter_ports_by_service(ports)
282
+ ports.filter do |port|
283
+ if (service = port.service)
284
+ @services.include?(service.name)
285
+ end
286
+ end
287
+ end
288
+
289
+ end
290
+ end
291
+ end
292
+ end
293
+ end