ruby-nmap 0.9.3 → 1.0.0

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.
Files changed (107) hide show
  1. checksums.yaml +5 -5
  2. data/.document +1 -0
  3. data/.editorconfig +11 -0
  4. data/.github/workflows/ruby.yml +31 -0
  5. data/ChangeLog.md +122 -67
  6. data/Gemfile +11 -5
  7. data/LICENSE.txt +1 -1
  8. data/README.md +88 -50
  9. data/Rakefile +8 -3
  10. data/UPGRADING.md +47 -0
  11. data/gemspec.yml +6 -6
  12. data/lib/nmap/command.rb +765 -0
  13. data/lib/nmap/version.rb +1 -1
  14. data/lib/nmap/xml/address.rb +38 -0
  15. data/lib/nmap/xml/cpe/url.rb +80 -0
  16. data/lib/nmap/xml/cpe.rb +47 -0
  17. data/lib/nmap/xml/hop.rb +22 -0
  18. data/lib/nmap/xml/host.rb +546 -0
  19. data/lib/nmap/xml/host_script.rb +26 -0
  20. data/lib/nmap/xml/hostname.rb +44 -0
  21. data/lib/nmap/xml/ip_id_sequence.rb +26 -0
  22. data/lib/nmap/xml/os.rb +131 -0
  23. data/lib/nmap/xml/os_class.rb +86 -0
  24. data/lib/nmap/xml/os_match.rb +22 -0
  25. data/lib/nmap/xml/port.rb +114 -0
  26. data/lib/nmap/xml/postscript.rb +26 -0
  27. data/lib/nmap/xml/prescript.rb +26 -0
  28. data/lib/nmap/xml/run_stat.rb +22 -0
  29. data/lib/nmap/xml/scan.rb +38 -0
  30. data/lib/nmap/xml/scan_task.rb +55 -0
  31. data/lib/nmap/xml/scanner.rb +22 -0
  32. data/lib/nmap/xml/script.rb +110 -0
  33. data/lib/nmap/xml/scripts.rb +33 -0
  34. data/lib/nmap/xml/sequence.rb +52 -0
  35. data/lib/nmap/xml/service.rb +172 -0
  36. data/lib/nmap/xml/status.rb +22 -0
  37. data/lib/nmap/xml/tcp_sequence.rb +48 -0
  38. data/lib/nmap/xml/tcp_ts_sequence.rb +26 -0
  39. data/lib/nmap/xml/traceroute.rb +73 -0
  40. data/lib/nmap/xml/uptime.rb +22 -0
  41. data/lib/nmap/xml.rb +46 -44
  42. data/ruby-nmap.gemspec +38 -83
  43. data/spec/command_spec.rb +726 -0
  44. data/spec/fixtures/down_host_scan.xml +16 -0
  45. data/spec/{local_scan.xml → fixtures/local_scan.xml} +1 -1
  46. data/spec/{scan.xml → fixtures/scan.xml} +1 -1
  47. data/spec/spec_helper.rb +2 -2
  48. data/spec/{address_spec.rb → xml/address_spec.rb} +2 -2
  49. data/spec/{cpe → xml/cpe}/url_spec.rb +1 -1
  50. data/spec/{cpe_examples.rb → xml/cpe_examples.rb} +1 -1
  51. data/spec/{hop_spec.rb → xml/hop_spec.rb} +2 -2
  52. data/spec/{host_script_spec.rb → xml/host_script_spec.rb} +2 -2
  53. data/spec/{host_spec.rb → xml/host_spec.rb} +12 -8
  54. data/spec/{hostname_spec.rb → xml/hostname_spec.rb} +2 -2
  55. data/spec/{ip_id_sequence_spec.rb → xml/ip_id_sequence_spec.rb} +3 -3
  56. data/spec/{os_class_spec.rb → xml/os_class_spec.rb} +3 -3
  57. data/spec/{os_match_spec.rb → xml/os_match_spec.rb} +2 -2
  58. data/spec/{os_spec.rb → xml/os_spec.rb} +3 -3
  59. data/spec/{port_spec.rb → xml/port_spec.rb} +10 -5
  60. data/spec/{postscript_spec.rb → xml/postscript_spec.rb} +2 -2
  61. data/spec/{prescript_spec.rb → xml/prescript_spec.rb} +2 -2
  62. data/spec/{run_stat_spec.rb → xml/run_stat_spec.rb} +2 -2
  63. data/spec/{scan_spec.rb → xml/scan_spec.rb} +2 -2
  64. data/spec/{scan_task_spec.rb → xml/scan_task_spec.rb} +6 -6
  65. data/spec/{scanner_spec.rb → xml/scanner_spec.rb} +3 -3
  66. data/spec/xml/script_spec.rb +137 -0
  67. data/spec/xml/scripts_examples.rb +19 -0
  68. data/spec/{sequence_examples.rb → xml/sequence_examples.rb} +1 -0
  69. data/spec/{service_spec.rb → xml/service_spec.rb} +31 -5
  70. data/spec/{status_spec.rb → xml/status_spec.rb} +4 -3
  71. data/spec/{tcp_sequence_spec.rb → xml/tcp_sequence_spec.rb} +3 -3
  72. data/spec/{tcp_ts_sequence_spec.rb → xml/tcp_ts_sequence_spec.rb} +3 -3
  73. data/spec/{traceroute_spec.rb → xml/traceroute_spec.rb} +3 -3
  74. data/spec/{uptime_spec.rb → xml/uptime_spec.rb} +2 -2
  75. data/spec/xml_spec.rb +93 -45
  76. metadata +78 -99
  77. data/.travis.yml +0 -14
  78. data/lib/nmap/address.rb +0 -34
  79. data/lib/nmap/cpe/url.rb +0 -78
  80. data/lib/nmap/cpe.rb +0 -45
  81. data/lib/nmap/hop.rb +0 -20
  82. data/lib/nmap/host.rb +0 -586
  83. data/lib/nmap/host_script.rb +0 -18
  84. data/lib/nmap/hostname.rb +0 -42
  85. data/lib/nmap/ip_id_sequence.rb +0 -24
  86. data/lib/nmap/os.rb +0 -127
  87. data/lib/nmap/os_class.rb +0 -82
  88. data/lib/nmap/os_match.rb +0 -18
  89. data/lib/nmap/port.rb +0 -99
  90. data/lib/nmap/postscript.rb +0 -16
  91. data/lib/nmap/prescript.rb +0 -16
  92. data/lib/nmap/program.rb +0 -102
  93. data/lib/nmap/run_stat.rb +0 -20
  94. data/lib/nmap/scan.rb +0 -34
  95. data/lib/nmap/scan_task.rb +0 -50
  96. data/lib/nmap/scanner.rb +0 -18
  97. data/lib/nmap/scripts.rb +0 -71
  98. data/lib/nmap/sequence.rb +0 -50
  99. data/lib/nmap/service.rb +0 -170
  100. data/lib/nmap/status.rb +0 -18
  101. data/lib/nmap/task.rb +0 -381
  102. data/lib/nmap/tcp_sequence.rb +0 -46
  103. data/lib/nmap/tcp_ts_sequence.rb +0 -22
  104. data/lib/nmap/traceroute.rb +0 -71
  105. data/lib/nmap/uptime.rb +0 -20
  106. data/spec/scripts_examples.rb +0 -35
  107. data/spec/task_spec.rb +0 -150
