ruby-nmap 0.6.0 → 0.7.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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.travis.yml +13 -0
  4. data/ChangeLog.md +24 -0
  5. data/Gemfile +12 -0
  6. data/LICENSE.txt +1 -1
  7. data/README.md +11 -9
  8. data/Rakefile +20 -24
  9. data/gemspec.yml +1 -3
  10. data/lib/nmap/cpe.rb +2 -0
  11. data/lib/nmap/cpe/cpe.rb +45 -0
  12. data/lib/nmap/cpe/url.rb +78 -0
  13. data/lib/nmap/hop.rb +20 -0
  14. data/lib/nmap/host.rb +69 -15
  15. data/lib/nmap/hostname.rb +20 -0
  16. data/lib/nmap/os.rb +2 -17
  17. data/lib/nmap/os_class.rb +65 -1
  18. data/lib/nmap/port.rb +10 -0
  19. data/lib/nmap/run_stat.rb +20 -0
  20. data/lib/nmap/scan_task.rb +4 -19
  21. data/lib/nmap/sequence.rb +6 -18
  22. data/lib/nmap/service.rb +76 -0
  23. data/lib/nmap/tcp_sequence.rb +1 -1
  24. data/lib/nmap/traceroute.rb +67 -0
  25. data/lib/nmap/uptime.rb +20 -0
  26. data/lib/nmap/version.rb +1 -1
  27. data/lib/nmap/xml.rb +134 -17
  28. data/spec/address_spec.rb +14 -0
  29. data/spec/cpe/url_spec.rb +99 -0
  30. data/spec/cpe_examples.rb +11 -0
  31. data/spec/hop_spec.rb +14 -0
  32. data/spec/host_spec.rb +138 -55
  33. data/spec/hostname_spec.rb +15 -0
  34. data/spec/ip_id_sequence_spec.rb +24 -10
  35. data/spec/os_class_spec.rb +31 -0
  36. data/spec/os_match_spec.rb +15 -0
  37. data/spec/os_spec.rb +23 -20
  38. data/spec/port_spec.rb +14 -15
  39. data/spec/run_stat_spec.rb +21 -0
  40. data/spec/scan.xml +137 -0
  41. data/spec/scan_spec.rb +28 -0
  42. data/spec/scan_task_spec.rb +35 -0
  43. data/spec/scanner_spec.rb +24 -0
  44. data/spec/scripts_examples.rb +10 -0
  45. data/spec/sequence_examples.rb +10 -0
  46. data/spec/service_spec.rb +55 -18
  47. data/spec/spec_helper.rb +30 -3
  48. data/spec/status_spec.rb +15 -0
  49. data/spec/tcp_sequence_spec.rb +32 -19
  50. data/spec/tcp_ts_sequence_spec.rb +24 -10
  51. data/spec/traceroute_spec.rb +31 -0
  52. data/spec/uptime_spec.rb +15 -0
  53. data/spec/xml_spec.rb +172 -31
  54. metadata +50 -54
  55. data/.gemtest +0 -0
  56. data/spec/helpers/nse.xml +0 -94
  57. data/spec/helpers/scan.xml +0 -241
  58. data/spec/helpers/xml.rb +0 -5
@@ -0,0 +1,20 @@
1
+ module Nmap
2
+ #
3
+ # Represents a hostname.
4
+ #
5
+ # @since 0.7.0
6
+ #
7
+ class Hostname < Struct.new(:type, :name)
8
+
9
+ #
10
+ # Converts the hostname to a String.
11
+ #
12
+ # @return [String]
13
+ # The name of the host.
14
+ #
15
+ def to_s
16
+ self.name.to_s
17
+ end
18
+
19
+ end
20
+ end
@@ -15,16 +15,8 @@ module Nmap
15
15
  # @param [Nokogiri::XML::Node] node
16
16
  # The node that contains the OS guessing information.
17
17
  #
18
- # @yield [os]
19
- # If a block is given, it will passed the newly created OS object.
20
- #
21
- # @yieldparam [OS] os
22
- # The newly created OS object.
23
- #
24
18
  def initialize(node)
25
19
  @node = node
26
-
27
- yield self if block_given?
28
20
  end
29
21
 
30
22
  #
@@ -43,15 +35,8 @@ module Nmap
43
35
  def each_class
44
36
  return enum_for(__method__) unless block_given?
45
37
 
46
- @node.xpath("osclass").map do |osclass|
47
- os_class = OSClass.new(
48
- osclass['type'].to_sym,
49
- osclass['vendor'],
50
- osclass['osfamily'].to_sym,
51
- osclass['accuracy'].to_i
52
- )
53
-
54
- yield os_class
38
+ @node.xpath("osmatch/osclass").each do |osclass|
39
+ yield OSClass.new(osclass)
55
40
  end
