ronin-nmap 0.1.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +4 -0
- data/.github/workflows/ruby.yml +47 -0
- data/.gitignore +14 -0
- data/.rspec +1 -0
- data/.rubocop.yml +15 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +165 -0
- data/ChangeLog.md +10 -0
- data/Gemfile +42 -0
- data/README.md +238 -0
- data/Rakefile +43 -0
- data/bin/ronin-nmap +32 -0
- data/data/completions/ronin-nmap +79 -0
- data/data/templates/script.rb.erb +58 -0
- data/gemspec.yml +42 -0
- data/lib/ronin/nmap/cli/command.rb +40 -0
- data/lib/ronin/nmap/cli/commands/completion.rb +61 -0
- data/lib/ronin/nmap/cli/commands/convert.rb +108 -0
- data/lib/ronin/nmap/cli/commands/dump.rb +293 -0
- data/lib/ronin/nmap/cli/commands/grep.rb +378 -0
- data/lib/ronin/nmap/cli/commands/import.rb +79 -0
- data/lib/ronin/nmap/cli/commands/new.rb +226 -0
- data/lib/ronin/nmap/cli/commands/print.rb +133 -0
- data/lib/ronin/nmap/cli/commands/scan.rb +233 -0
- data/lib/ronin/nmap/cli/filtering_options.rb +355 -0
- data/lib/ronin/nmap/cli/importable.rb +68 -0
- data/lib/ronin/nmap/cli/port_list.rb +102 -0
- data/lib/ronin/nmap/cli.rb +50 -0
- data/lib/ronin/nmap/converter.rb +114 -0
- data/lib/ronin/nmap/converters/csv.rb +162 -0
- data/lib/ronin/nmap/converters/json.rb +562 -0
- data/lib/ronin/nmap/converters.rb +54 -0
- data/lib/ronin/nmap/exceptions.rb +47 -0
- data/lib/ronin/nmap/importer.rb +369 -0
- data/lib/ronin/nmap/root.rb +28 -0
- data/lib/ronin/nmap/version.rb +26 -0
- data/lib/ronin/nmap.rb +223 -0
- data/man/ronin-nmap-completion.1 +76 -0
- data/man/ronin-nmap-completion.1.md +78 -0
- data/man/ronin-nmap-convert.1 +33 -0
- data/man/ronin-nmap-convert.1.md +36 -0
- data/man/ronin-nmap-dump.1 +141 -0
- data/man/ronin-nmap-dump.1.md +119 -0
- data/man/ronin-nmap-grep.1 +33 -0
- data/man/ronin-nmap-grep.1.md +36 -0
- data/man/ronin-nmap-import.1 +52 -0
- data/man/ronin-nmap-import.1.md +57 -0
- data/man/ronin-nmap-new.1 +81 -0
- data/man/ronin-nmap-new.1.md +73 -0
- data/man/ronin-nmap-print.1 +61 -0
- data/man/ronin-nmap-print.1.md +63 -0
- data/man/ronin-nmap-scan.1 +86 -0
- data/man/ronin-nmap-scan.1.md +84 -0
- data/man/ronin-nmap.1 +58 -0
- data/man/ronin-nmap.1.md +57 -0
- data/ronin-nmap.gemspec +62 -0
- data/scripts/setup +161 -0
- 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
|