@@ -1,24 +0,0 @@
1
- require 'nmap/sequence'
2
-
3
- module Nmap
4
- #
5
- # Represents an IP ID.
6
- #
7
- # @since 0.5.0
8
- #
9
- class IpIdSequence < Sequence
10
-
11
- #
12
- # Converts the IpidSequence class to a String.
13
- #
14
- # @return [String]
15
- # The String form of the object.
16
- #
17
- # @since 0.5.0
18
- #
19
- def to_s
20
- "description=#{description.inspect} values=#{values.inspect}"
21
- end
22
-
23
- end
24
- end
data/lib/nmap/os.rb DELETED
@@ -1,127 +0,0 @@
1
- require 'nmap/os_class'
2
- require 'nmap/os_match'
3
-
4
- module Nmap
5
- #
6
- # Wraps the `os` XML element.
7
- #
8
- class OS
9
-
10
- include Enumerable
11
-
12
- #
13
- # Creates a new OS object.
14
- #
15
- # @param [Nokogiri::XML::Node] node
16
- # The node that contains the OS guessing information.
17
- #
18
- def initialize(node)
19
- @node = node
20
- end
21
-
22
- #
23
- # Parses the OS class information.
24
- #
25
- # @yield [class]
26
- # Passes each OS class to the given block.
27
- #
28
- # @yieldparam [OSClass] class
29
- # The OS class information.
30
- #
31
- # @return [OS, Enumerator]
32
- # The OS information. If no block was given, an enumerator object
33
- # will be returned.
34
- #
35
- def each_class
36
- return enum_for(__method__) unless block_given?
37
-
38
- @node.xpath("osmatch/osclass").each do |osclass|
39
- yield OSClass.new(osclass)
40
- end
41
-
42
- return self
43
- end
44
-
45
- #
46
- # Parses the OS class information.
47
- #
48
- # @return [Array<OSClass>]
49
- # The OS class information.
50
- #
51
- def classes
52
- each_class.to_a
53
- end
54
-
55
- #
56
- # Parses the OS match information.
57
- #
58
- # @yield [match]
59
- # Passes each OS match to the given block.
60
- #
61
- # @yieldparam [OSMatch] class
62
- # The OS match information.
63
- #
64
- # @return [OS, Enumerator]
65
- # The OS information. If no block was given, an enumerator object
66
- # will be returned.
67
- #
68
- def each_match
69
- return enum_for(__method__) unless block_given?
70
-
71
- @node.xpath("osmatch").map do |osclass|
72
- os_match = OSMatch.new(
73
- osclass['name'],
74
- osclass['accuracy'].to_i
75
- )
76
-
77
- yield os_match
78
- end
79
-
80
- return self
81
- end
82
-
83
- #
84
- # Parses the OS match information.
85
- #
86
- # @return [Array<OSMatch>]
87
- # The OS match information.
88
- #
89
- def matches
90
- each_match.to_a
91
- end
92
-
93
- #
94
- # Parses the ports used for guessing the OS.
95
- #
96
- # @return [Array<Integer>]
97
- # The ports used.
98
- #
99
- def ports_used
100
- @ports_used ||= @node.xpath("portused/@portid").map do |port|
101
- port.inner_text.to_i
102
- end
103
- end
104
-
105
- #
106
- # Parses the OS fingerprint used by Nmap.
107
- #
108
- # @return [String]
109
- # The OS fingerprint.
110
- #
111
- def fingerprint
112
- @fingerprint ||= if (fingerprint = @node.at_xpath("osfingerprint/@fingerprint"))
113
- fingerprint.inner_text
114
- end
115
- end
116
-
117
- #
118
- # Parses the OS match information.
119
- #
120
- # @see #each_match
121
- #
122
- def each(&block)
123
- each_match(&block)
124
- end
125
-
126
- end
127
- end
data/lib/nmap/os_class.rb DELETED
@@ -1,82 +0,0 @@
1
- require 'nmap/cpe'
2
-
3
- module Nmap
4
- #
5
- # Represents an {OS} class.
6
- #
7
- class OSClass
8
-
9
- include CPE
10
-
11
- #
12
- # Initializes the os class.
13
- #
14
- # @param [Nokogiri::XML::Node] node
15
- # The node that contains the OS Class information.
16
- #
17
- def initialize(node)
18
- @node = node
19
- end
20
-
21
- #
22
- # The OS type.
23
- #
24
- # @return [String]
25
- #
26
- def type
27
- @type ||= if @node['type']
28
- @node['type'].to_sym
29
- end
30
- end
31
-
32
- #
33
- # The OS vendor.
34
- #
35
- # @return [String]
36
- #
37
- def vendor
38
- @vendor ||= @node.get_attribute('vendor')
39
- end
40
-
41
- #
42
- # The OS family.
43
- #
44
- # @return [Symbol, nil]
45
- #
46
- def family
47
- @family ||= @node.get_attribute('osfamily').to_sym
48
- end
49
-
50
- #
51
- # The OS generation.
52
- #
53
- # @return [Symbol, nil]
54
- #
55
- def gen
56
- @gen ||= if @node['osgen']
57
- @node['osgen'].to_sym
58
- end
59
- end
60
-
61
- #
62
- # The accuracy of the OS class information.
63
- #
64
- # @return [Integer]
65
- # Returns a number between 0 and 10.
66
- #
67
- def accuracy
68
- @accuracy ||= @node.get_attribute('accuracy').to_i
69
- end
70
-
71
- #
72
- # Converts the OS class to a String.
73
- #
74
- # @return [String]
75
- # The String form of the OS class.
76
- #
77
- def to_s
78
- "#{self.type} #{self.vendor} (#{self.accuracy}%)"
79
- end
80
-
81
- end
82
- end
data/lib/nmap/os_match.rb DELETED
@@ -1,18 +0,0 @@
1
- module Nmap
2
- #
3
- # Represents a match for a specific {OS}.
4
- #
5
- class OSMatch < Struct.new(:name, :accuracy)
6
-
7
- #
8
- # Converts the OS match to a String.
9
- #
10
- # @return [String]
11
- # The String form of the OS match.
12
- #
13
- def to_s
14
- "#{self.name} (#{self.accuracy}%)"
15
- end
16
-
17
- end
18
- end
data/lib/nmap/port.rb DELETED
@@ -1,99 +0,0 @@
1
- require 'nmap/service'
2
- require 'nmap/scripts'
3
-
4
- module Nmap
5
- #
6
- # Wraps a `port` XML element.
7
- #
8
- class Port
9
-
10
- include Scripts
11
-
12
- #
13
- # Creates a new Port object.
14
- #
15
- # @param [Nokogiri::XML::Element] node
16
- # The XML `port` element.
17
- #
18
- def initialize(node)
19
- @node = node
20
- end
21
-
22
- #
23
- # The protocol the port runs on
24
- #
25
- # @return [Symbol]
26
- # The protocol of the port.
27
- #
28
- def protocol
29
- @protocol ||= @node['protocol'].to_sym
30
- end
31
-
32
- #
33
- # The port number.
34
- #
35
- # @return [Integer]
36
- # The number of the port.
37
- #
38
- def number
39
- @number ||= @node['portid'].to_i
40
- end
41
-
42
- #
43
- # The state of the port.
44
- #
45
- # @return [Symbol]
46
- # The state of the port (`:open`, `:filtered` or `:closed`).
47
- #
48
- def state
49
- @state ||= @node.at_xpath('state/@state').inner_text.to_sym
50
- end
51
-
52
- #
53
- # The reason the port was discovered.
54
- #
55
- # @return [String]
56
- # How the port was discovered.
57
- #
58
- def reason
59
- @reason ||= @node.at_xpath('state/@reason').inner_text
60
- end
61
-
62
- #
63
- # The fingerprinted service of the port.
64
- #
65
- # @return [Service]
66
- # The service detected on the port.
67
- #
68
- # @since 0.6.0
69
- #
70
- def service
71
- @service_info ||= if (service = @node.at_xpath('service'))
72
- Service.new(service)
73
- end
74
- end
75
-
76
- alias to_i number
77
-
78
- #
79
- # Converts the port to a String.
80
- #
81
- # @return [String]
82
- # The port number.
83
- #
84
- def to_s
85
- number.to_s
86
- end
87
-
88
- #
89
- # Inspects the port.
90
- #
91
- # @return [String]
92
- # The inspected port.
93
- #
94
- def inspect
95
- "#<#{self.class}: #{self}>"
96
- end
97
-
98
- end
99
- end
@@ -1,16 +0,0 @@
1
- require 'nmap/scripts'
2
-
3
- module Nmap
4
- #
5
- # Represents the `postscript` element.
6
- #
7
- class Postscript
8
-
9
- include Scripts
10
-
11
- def initialize(node)
12
- @node = node
13
- end
14
-
15
- end
16
- end
@@ -1,16 +0,0 @@
1
- require 'nmap/scripts'
2
-
3
- module Nmap
4
- #
5
- # Represents the `prescript` element.
6
- #
7
- class Prescript
8
-
9
- include Scripts
10
-
11
- def initialize(node)
12
- @node = node
13
- end
14
-
15
- end
16
- end
data/lib/nmap/program.rb DELETED
@@ -1,102 +0,0 @@
1
- require 'nmap/task'
2
-
3
- require 'rprogram/program'
4
-
5
- module Nmap
6
- #
7
- # Represents the `nmap` program.
8
- #
9
- class Program < RProgram::Program
10
-
11
- name_program 'nmap'
12
-
13
- #
14
- # Finds the `nmap` program and performs a scan.
15
- #
16
- # @param [Hash{Symbol => Object}] options
17
- # Additional options for nmap.
18
- #
19
- # @param [Hash{Symbol => Object}] exec_options
20
- # Additional exec-options.
21
- #
22
- # @yield [task]
23
- # If a block is given, it will be passed a task object
24
- # used to specify options for nmap.
25
- #
26
- # @yieldparam [Task] task
27
- # The nmap task object.
28
- #
29
- # @return [Boolean]
30
- # Specifies whether the command exited normally.
31
- #
32
- # @example Specifying Nmap options via a Hash.
33
- # Nmap::Program.scan(
34
- # :targets => '192.168.1.1',
35
- # :ports => [22,80,443],
36
- # :verbose => true
37
- # )
38
- #
39
- # @example Specifying Nmap options via a {Task} object.
40
- # Nmap::Program.scan do |nmap|
41
- # nmap.targets = '192.168.1.1'
42
- # nmap.ports = [22,80,443]
43
- # nmap.verbose = true
44
- # end
45
- #
46
- # @see #scan
47
- #
48
- def self.scan(options={},exec_options={},&block)
49
- find.scan(options,exec_options,&block)
50
- end
51
-
52
- #
53
- # Finds the `nmap` program and performs a scan, but runs `nmap` under
54
- # `sudo`.
55
- #
56
- # @see scan
57
- #
58
- # @since 0.8.0
59
- #
60
- def self.sudo_scan(options={},exec_options={},&block)
61
- find.sudo_scan(options,exec_options,&block)
62
- end
63
-
64
- #
65
- # Performs a scan.
66
- #
67
- # @param [Hash{Symbol => Object}] options
68
- # Additional options for nmap.
69
- #
70
- # @param [Hash{Symbol => Object}] exec_options
71
- # Additional exec-options.
72
- #
73
- # @yield [task]
74
- # If a block is given, it will be passed a task object
75
- # used to specify options for nmap.
76
- #
77
- # @yieldparam [Task] task
78
- # The nmap task object.
79
- #
80
- # @return [Boolean]
81
- # Specifies whether the command exited normally.
82
- #
83
- # @see http://rubydoc.info/gems/rprogram/0.3.0/RProgram/Program#run-instance_method
84
- # For additional exec-options.
85
- #
86
- def scan(options={},exec_options={},&block)
87
- run_task(Task.new(options,&block),exec_options)
88
- end
89
-
90
- #
91
- # Performs a scan and runs `nmap` under `sudo`.
92
- #
93
- # @see #scan
94
- #
95
- # @since 0.8.0
96
- #
97
- def sudo_scan(options={},exec_options={},&block)
98
- sudo_task(Task.new(options,&block),exec_options)
99
- end
100
-
101
- end
102
- end
data/lib/nmap/run_stat.rb DELETED
@@ -1,20 +0,0 @@
1
- module Nmap
2
- #
3
- # Represents the runstats of a scan.
4
- #
5
- # @since 0.7.0
6
- #
7
- class RunStat < Struct.new(:end_time, :elapsed, :summary, :exit_status)
8
-
9
- #
10
- # Converts the stats to a String.
11
- #
12
- # @return [String]
13
- # The String form of the scan.
14
- #
15
- def to_s
16
- "#{self.end_time} #{self.elapsed} #{self.exit_status}"
17
- end
18
-
19
- end
20
- end
data/lib/nmap/scan.rb DELETED
@@ -1,34 +0,0 @@
1
- module Nmap
2
- #
3
- # Represents an Nmap scan.
4
- #
5
- class Scan < Struct.new(:type, :protocol, :services)
6
-
7
- #
8
- # Creates a new Scan object.
9
- #
10
- # @param [Symbol] type
11
- # The type of the scan.
12
- #
13
- # @param [Symbol] protocol
14
- # The protocol used for the scan.
15
- #
16
- # @param [Array<Integer, Rage>] services
17
- # The port numbers scanned.
18
- #
19
- def initialize(type,protocol,services=[])
20
- super(type,protocol,services)
21
- end
22
-
23
- #
24
- # Converts the scan to a String.
25
- #
26
- # @return [String]
27
- # The String form of the scan.
28
- #
29
- def to_s
30
- "#{self.protocol} #{self.type}"
31
- end
32
-
33
- end
34
- end
@@ -1,50 +0,0 @@
1
- module Nmap
2
- class ScanTask < Struct.new(:name, :start_time, :end_time, :extrainfo)
3
-
4
- #
5
- # Creates a new ScanTask object.
6
- #
7
- # @param [String] name
8
- # The name of the scan task.
9
- #
10
- # @param [Time] start_time
11
- # The time the scan task begun.
12
- #
13
- # @param [Time] end_time
14
- # The time the scan task ended.
15
- #
16
- # @param [String] extrainfo
17
- # Any extra information relating to the scan task.
18
- #
19
- # @since 0.1.2
20
- #
21
- def initialize(name,start_time,end_time,extrainfo=nil)
22
- super
23
- end
24
-
25
- #
26
- # The duration of the scan task.
27
- #
28
- # @return [Integer]
29
- # The number of seconds it took the scan task to complete.
30
- #
31
- # @since 0.1.2
32
- #
33
- def duration
34
- (self.end_time - self.start_time)
35
- end
36
-
37
- #
38
- # Converts the scan task to a String.
39
- #
40
- # @return [String]
41
- # The String form of the scan task.
42
- #
43
- # @since 0.1.2
44
- #
45
- def to_s
46
- "#{self.start_time}: #{self.name} (#{self.extrainfo})"
47
- end
48
-
49
- end
50
- end
data/lib/nmap/scanner.rb DELETED
@@ -1,18 +0,0 @@
1
- module Nmap
2
- #
3
- # Describes the `nmap` command.
4
- #
5
- class Scanner < Struct.new(:name, :version, :arguments, :start_time)
6
-
7
- #
8
- # Converts the scanner to a String.
9
- #
10
- # @return [String]
11
- # The scanner name and arguments.
12
- #
13
- def to_s
14
- "#{self.name} #{self.arguments}"
15
- end
16
-
17
- end
18
- end
data/lib/nmap/scripts.rb DELETED
@@ -1,71 +0,0 @@
1
- module Nmap
2
- module Scripts
3
- #
4
- # The output from the NSE scripts ran against the open port.
5
- #
6
- # @return [Hash{String => String}]
7
- # The NSE script names and output.
8
- #
9
- # @since 0.3.0
10
- #
11
- def scripts
12
- unless @scripts
13
- @scripts = {}
14
-
15
- @node.xpath('script').each do |script|
16
- @scripts[script['id']] = script['output']
17
- end
18
- end
19
-
20
- return @scripts
21
- end
22
-
23
- #
24
- # The structured output of the NSE scripts.
25
- #
26
- # @return [Hash{String => Hash{String => Array<String>}}]
27
- # The NSE script names and their structured output.
28
- #
29
- # @since 0.9.0
30
- #
31
- def script_data
32
- unless @script_data
33
- @script_data = {}
34
-
35
- traverse = lambda do |node|
36
- case node.name
37
- when 'script', 'table'
38
- unless node.xpath('*[@key]').empty?
39
- hash = {}
40
-
41
- node.elements.each do |element|
42
- hash[element['key']] = traverse.call(element)
43
- end
44
-
45
- hash
46
- else
47
- array = []
48
-
49
- node.elements.each do |element|
50
- array << traverse.call(element)
51
- end
52
-
53
- array
54
- end
55
- when 'elem'
56
- node.inner_text
57
- else
58
- raise(NotImplementedError,"unrecognized XML NSE element: #{node}")
59
- end
60
- end
61
-
62
- @node.xpath('script').each do |script|
63
- @script_data[script['id']] = traverse.call(script)
64
- end
65
- end
66
-
67
- return @script_data
68
- end
69
-
70
- end
71
- end