56
41
 
57
42
  return self
@@ -1,8 +1,72 @@
1
+ require 'nmap/cpe'
2
+
1
3
  module Nmap
2
4
  #
3
5
  # Represents an {OS} class.
4
6
  #
5
- class OSClass < Struct.new(:type, :vendor, :family, :accuracy)
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
6
70
 
7
71
  #
8
72
  # Converts the OS class to a String.
@@ -102,5 +102,15 @@ module Nmap
102
102
  number.to_s
103
103
  end
104
104
 
105
+ #
106
+ # Inspects the port.
107
+ #
108
+ # @return [String]
109
+ # The inspected port.
110
+ #
111
+ def inspect
112
+ "#<#{self.class}: #{self}>"
113
+ end
114
+
105
115
  end
106
116
  end
@@ -0,0 +1,20 @@
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
@@ -1,17 +1,5 @@
1
1
  module Nmap
2
- class ScanTask
3
-
4
- # The name of the scan task
5
- attr_reader :name
6
-
7
- # The time the scan task begun
8
- attr_reader :start_time
9
-
10
- # The time the scan task ended
11
- attr_reader :end_time
12
-
13
- # Extra information on the scan task
14
- attr_reader :extrainfo
2
+ class ScanTask < Struct.new(:name, :start_time, :end_time, :extrainfo)
15
3
 
16
4
  #
17
5
  # Creates a new ScanTask object.
@@ -31,10 +19,7 @@ module Nmap
31
19
  # @since 0.1.2
32
20
  #
33
21
  def initialize(name,start_time,end_time,extrainfo=nil)
34
- @name = name
35
- @start_time = start_time
36
- @end_time = end_time
37
- @extrainfo = extrainfo
22
+ super
38
23
  end
39
24
 
40
25
  #
@@ -46,7 +31,7 @@ module Nmap
46
31
  # @since 0.1.2
47
32
  #
48
33
  def duration
49
- (@end_time - @start_time)
34
+ (self.end_time - self.start_time)
50
35
  end
51
36
 
52
37
  #
@@ -58,7 +43,7 @@ module Nmap
58
43
  # @since 0.1.2
59
44
  #
60
45
  def to_s
61
- "#{@start}: #{@name} (#{@extrainfo})"
46
+ "#{self.start_time}: #{self.name} (#{self.extrainfo})"
62
47
  end
63
48
 
64
49
  end
@@ -12,18 +12,10 @@ module Nmap
12
12
  # @param [Nokogiri::XML::Node] node
13
13
  # The node that contains the sequence information.
14
14
  #
15
- # @yield [sequence]
16
- # If a block is given, it will passed the newly created sequence.
17
- #
18
- # @yieldparam [Sequence] sequence
19
- # The newly created sequence object.
20
- #
21
15
  # @since 0.5.0
22
16
  #
23
17
  def initialize(node)
24
18
  @node = node
25
-
26
- yield self if block_given?
27
19
  end
28
20
 
29
21
  #
@@ -35,7 +27,7 @@ module Nmap
35
27
  # @since 0.5.0
36
28
  #
37
29
  def description
38
- @node['class']
30
+ @description ||= @node['class']
39
31
  end
40
32
 
41
33
  #
@@ -47,15 +39,11 @@ module Nmap
47
39
  # @since 0.5.0
48
40
  #
49
41
  def values
50
- unless @values
51
- @values = []
52
-
53
- if (string = @node['values'])
54
- string.scan(/[^\s,]+/) { |match| @values << match.to_i(16) }
55
- end
56
- end
57
-
58
- return @values
42
+ @values ||= if @node['values']
43
+ @node['values'].split(',').map { |value| value.to_i(16) }
44
+ else
45
+ []
46
+ end
59
47
  end
60
48
 
61
49
  end
@@ -1,3 +1,5 @@
1
+ require 'nmap/cpe'
2
+
1
3
  module Nmap
2
4
  #
3
5
  # Wraps a `service` XML element.
@@ -6,6 +8,8 @@ module Nmap
6
8
  #
7
9
  class Service
8
10
 
11
+ include CPE
12
+
9
13
  #
10
14
  # Creates a new OS object.
11
15
  #
@@ -26,6 +30,30 @@ module Nmap
26
30
  @name ||= @node.get_attribute('name')
27
31
  end
28
32
 
