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/lib/nmap/program.rb
CHANGED
data/lib/nmap/scan.rb
CHANGED
@@ -1,14 +1,8 @@
|
|
1
1
|
module Nmap
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# The protocol used for the scan
|
8
|
-
attr_reader :protocol
|
9
|
-
|
10
|
-
# The port numbers that were scanned
|
11
|
-
attr_reader :services
|
2
|
+
#
|
3
|
+
# Represents an Nmap scan.
|
4
|
+
#
|
5
|
+
class Scan < Struct.new(:type, :protocol, :services)
|
12
6
|
|
13
7
|
#
|
14
8
|
# Creates a new Scan object.
|
@@ -23,9 +17,7 @@ module Nmap
|
|
23
17
|
# The port numbers scanned.
|
24
18
|
#
|
25
19
|
def initialize(type,protocol,services=[])
|
26
|
-
|
27
|
-
@protocol = protocol
|
28
|
-
@services = services
|
20
|
+
super(type,protocol,services)
|
29
21
|
end
|
30
22
|
|
31
23
|
#
|
@@ -35,7 +27,7 @@ module Nmap
|
|
35
27
|
# The String form of the scan.
|
36
28
|
#
|
37
29
|
def to_s
|
38
|
-
"#{
|
30
|
+
"#{self.protocol} #{self.type}"
|
39
31
|
end
|
40
32
|
|
41
33
|
end
|
data/lib/nmap/scanner.rb
CHANGED
@@ -1,39 +1,8 @@
|
|
1
1
|
module Nmap
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# The version of the scanner
|
8
|
-
attr_reader :version
|
9
|
-
|
10
|
-
# The arguments used with the scanner
|
11
|
-
attr_reader :arguments
|
12
|
-
|
13
|
-
# The time the scan begun
|
14
|
-
attr_reader :start_time
|
15
|
-
|
16
|
-
#
|
17
|
-
# Creates a new Scanner object.
|
18
|
-
#
|
19
|
-
# @param [String] name
|
20
|
-
# The name of the scanner.
|
21
|
-
#
|
22
|
-
# @param [String] version
|
23
|
-
# The version of the scanner.
|
24
|
-
#
|
25
|
-
# @param [String] arguments
|
26
|
-
# The arguments used with the scanner.
|
27
|
-
#
|
28
|
-
# @param [Time] start_time
|
29
|
-
# The time the scan begun
|
30
|
-
#
|
31
|
-
def initialize(name,version,arguments,start_time)
|
32
|
-
@name = name
|
33
|
-
@version = version
|
34
|
-
@arguments = arguments
|
35
|
-
@start_time = start_time
|
36
|
-
end
|
2
|
+
#
|
3
|
+
# Describes the `nmap` command.
|
4
|
+
#
|
5
|
+
class Scanner < Struct.new(:name, :version, :arguments, :start_time)
|
37
6
|
|
38
7
|
#
|
39
8
|
# Converts the scanner to a String.
|
@@ -42,7 +11,7 @@ module Nmap
|
|
42
11
|
# The scanner name and arguments.
|
43
12
|
#
|
44
13
|
def to_s
|
45
|
-
"#{
|
14
|
+
"#{self.name} #{self.arguments}"
|
46
15
|
end
|
47
16
|
|
48
17
|
end
|
data/lib/nmap/sequence.rb
CHANGED
data/lib/nmap/service.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
module Nmap
|
2
|
+
#
|
3
|
+
# Wraps a `service` XML element.
|
4
|
+
#
|
5
|
+
# @since 0.6.0
|
6
|
+
#
|
7
|
+
class Service
|
8
|
+
|
9
|
+
#
|
10
|
+
# Creates a new OS object.
|
11
|
+
#
|
12
|
+
# @param [Nokogiri::XML::Node] node
|
13
|
+
# The node that contains the OS guessing information.
|
14
|
+
#
|
15
|
+
def initialize(node)
|
16
|
+
@node = node
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# The name of the service.
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
# The service name.
|
24
|
+
#
|
25
|
+
def name
|
26
|
+
@name ||= @node.get_attribute('name')
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# The product of the service.
|
31
|
+
#
|
32
|
+
# @return [String]
|
33
|
+
# The product name.
|
34
|
+
#
|
35
|
+
def product
|
36
|
+
@product ||= @node.get_attribute('product')
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# The version of the service.
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
# The service version.
|
44
|
+
#
|
45
|
+
def version
|
46
|
+
@version ||= @node.get_attribute('version')
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# The hostname reported by the service.
|
51
|
+
#
|
52
|
+
# @return [String]
|
53
|
+
# The reported hostname.
|
54
|
+
#
|
55
|
+
def hostname
|
56
|
+
@hostname ||= @node.get_attribute('hostname')
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# The fingerprint method used to identify the service.
|
61
|
+
#
|
62
|
+
# @return [Symbol]
|
63
|
+
# The fingerprint method.
|
64
|
+
#
|
65
|
+
def fingerprint_method
|
66
|
+
@fingerprint_method ||= @node.get_attribute('method').to_sym
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# The confidence score of the service fingerprinting.
|
71
|
+
#
|
72
|
+
# @return [Integer]
|
73
|
+
# The confidence score.
|
74
|
+
#
|
75
|
+
def confidence
|
76
|
+
@confidence ||= @node.get_attribute('conf').to_i
|
77
|
+
end
|
78
|
+
|
79
|
+
alias to_s name
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
data/lib/nmap/status.rb
CHANGED
@@ -1,25 +1,8 @@
|
|
1
1
|
module Nmap
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# The reason for the state
|
8
|
-
attr_reader :reason
|
9
|
-
|
10
|
-
#
|
11
|
-
# Creates a new Status object.
|
12
|
-
#
|
13
|
-
# @param [Symbol] state
|
14
|
-
# The state of a host.
|
15
|
-
#
|
16
|
-
# @param [String] reason
|
17
|
-
# The reason for the state.
|
18
|
-
#
|
19
|
-
def initialize(state,reason)
|
20
|
-
@state = state
|
21
|
-
@reason = reason
|
22
|
-
end
|
2
|
+
#
|
3
|
+
# Represents the Status of a {Host}.
|
4
|
+
#
|
5
|
+
class Status < Struct.new(:state, :reason)
|
23
6
|
|
24
7
|
#
|
25
8
|
# Converts the status to a String.
|
@@ -28,7 +11,7 @@ module Nmap
|
|
28
11
|
# The state.
|
29
12
|
#
|
30
13
|
def to_s
|
31
|
-
|
14
|
+
self.state.to_s
|
32
15
|
end
|
33
16
|
|
34
17
|
end
|
data/lib/nmap/tcp_sequence.rb
CHANGED
data/lib/nmap/tcp_ts_sequence.rb
CHANGED
data/lib/nmap/version.rb
CHANGED
data/lib/nmap/xml.rb
CHANGED
@@ -6,6 +6,9 @@ require 'nmap/host'
|
|
6
6
|
require 'nokogiri'
|
7
7
|
|
8
8
|
module Nmap
|
9
|
+
#
|
10
|
+
# Represents an Nmap XML file.
|
11
|
+
#
|
9
12
|
class XML
|
10
13
|
|
11
14
|
include Enumerable
|
@@ -27,7 +30,7 @@ module Nmap
|
|
27
30
|
#
|
28
31
|
def initialize(path)
|
29
32
|
@path = File.expand_path(path)
|
30
|
-
@doc = Nokogiri::XML(
|
33
|
+
@doc = Nokogiri::XML(open(@path))
|
31
34
|
|
32
35
|
yield self if block_given?
|
33
36
|
end
|
@@ -134,7 +137,7 @@ module Nmap
|
|
134
137
|
# be returned.
|
135
138
|
#
|
136
139
|
def each_host(&block)
|
137
|
-
return enum_for(
|
140
|
+
return enum_for(__method__) unless block
|
138
141
|
|
139
142
|
@doc.xpath('/nmaprun/host').each do |host|
|
140
143
|
Host.new(host,&block)
|
@@ -167,7 +170,7 @@ module Nmap
|
|
167
170
|
# be returned.
|
168
171
|
#
|
169
172
|
def each_up_host(&block)
|
170
|
-
return enum_for(
|
173
|
+
return enum_for(__method__) unless block
|
171
174
|
|
172
175
|
@doc.xpath("/nmaprun/host[status[@state='up']]").each do |host|
|
173
176
|
Host.new(host,&block)
|
data/spec/host_spec.rb
CHANGED
@@ -1,38 +1,31 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'helpers/xml'
|
3
2
|
|
4
3
|
require 'nmap/xml'
|
5
4
|
require 'nmap/host'
|
6
5
|
|
7
6
|
describe Host do
|
8
|
-
|
7
|
+
let(:xml) { XML.new(Helpers::SCAN_FILE) }
|
9
8
|
|
10
|
-
|
11
|
-
@xml = XML.new(Helpers::SCAN_FILE)
|
12
|
-
@nse_xml = XML.new(Helpers::NSE_FILE)
|
13
|
-
|
14
|
-
@host = @xml.hosts.first
|
15
|
-
@nse_host = @nse_xml.hosts.first
|
16
|
-
end
|
9
|
+
subject { xml.hosts.first }
|
17
10
|
|
18
11
|
it "should parse the start_time" do
|
19
|
-
|
12
|
+
subject.start_time.should > Time.at(0)
|
20
13
|
end
|
21
14
|
|
22
15
|
it "should parse the end_time" do
|
23
|
-
|
24
|
-
|
16
|
+
subject.end_time.should > Time.at(0)
|
17
|
+
subject.end_time.should > subject.start_time
|
25
18
|
end
|
26
19
|
|
27
20
|
it "should parse the status" do
|
28
|
-
status =
|
21
|
+
status = subject.status
|
29
22
|
|
30
23
|
status.state.should == :up
|
31
24
|
status.reason.should == 'arp-response'
|
32
25
|
end
|
33
26
|
|
34
27
|
it "should parse the addresses" do
|
35
|
-
addresses =
|
28
|
+
addresses = subject.addresses
|
36
29
|
|
37
30
|
addresses.length.should == 2
|
38
31
|
|
@@ -44,11 +37,11 @@ describe Host do
|
|
44
37
|
end
|
45
38
|
|
46
39
|
it "should parse the MAC address" do
|
47
|
-
|
40
|
+
subject.mac.should == '00:1D:7E:EF:2A:E5'
|
48
41
|
end
|
49
42
|
|
50
43
|
it "should parse the IPv4 address" do
|
51
|
-
|
44
|
+
subject.ipv4.should == '192.168.5.1'
|
52
45
|
end
|
53
46
|
|
54
47
|
it "should parse the IPv6 address" do
|
@@ -56,11 +49,11 @@ describe Host do
|
|
56
49
|
end
|
57
50
|
|
58
51
|
it "should have an IP" do
|
59
|
-
|
52
|
+
subject.ip.should == '192.168.5.1'
|
60
53
|
end
|
61
54
|
|
62
55
|
it "should have an address" do
|
63
|
-
|
56
|
+
subject.address.should == '192.168.5.1'
|
64
57
|
end
|
65
58
|
|
66
59
|
it "should parse the hostnames" do
|
@@ -68,24 +61,24 @@ describe Host do
|
|
68
61
|
end
|
69
62
|
|
70
63
|
it "should parse the OS guessing information" do
|
71
|
-
|
64
|
+
subject.os.should_not be_nil
|
72
65
|
end
|
73
66
|
|
74
67
|
it "should parse the ports" do
|
75
|
-
ports =
|
68
|
+
ports = subject.ports
|
76
69
|
|
77
70
|
ports.length.should == 3
|
78
71
|
end
|
79
72
|
|
80
73
|
it "should list the open ports" do
|
81
|
-
ports =
|
74
|
+
ports = subject.open_ports
|
82
75
|
|
83
76
|
ports.length.should == 1
|
84
77
|
ports.all? { |port| port.state == :open }.should == true
|
85
78
|
end
|
86
79
|
|
87
80
|
it "should list TCP ports" do
|
88
|
-
ports =
|
81
|
+
ports = subject.tcp_ports
|
89
82
|
|
90
83
|
ports.length.should == 3
|
91
84
|
ports.all? { |port| port.protocol == :tcp }.should == true
|
@@ -96,13 +89,19 @@ describe Host do
|
|
96
89
|
end
|
97
90
|
|
98
91
|
it "should convert to a String" do
|
99
|
-
|
92
|
+
subject.to_s.should == '192.168.5.1'
|
100
93
|
end
|
101
94
|
|
102
|
-
|
103
|
-
|
95
|
+
context "when NSE scripts are ran" do
|
96
|
+
let(:xml) { XML.new(Helpers::NSE_FILE) }
|
97
|
+
|
98
|
+
subject { xml.hosts.first }
|
99
|
+
|
100
|
+
it "should list output of the scripts" do
|
101
|
+
subject.scripts.should_not be_empty
|
104
102
|
|
105
|
-
|
106
|
-
|
103
|
+
subject.scripts.keys.should_not include(nil)
|
104
|
+
subject.scripts.values.should_not include(nil)
|
105
|
+
end
|
107
106
|
end
|
108
107
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'nmap/ip_id_sequence'
|
3
|
+
|
4
|
+
describe IpIdSequence do
|
5
|
+
let(:xml) { XML.new(Helpers::SCAN_FILE) }
|
6
|
+
|
7
|
+
subject { xml.hosts.first.ip_id_sequence }
|
8
|
+
|
9
|
+
it "should be accessible from host objects" do
|
10
|
+
subject.should be_kind_of(IpIdSequence)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should parse the description" do
|
14
|
+
subject.description.should == "Incremental"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should parse the values" do
|
18
|
+
subject.values.should == [0x1FB0, 0x1FB2, 0x1FB4, 0x1FB6, 0x1FB8, 0x1FBA]
|
19
|
+
end
|
20
|
+
end
|