ruby-nmap 0.5.1 → 0.6.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.
- data/ChangeLog.md +8 -0
- data/README.md +1 -1
- data/lib/nmap/address.rb +5 -22
- data/lib/nmap/host.rb +78 -45
- data/lib/nmap/ip_id_sequence.rb +6 -1
- data/lib/nmap/os.rb +5 -2
- data/lib/nmap/os_class.rb +5 -36
- data/lib/nmap/os_match.rb +5 -22
- data/lib/nmap/port.rb +12 -5
- data/lib/nmap/program.rb +3 -0
- data/lib/nmap/scan.rb +6 -14
- data/lib/nmap/scanner.rb +5 -36
- data/lib/nmap/sequence.rb +5 -0
- data/lib/nmap/service.rb +82 -0
- data/lib/nmap/status.rb +5 -22
- data/lib/nmap/tcp_sequence.rb +5 -0
- data/lib/nmap/tcp_ts_sequence.rb +3 -0
- data/lib/nmap/version.rb +1 -1
- data/lib/nmap/xml.rb +6 -3
- data/spec/host_spec.rb +26 -27
- data/spec/ip_id_sequence_spec.rb +20 -0
- data/spec/nmap_spec.rb +1 -1
- data/spec/os_spec.rb +6 -11
- data/spec/port_spec.rb +15 -20
- data/spec/service_spec.rb +40 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/task_spec.rb +0 -2
- data/spec/tcp_sequence_spec.rb +31 -0
- data/spec/tcp_ts_sequence_spec.rb +20 -0
- data/spec/xml_spec.rb +13 -19
- metadata +11 -4
- data/spec/sequence_spec.rb +0 -75
data/ChangeLog.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
### 0.6.0 / 2012-11-07
|
2
|
+
|
3
|
+
* Added {Nmap::Service}.
|
4
|
+
* Renamed `Nmap::IpidSequence` to {Nmap::IpIdSequence}.
|
5
|
+
* Renamed {Nmap::Host#ipidsequence} to {Nmap::Host#ip_id_sequence}.
|
6
|
+
* Renamed {Nmap::Host#tcpsequence} to {Nmap::Host#tcp_sequence}.
|
7
|
+
* Renamed {Nmap::Host#tcptssequence} to {Nmap::Host#tcp_ts_sequence}.
|
8
|
+
|
1
9
|
### 0.5.1 / 2012-05-27
|
2
10
|
|
3
11
|
* Replaced ore-tasks with
|
data/README.md
CHANGED
@@ -75,7 +75,7 @@ Print NSE script output from an XML scan file:
|
|
75
75
|
|
76
76
|
* [nmap](http://www.insecure.org/) >= 5.00
|
77
77
|
* [nokogiri](http://nokogiri.rubyforge.org/) ~> 1.3
|
78
|
-
* [rprogram](https://github.com/postmodern/rprogram) ~> 0.3
|
78
|
+
* [rprogram](https://github.com/postmodern/rprogram#readme) ~> 0.3
|
79
79
|
|
80
80
|
## Install
|
81
81
|
|
data/lib/nmap/address.rb
CHANGED
@@ -1,25 +1,8 @@
|
|
1
1
|
module Nmap
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# Address
|
8
|
-
attr_reader :addr
|
9
|
-
|
10
|
-
#
|
11
|
-
# Creates a new Address object.
|
12
|
-
#
|
13
|
-
# @param [Symbol] type
|
14
|
-
# The type of the address.
|
15
|
-
#
|
16
|
-
# @param [String] addr
|
17
|
-
# The address.
|
18
|
-
#
|
19
|
-
def initialize(type,addr)
|
20
|
-
@type = type
|
21
|
-
@addr = addr
|
22
|
-
end
|
2
|
+
#
|
3
|
+
# Represents a IP or MAC address.
|
4
|
+
#
|
5
|
+
class Address < Struct.new(:type, :addr)
|
23
6
|
|
24
7
|
#
|
25
8
|
# Converts the address to a String.
|
@@ -28,7 +11,7 @@ module Nmap
|
|
28
11
|
# The address.
|
29
12
|
#
|
30
13
|
def to_s
|
31
|
-
|
14
|
+
self.addr.to_s
|
32
15
|
end
|
33
16
|
|
34
17
|
end
|
data/lib/nmap/host.rb
CHANGED
@@ -9,6 +9,9 @@ require 'nmap/tcp_ts_sequence'
|
|
9
9
|
require 'nokogiri'
|
10
10
|
|
11
11
|
module Nmap
|
12
|
+
#
|
13
|
+
# Wraps a `host` XML element.
|
14
|
+
#
|
12
15
|
class Host
|
13
16
|
|
14
17
|
include Enumerable
|
@@ -89,7 +92,7 @@ module Nmap
|
|
89
92
|
# If no block was given, an enumerator will be returned.
|
90
93
|
#
|
91
94
|
def each_address
|
92
|
-
return enum_for(
|
95
|
+
return enum_for(__method__) unless block_given?
|
93
96
|
|
94
97
|
@node.xpath("address[@addr]").each do |addr|
|
95
98
|
address = Address.new(
|
@@ -120,13 +123,9 @@ module Nmap
|
|
120
123
|
# The MAC address of the host.
|
121
124
|
#
|
122
125
|
def mac
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
@mac = addr['addr'] if addr
|
127
|
-
end
|
128
|
-
|
129
|
-
return @mac
|
126
|
+
@mac ||= if (addr = @node.xpath("address[@addrtype='mac']").first)
|
127
|
+
addr['addr']
|
128
|
+
end
|
130
129
|
end
|
131
130
|
|
132
131
|
#
|
@@ -136,13 +135,9 @@ module Nmap
|
|
136
135
|
# The IPv4 address of the host.
|
137
136
|
#
|
138
137
|
def ipv4
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
@ipv4 = addr['addr'] if addr
|
143
|
-
end
|
144
|
-
|
145
|
-
return @ipv4
|
138
|
+
@ipv4 ||= if (addr = @node.xpath("address[@addrtype='ipv4']").first)
|
139
|
+
addr['addr']
|
140
|
+
end
|
146
141
|
end
|
147
142
|
|
148
143
|
#
|
@@ -152,13 +147,9 @@ module Nmap
|
|
152
147
|
# The IPv6 address of the host.
|
153
148
|
#
|
154
149
|
def ipv6
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
@ipv6 = addr['addr'] if addr
|
159
|
-
end
|
160
|
-
|
161
|
-
return @ipv6
|
150
|
+
@ipv6 ||= if (@node.xpath("address[@addrtype='ipv6']").first)
|
151
|
+
addr['addr']
|
152
|
+
end
|
162
153
|
end
|
163
154
|
|
164
155
|
#
|
@@ -195,7 +186,7 @@ module Nmap
|
|
195
186
|
# If no block was given, an enumerator will be returned.
|
196
187
|
#
|
197
188
|
def each_hostname
|
198
|
-
return enum_for(
|
189
|
+
return enum_for(__method__) unless block_given?
|
199
190
|
|
200
191
|
@node.xpath("hostnames/hostname[@name]").each do |host|
|
201
192
|
yield host['name']
|
@@ -226,46 +217,76 @@ module Nmap
|
|
226
217
|
# @return [OS]
|
227
218
|
# The OS guessing information.
|
228
219
|
#
|
229
|
-
def os
|
230
|
-
if (os = @node.at('os'))
|
231
|
-
|
232
|
-
|
220
|
+
def os
|
221
|
+
@os ||= if (os = @node.at('os'))
|
222
|
+
OS.new(os)
|
223
|
+
end
|
224
|
+
|
225
|
+
yield @os if (@os && block_given?)
|
226
|
+
return @os
|
233
227
|
end
|
234
228
|
|
229
|
+
#
|
235
230
|
# Parses the Tcp Sequence number analysis of the host.
|
236
231
|
#
|
237
|
-
# @yield [
|
232
|
+
# @yield [sequence]
|
238
233
|
# If a block is given, it will be passed the resulting object
|
239
234
|
#
|
240
|
-
# @yieldparam [TcpSequence]
|
235
|
+
# @yieldparam [TcpSequence] sequence
|
241
236
|
# Tcp Sequence number analysis.
|
242
237
|
#
|
243
238
|
# @return [TcpSequence]
|
244
239
|
# The parsed object.
|
245
240
|
#
|
241
|
+
def tcp_sequence
|
242
|
+
@tcp_sequence ||= if (seq = @node.at('tcpsequence'))
|
243
|
+
TcpSequence.new(seq)
|
244
|
+
end
|
245
|
+
|
246
|
+
yield @tcp_sequence if (@tcp_sequence && block_given?)
|
247
|
+
return @tcp_sequence
|
248
|
+
end
|
249
|
+
|
250
|
+
#
|
251
|
+
# @deprecated Use {#tcp_sequence} instead.
|
252
|
+
#
|
246
253
|
def tcpsequence(&block)
|
247
|
-
|
248
|
-
|
249
|
-
|
254
|
+
warn "DEPRECATION: use #{self.class}#tcp_sequence instead"
|
255
|
+
|
256
|
+
tcp_sequence(&block)
|
250
257
|
end
|
251
258
|
|
259
|
+
#
|
252
260
|
# Parses the IPID sequence number analysis of the host.
|
253
261
|
#
|
254
262
|
# @yield [ipidsequence]
|
255
263
|
# If a block is given, it will be passed the resulting object
|
256
264
|
#
|
257
|
-
# @yieldparam [
|
265
|
+
# @yieldparam [IpIdSequence] ipidsequence
|
258
266
|
# IPID Sequence number analysis.
|
259
267
|
#
|
260
|
-
# @return [
|
268
|
+
# @return [IpIdSequence]
|
261
269
|
# The parsed object.
|
262
270
|
#
|
271
|
+
def ip_id_sequence
|
272
|
+
@ip_id_sequence ||= if (seq = @node.at('ipidsequence'))
|
273
|
+
IpIdSequence.new(seq)
|
274
|
+
end
|
275
|
+
|
276
|
+
yield @ip_id_sequence if (@ip_id_sequence && block_given?)
|
277
|
+
return @ip_id_sequence
|
278
|
+
end
|
279
|
+
|
280
|
+
#
|
281
|
+
# @deprecated Use {#ip_id_sequence} instead.
|
282
|
+
#
|
263
283
|
def ipidsequence(&block)
|
264
|
-
|
265
|
-
|
266
|
-
|
284
|
+
warn "DEPRECATION: use #{self.class}#ip_id_sequence instead"
|
285
|
+
|
286
|
+
ip_id_sequence(&block)
|
267
287
|
end
|
268
288
|
|
289
|
+
#
|
269
290
|
# Parses the TCP Timestamp sequence number analysis of the host.
|
270
291
|
#
|
271
292
|
# @yield [tcptssequence]
|
@@ -277,10 +298,22 @@ module Nmap
|
|
277
298
|
# @return [TcpTsSequence]
|
278
299
|
# The parsed object.
|
279
300
|
#
|
301
|
+
def tcp_ts_sequence
|
302
|
+
@tcp_ts_sequence ||= if (seq = @node.at('tcptssequence'))
|
303
|
+
TcpTsSequence.new(seq)
|
304
|
+
end
|
305
|
+
|
306
|
+
yield @tcp_ts_sequence if (@tcp_ts_sequence && block_given?)
|
307
|
+
return @tcp_ts_sequence
|
308
|
+
end
|
309
|
+
|
310
|
+
#
|
311
|
+
# @deprecated Use {#tcp_ts_sequence} instead.
|
312
|
+
#
|
280
313
|
def tcptssequence(&block)
|
281
|
-
|
282
|
-
|
283
|
-
|
314
|
+
warn "DEPRECATION: use #{self.class}#tcp_ts_sequence instead"
|
315
|
+
|
316
|
+
tcp_ts_sequence(&block)
|
284
317
|
end
|
285
318
|
|
286
319
|
#
|
@@ -297,7 +330,7 @@ module Nmap
|
|
297
330
|
# If no block was given, an enumerator will be returned.
|
298
331
|
#
|
299
332
|
def each_port
|
300
|
-
return enum_for(
|
333
|
+
return enum_for(__method__) unless block_given?
|
301
334
|
|
302
335
|
@node.xpath("ports/port").each do |port|
|
303
336
|
yield Port.new(port)
|
@@ -329,8 +362,8 @@ module Nmap
|
|
329
362
|
# The host.
|
330
363
|
# If no block was given, an enumerator will be returned.
|
331
364
|
#
|
332
|
-
def each_open_port
|
333
|
-
return enum_for(
|
365
|
+
def each_open_port
|
366
|
+
return enum_for(__method__) unless block_given?
|
334
367
|
|
335
368
|
@node.xpath("ports/port[state/@state='open']").each do |port|
|
336
369
|
yield Port.new(port)
|
@@ -363,7 +396,7 @@ module Nmap
|
|
363
396
|
# If no block was given, an enumerator will be returned.
|
364
397
|
#
|
365
398
|
def each_tcp_port
|
366
|
-
return enum_for(
|
399
|
+
return enum_for(__method__) unless block_given?
|
367
400
|
|
368
401
|
@node.xpath("ports/port[@protocol='tcp']").each do |port|
|
369
402
|
yield Port.new(port)
|
@@ -396,7 +429,7 @@ module Nmap
|
|
396
429
|
# If no block was given, an enumerator will be returned.
|
397
430
|
#
|
398
431
|
def each_udp_port
|
399
|
-
return enum_for(
|
432
|
+
return enum_for(__method__) unless block_given?
|
400
433
|
|
401
434
|
@node.xpath("ports/port[@protocol='udp']").each do |port|
|
402
435
|
yield Port.new(port)
|
data/lib/nmap/ip_id_sequence.rb
CHANGED
data/lib/nmap/os.rb
CHANGED
@@ -2,6 +2,9 @@ require 'nmap/os_class'
|
|
2
2
|
require 'nmap/os_match'
|
3
3
|
|
4
4
|
module Nmap
|
5
|
+
#
|
6
|
+
# Wraps the `os` XML element.
|
7
|
+
#
|
5
8
|
class OS
|
6
9
|
|
7
10
|
include Enumerable
|
@@ -38,7 +41,7 @@ module Nmap
|
|
38
41
|
# will be returned.
|
39
42
|
#
|
40
43
|
def each_class
|
41
|
-
return enum_for(
|
44
|
+
return enum_for(__method__) unless block_given?
|
42
45
|
|
43
46
|
@node.xpath("osclass").map do |osclass|
|
44
47
|
os_class = OSClass.new(
|
@@ -78,7 +81,7 @@ module Nmap
|
|
78
81
|
# will be returned.
|
79
82
|
#
|
80
83
|
def each_match
|
81
|
-
return enum_for(
|
84
|
+
return enum_for(__method__) unless block_given?
|
82
85
|
|
83
86
|
@node.xpath("osmatch").map do |osclass|
|
84
87
|
os_match = OSMatch.new(
|
data/lib/nmap/os_class.rb
CHANGED
@@ -1,39 +1,8 @@
|
|
1
1
|
module Nmap
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# The OS vendor
|
8
|
-
attr_reader :vendor
|
9
|
-
|
10
|
-
# The family of the OS
|
11
|
-
attr_reader :family
|
12
|
-
|
13
|
-
# The accuracy of the OS guess
|
14
|
-
attr_reader :accuracy
|
15
|
-
|
16
|
-
#
|
17
|
-
# Creates a new OSClass object.
|
18
|
-
#
|
19
|
-
# @param [Symbol] type
|
20
|
-
# The class of the OS.
|
21
|
-
#
|
22
|
-
# @param [String] vendor
|
23
|
-
# The vendor of the OS.
|
24
|
-
#
|
25
|
-
# @param [String] family
|
26
|
-
# The family of the OS.
|
27
|
-
#
|
28
|
-
# @param [Integer] accuracy
|
29
|
-
# The accuracy of the OS guess.
|
30
|
-
#
|
31
|
-
def initialize(type,vendor,family,accuracy)
|
32
|
-
@type = type
|
33
|
-
@vendor = vendor
|
34
|
-
@family = family
|
35
|
-
@accuracy = accuracy
|
36
|
-
end
|
2
|
+
#
|
3
|
+
# Represents an {OS} class.
|
4
|
+
#
|
5
|
+
class OSClass < Struct.new(:type, :vendor, :family, :accuracy)
|
37
6
|
|
38
7
|
#
|
39
8
|
# Converts the OS class to a String.
|
@@ -42,7 +11,7 @@ module Nmap
|
|
42
11
|
# The String form of the OS class.
|
43
12
|
#
|
44
13
|
def to_s
|
45
|
-
"#{
|
14
|
+
"#{self.type} #{self.vendor} (#{self.accuracy}%)"
|
46
15
|
end
|
47
16
|
|
48
17
|
end
|
data/lib/nmap/os_match.rb
CHANGED
@@ -1,25 +1,8 @@
|
|
1
1
|
module Nmap
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# The accuracy of the OS guess
|
8
|
-
attr_reader :accuracy
|
9
|
-
|
10
|
-
#
|
11
|
-
# Creates a OSMatch object.
|
12
|
-
#
|
13
|
-
# @param [String] name
|
14
|
-
# The name of the OS.
|
15
|
-
#
|
16
|
-
# @param [Integer] accuracy
|
17
|
-
# The accuracy of the OS guess.
|
18
|
-
#
|
19
|
-
def initialize(name,accuracy)
|
20
|
-
@name = name
|
21
|
-
@accuracy = accuracy
|
22
|
-
end
|
2
|
+
#
|
3
|
+
# Represents a match for a specific {OS}.
|
4
|
+
#
|
5
|
+
class OSMatch < Struct.new(:name, :accuracy)
|
23
6
|
|
24
7
|
#
|
25
8
|
# Converts the OS match to a String.
|
@@ -28,7 +11,7 @@ module Nmap
|
|
28
11
|
# The String form of the OS match.
|
29
12
|
#
|
30
13
|
def to_s
|
31
|
-
"#{
|
14
|
+
"#{self.name} (#{self.accuracy}%)"
|
32
15
|
end
|
33
16
|
|
34
17
|
end
|
data/lib/nmap/port.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
+
require 'nmap/service'
|
2
|
+
|
1
3
|
module Nmap
|
4
|
+
#
|
5
|
+
# Wraps a `port` XML element.
|
6
|
+
#
|
2
7
|
class Port
|
3
8
|
|
4
9
|
#
|
@@ -52,15 +57,17 @@ module Nmap
|
|
52
57
|
end
|
53
58
|
|
54
59
|
#
|
55
|
-
# The service the port
|
60
|
+
# The fingerprinted service of the port.
|
56
61
|
#
|
57
|
-
# @return [
|
62
|
+
# @return [Service]
|
58
63
|
# The service detected on the port.
|
59
64
|
#
|
65
|
+
# @since 0.6.0
|
66
|
+
#
|
60
67
|
def service
|
61
|
-
@
|
62
|
-
|
63
|
-
|
68
|
+
@service_info ||= if (service = @node.at('service'))
|
69
|
+
Service.new(service)
|
70
|
+
end
|
64
71
|
end
|
65
72
|
|
66
73
|
#
|