33
+ #
34
+ # Determines if the service requires SSL.
35
+ #
36
+ # @return [Boolean]
37
+ # Checks whether the `tunnel` XML attribute is `ssl`.
38
+ #
39
+ # @since 0.7.0
40
+ #
41
+ def ssl?
42
+ (@ssl ||= @node['tunnel']) == 'ssl'
43
+ end
44
+
45
+ #
46
+ # The application protocol used by the service.
47
+ #
48
+ # @return [String]
49
+ # The `proto` XML attribute.
50
+ #
51
+ # @since 0.7.0
52
+ #
53
+ def protocol
54
+ @protocol ||= @node['proto']
55
+ end
56
+
29
57
  #
30
58
  # The product of the service.
31
59
  #
@@ -46,6 +74,18 @@ module Nmap
46
74
  @version ||= @node.get_attribute('version')
47
75
  end
48
76
 
77
+ #
78
+ # The extra information from the service scan.
79
+ #
80
+ # @return [String]
81
+ # The `extrainfo` XML attribute.
82
+ #
83
+ # @since 0.7.0
84
+ #
85
+ def extra_info
86
+ @extra_info ||= @node['extrainfo']
87
+ end
88
+
49
89
  #
50
90
  # The hostname reported by the service.
51
91
  #
@@ -56,6 +96,30 @@ module Nmap
56
96
  @hostname ||= @node.get_attribute('hostname')
57
97
  end
58
98
 
99
+ #
100
+ # The reported OS type.
101
+ #
102
+ # @return [String]
103
+ # The `ostype` XML attribute.
104
+ #
105
+ # @since 0.7.0
106
+ #
107
+ def os_type
108
+ @os_type ||= @node['ostype']
109
+ end
110
+
111
+ #
112
+ # The reported device type.
113
+ #
114
+ # @return [String]
115
+ # The `devicetype` XML attribute.
116
+ #
117
+ # @since 0.7.0
118
+ #
119
+ def device_type
120
+ @device_type ||= @node['devicetype']
121
+ end
122
+
59
123
  #
60
124
  # The fingerprint method used to identify the service.
61
125
  #
@@ -66,6 +130,18 @@ module Nmap
66
130
  @fingerprint_method ||= @node.get_attribute('method').to_sym
67
131
  end
68
132
 
133
+ #
134
+ # The actual fingerprint
135
+ #
136
+ # @return [String]
137
+ # The fingerprint
138
+ #
139
+ # @since 0.7.0
140
+ #
141
+ def fingerprint
142
+ @fingerprint ||= @node.get_attribute('servicefp')
143
+ end
144
+
69
145
  #
70
146
  # The confidence score of the service fingerprinting.
71
147
  #
@@ -27,7 +27,7 @@ module Nmap
27
27
  # @since 0.5.0
28
28
  #
29
29
  def difficulty
30
- @node['difficulty']
30
+ @difficulty ||= @node['difficulty']
31
31
  end
32
32
 
33
33
  #
@@ -0,0 +1,67 @@
1
+ require 'nmap/hop'
2
+
3
+ module Nmap
4
+ #
5
+ # Wraps the `trace` XML element.
6
+ #
7
+ # @since 0.7.0
8
+ #
9
+ class Traceroute
10
+
11
+ include Enumerable
12
+
13
+ #
14
+ # Creates a new traceroute.
15
+ #
16
+ # @param [Nokogiri::XML::Element] node
17
+ # The `trace` XML element.
18
+ #
19
+ def initialize(node)
20
+ @node = node
21
+ end
22
+
23
+ #
24
+ # The port used for the traceroute.
25
+ #
26
+ # @return [Integer]
27
+ # The `port` XML attribute.
28
+ #
29
+ def port
30
+ @port ||= @node['port'].to_i
31
+ end
32
+
33
+ #
34
+ # The protocol used for the traceroute.
35
+ #
36
+ # @return [Symbol]
37
+ # The `proto` XML element.
38
+ #
39
+ def protocol
40
+ @protocol ||= @node['proto'].to_sym
41
+ end
42
+
43
+ #
44
+ # Parses the traceroute information for the host.
45
+ #
46
+ # @yield [hop]
47
+ # Each hop to the host.
48
+ #
49
+ # @yieldparam [Hop] hop
50
+ # A hop to the host.
51
+ #
52
+ # @return [Traceroute, Enumerator]
53
+ # The traceroute.
54
+ # If no block was given, an enumerator will be returned.
55
+ #
56
+ def each
57
+ return enum_for(__method__) unless block_given?
58
+
59
+ @node.xpath('hop').each do |hop|
60
+ yield Hop.new(hop['ipaddr'],hop['host'],hop['ttl'],hop['rtt'])
61
+ end
62
+
63
+ return self
64
+ end
65
+
66
+ end
67
+ end