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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8192a4dc58b09117d2aa6eb71a8a43440872f780
4
+ data.tar.gz: 605bb8d11e670acc42b90abdfd01bfeebd8cab1c
5
+ SHA512:
6
+ metadata.gz: 21b42a7d36d7aac99b722c38e80ff85646c1d677325ff6f480400a541ce8b9c9735dbbd58e227d13e321488458b30ae291783732955c70a784cd68481e6af7d9
7
+ data.tar.gz: 15ecfb499d538467f5d70c8ce5276a79852c4e04a50fd4a117d4c419ca75b54a415e3f822a29623cb8c406926004d04a9a05f3198c07fb25c9dd2b2012d2d3a4
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
+ Gemfile.lock
2
+ coverage
1
3
  doc
2
4
  pkg
3
5
  .DS_Store
@@ -6,3 +8,4 @@ pkg
6
8
  *.log
7
9
  *.swp
8
10
  *~
11
+ *.gem
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ before_install:
3
+ - sudo apt-get install libxml2-dev libxslt1-dev nmap
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - jruby-19mode
8
+ - rbx-19mode
9
+ matrix:
10
+ allow_failures:
11
+ - rvm: jruby-19mode
12
+ - rvm: rbx-19mode
13
+ script: rake test
@@ -1,3 +1,27 @@
1
+ ### 0.7.0 / 2014-05-09
2
+
3
+ * Added {Nmap::CPE}.
4
+ * Added {Nmap::CPE::URL}.
5
+ * Added {Nmap::Hop}.
6
+ * Added {Nmap::Hostname}.
7
+ * Added {Nmap::Traceroute}.
8
+ * Added {Nmap::Host#traceroute}.
9
+ * Added {Nmap::Host#uptime}. (@roodee)
10
+ * Added {Nmap::Service#ssl?}.
11
+ * Added {Nmap::Service#protocol}.
12
+ * Added {Nmap::Service#extra_info}.
13
+ * Added {Nmap::Service#os_type}.
14
+ * Added {Nmap::Service#device_type}.
15
+ * Added {Nmap::Service#fingerprint}. (@roodee)
16
+ * Added {Nmap::Uptime}. (@roodee)
17
+ * Added {Nmap::RunStat}. (@roodee)
18
+ * Added {Nmap::XML.load}. (@vzctl)
19
+ * Added {Nmap::XML.open}.
20
+ * Added {Nmap::XML#each_run_stat}.
21
+ * Added {Nmap::XML#run_stats}.
22
+ * Added {Nmap::XML#each_task}.
23
+ * Fixed xpath bug in {Nmap::OS#each_class} (@roodee).
24
+
1
25
  ### 0.6.0 / 2012-11-07
2
26
 
3
27
  * Added {Nmap::Service}.
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake', '~> 10.0'
7
+ gem 'rubygems-tasks', '~> 0.1'
8
+ gem 'rspec', '~> 2.4'
9
+ gem 'simplecov', '~> 0.7'
10
+ gem 'kramdown', '~> 1.0'
11
+ gem 'yard', '~> 0.7'
12
+ end
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2012 Postmodern
1
+ Copyright (c) 2009-2014 Postmodern
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -7,12 +7,12 @@
7
7
 
8
8
  ## Description
9
9
 
10
- A Ruby interface to Nmap, the exploration tool and security / port scanner.
10
+ A Ruby interface to [nmap], the exploration tool and security / port scanner.
11
11
 
12
12
  ## Features
13
13
 
14
- * Provides a Ruby interface for running Nmap.
15
- * Provides a Parser for enumerating Nmap XML scan files.
14
+ * Provides a Ruby interface for running nmap.
15
+ * Provides a Parser for enumerating nmap XML scan files.
16
16
 
17
17
  ## Examples
18
18
 
@@ -21,8 +21,6 @@ Run Nmap from Ruby:
21
21
  require 'nmap/program'
22
22
 
23
23
  Nmap::Program.scan do |nmap|
24
- nmap.sudo = true
25
-
26
24
  nmap.syn_scan = true
27
25
  nmap.service_scan = true
28
26
  nmap.os_fingerprint = true
@@ -73,9 +71,9 @@ Print NSE script output from an XML scan file:
73
71
 
74
72
  ## Requirements
75
73
 
76
- * [nmap](http://www.insecure.org/) >= 5.00
77
- * [nokogiri](http://nokogiri.rubyforge.org/) ~> 1.3
78
- * [rprogram](https://github.com/postmodern/rprogram#readme) ~> 0.3
74
+ * [nmap] >= 5.00
75
+ * [nokogiri] ~> 1.3
76
+ * [rprogram] ~> 0.3
79
77
 
80
78
  ## Install
81
79
 
@@ -83,6 +81,10 @@ Print NSE script output from an XML scan file:
83
81
 
84
82
  ## License
85
83
 
86
- Copyright (c) 2009-2012 Postmodern
84
+ Copyright (c) 2009-2014 Postmodern
87
85
 
88
86
  See {file:LICENSE.txt} for license information.
87
+
88
+ [nmap]: http://www.insecure.org/
89
+ [nokogiri]: http://nokogiri.rubyforge.org/
90
+ [rprogram]: https://github.com/postmodern/rprogram#readme
data/Rakefile CHANGED
@@ -1,40 +1,36 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'rubygems'
4
- require 'rake'
5
4
 
6
5
  begin
7
- gem 'rubygems-tasks', '~> 0.1'
8
- require 'rubygems/tasks'
9
-
10
- Gem::Tasks.new
6
+ require 'bundler/setup'
11
7
  rescue LoadError => e
12
8
  warn e.message
13
- warn "Run `gem install rubygems-tasks` to install 'rubygems/tasks'."
9
+ warn "Run `gem install bundler` to install Bundler"
10
+ exit -1
14
11
  end
15
12
 
16
- begin
17
- gem 'rspec', '~> 2.4'
18
- require 'rspec/core/rake_task'
13
+ require 'rake'
14
+ require 'rake/clean'
19
15
 
20
- RSpec::Core::RakeTask.new
21
- rescue LoadError => e
22
- task :spec do
23
- abort "Please run `gem install rspec` to install RSpec."
24
- end
25
- end
16
+ CLEAN.include('spec/*.xml')
17
+
18
+ require 'rubygems/tasks'
26
19
 
20
+ Gem::Tasks.new
21
+
22
+ require 'rspec/core/rake_task'
23
+ RSpec::Core::RakeTask.new
24
+
25
+ task :spec => 'spec/scan.xml'
27
26
  task :test => :spec
28
27
  task :default => :spec
29
28
 
30
- begin
31
- gem 'yard', '~> 0.7'
32
- require 'yard'
29
+ require 'yard'
30
+ YARD::Rake::YardocTask.new
31
+ task :doc => :yard
33
32
 
34
- YARD::Rake::YardocTask.new
35
- rescue LoadError => e
36
- task :yard do
37
- abort "Please run `gem install yard` to install YARD."
38
- end
33
+ file 'spec/scan.xml' do
34
+ puts ">>> Scanning scanme.nmap.org ..."
35
+ sh 'sudo nmap -v -sS -sU -A -O -oX spec/scan.xml scanme.nmap.org'
39
36
  end
40
- task :doc => :yard
@@ -17,6 +17,4 @@ dependencies:
17
17
  rprogram: ~> 0.3
18
18
 
19
19
  development_dependencies:
20
- rubygems-tasks: ~> 0.1
21
- rspec: ~> 2.4
22
- yard: ~> 0.7
20
+ bundler: ~> 1.0
@@ -0,0 +1,2 @@
1
+ require 'nmap/cpe/url'
2
+ require 'nmap/cpe/cpe'
@@ -0,0 +1,45 @@
1
+ require 'nmap/cpe/url'
2
+
3
+ module Nmap
4
+ #
5
+ # Mixins that adds methods for parsing [Common Platform Enumeration
6
+ # (CPE)][CPE] information.
7
+ #
8
+ # [CPE]: http://nmap.org/book/output-formats-cpe.html
9
+ #
10
+ # @since 0.7.0
11
+ #
12
+ module CPE
13
+ #
14
+ # Parses each Common Platform Enumeration (CPE) String.
15
+ #
16
+ # @yield [cpe]
17
+ # Passes each CPE URL to the given block.
18
+ #
19
+ # @yieldparam [URL] cpe
20
+ # The CPE URL.
21
+ #
22
+ # @return [Enumerator]
23
+ # If no block is given, an enumerator object will be returned.
24
+ #
25
+ def each_cpe
26
+ return enum_for(__method__) unless block_given?
27
+
28
+ @node.xpath('//cpe').each do |cpe|
29
+ yield URL.parse(cpe.inner_text)
30
+ end
31
+
32
+ return self
33
+ end
34
+
35
+ #
36
+ # Parses each Common Platform Enumeration (CPE) String.
37
+ #
38
+ # @return [Array<URL>]
39
+ # The CPE URLs.
40
+ #
41
+ def cpe
42
+ each_cpe.to_a
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,78 @@
1
+ module Nmap
2
+ module CPE
3
+ #
4
+ # Represets a [Common Platform Enumeration (CPE)][CPE] URL.
5
+ #
6
+ # [CPE]: http://nmap.org/book/output-formats-cpe.html
7
+ #
8
+ # @since 0.7.0
9
+ #
10
+ class URL < Struct.new(:part,:vendor,:product,:version,:update,:edition,
11
+ :language)
12
+
13
+ # CPE part codes
14
+ PARTS = {
15
+ '/a' => :application,
16
+ '/h' => :hardware,
17
+ '/o' => :os
18
+ }
19
+
20
+ #
21
+ # Parses a CPE URL.
22
+ #
23
+ # @param [String] url
24
+ # The raw URL.
25
+ #
26
+ # @return [URL]
27
+ # The parsed URL.
28
+ #
29
+ def self.parse(url)
30
+ scheme,
31
+ part,
32
+ vendor,
33
+ product,
34
+ version,
35
+ update,
36
+ edition,
37
+ language = url.split(':',8)
38
+
39
+ unless scheme == 'cpe'
40
+ raise(ArgumentError,"CPE URLs must begin with 'cpe:'")
41
+ end
42
+
43
+ vendor = vendor.to_sym
44
+ product = product.to_sym
45
+ language = language.to_sym if language
46
+
47
+ return new(
48
+ PARTS[part],
49
+ vendor,
50
+ product,
51
+ version,
52
+ update,
53
+ edition,
54
+ language
55
+ )
56
+ end
57
+
58
+ #
59
+ # Converts the CPE URL back into a String.
60
+ #
61
+ # @return [String]
62
+ # The raw CPE URL.
63
+ #
64
+ def to_s
65
+ 'cpe:' + [
66
+ PARTS.invert[part],
67
+ vendor,
68
+ product,
69
+ version,
70
+ update,
71
+ edition,
72
+ language
73
+ ].compact.join(':')
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,20 @@
1
+ module Nmap
2
+ #
3
+ # Represents a hop in a traceroute.
4
+ #
5
+ # @since 0.7.0
6
+ #
7
+ class Hop < Struct.new(:addr, :host, :ttl, :rtt)
8
+
9
+ #
10
+ # Converts the hop to a String.
11
+ #
12
+ # @return [String]
13
+ # The IP address of the hop.
14
+ #
15
+ def to_s
16
+ self.addr.to_s
17
+ end
18
+
19
+ end
20
+ end
@@ -1,12 +1,16 @@
1
1
  require 'nmap/status'
2
2
  require 'nmap/address'
3
+ require 'nmap/hostname'
3
4
  require 'nmap/os'
4
5
  require 'nmap/port'
5
6
  require 'nmap/ip_id_sequence'
6
7
  require 'nmap/tcp_sequence'
7
8
  require 'nmap/tcp_ts_sequence'
9
+ require 'nmap/uptime'
10
+ require 'nmap/traceroute'
8
11
 
9
12
  require 'nokogiri'
13
+ require 'time'
10
14
 
11
15
  module Nmap
12
16
  #
@@ -22,17 +26,8 @@ module Nmap
22
26
  # @param [Nokogiri::XML::Node] node
23
27
  # The XML node that contains the host information.
24
28
  #
25
- # @yield [host]
26
- # If a block is given, it will be passed the newly created Host
27
- # object.
28
- #
29
- # @yieldparam [Host] host
30
- # The newly created Host object.
31
- #
32
29
  def initialize(node)
33
30
  @node = node
34
-
35
- yield self if block_given?
36
31
  end
37
32
 
38
33
  #
@@ -123,7 +118,7 @@ module Nmap
123
118
  # The MAC address of the host.
124
119
  #
125
120
  def mac
126
- @mac ||= if (addr = @node.xpath("address[@addrtype='mac']").first)
121
+ @mac ||= if (addr = @node.at("address[@addrtype='mac']"))
127
122
  addr['addr']
128
123
  end
129
124
  end
@@ -135,7 +130,7 @@ module Nmap
135
130
  # The IPv4 address of the host.
136
131
  #
137
132
  def ipv4
138
- @ipv4 ||= if (addr = @node.xpath("address[@addrtype='ipv4']").first)
133
+ @ipv4 ||= if (addr = @node.at("address[@addrtype='ipv4']"))
139
134
  addr['addr']
140
135
  end
141
136
  end
@@ -147,7 +142,7 @@ module Nmap
147
142
  # The IPv6 address of the host.
148
143
  #
149
144
  def ipv6
150
- @ipv6 ||= if (@node.xpath("address[@addrtype='ipv6']").first)
145
+ @ipv6 ||= if (@node.at("address[@addrtype='ipv6']"))
151
146
  addr['addr']
152
147
  end
153
148
  end
@@ -178,7 +173,7 @@ module Nmap
178
173
  # @yield [host]
179
174
  # Each parsed hostname will be passed to the given block.
180
175
  #
181
- # @yieldparam [String] host
176
+ # @yieldparam [Hostname] host
182
177
  # A hostname of the host.
183
178
  #
184
179
  # @return [Host, Enumerator]
@@ -189,7 +184,7 @@ module Nmap
189
184
  return enum_for(__method__) unless block_given?
190
185
 
191
186
  @node.xpath("hostnames/hostname[@name]").each do |host|
192
- yield host['name']
187
+ yield Hostname.new(host['type'],host['name'])
193
188
  end
194
189
 
195
190
  return self
@@ -198,7 +193,7 @@ module Nmap
198
193
  #
199
194
  # Parses the hostnames of the host.
200
195
  #
201
- # @return [Array<String>]
196
+ # @return [Array<Hostname>]
202
197
  # The hostnames of the host.
203
198
  #
204
199
  def hostnames
@@ -225,6 +220,32 @@ module Nmap
225
220
  yield @os if (@os && block_given?)
226
221
  return @os
227
222
  end
223
+
224
+ #
225
+ # Parses the Uptime analysis of the host.
226
+ #
227
+ # @yield [uptime]
228
+ # If a block is given, it will be passed the resulting object
229
+ #
230
+ # @yieldparam [Uptime]
231
+ # Uptime value.
232
+ #
233
+ # @return [Uptime]
234
+ # The parsed object.
235
+ #
236
+ # @since 0.7.0
237
+ #
238
+ def uptime
239
+ @uptime ||= if (uptime = @node.at('uptime'))
240
+ Uptime.new(
241
+ uptime['seconds'].to_i,
242
+ Time.parse(uptime['lastboot'])
243
+ )
244
+ end
245
+
246
+ yield @uptime if (@uptime && block_given?)
247
+ return @uptime
248
+ end
228
249
 
229
250
  #
230
251
  # Parses the Tcp Sequence number analysis of the host.
@@ -477,6 +498,29 @@ module Nmap
477
498
  return @scripts
478
499
  end
479
500
 
501
+ #
502
+ # Parses the traceroute information, if present.
503
+ #
504
+ # @yield [traceroute]
505
+ # If a block is given, it will be passed the traceroute information.
506
+ #
507
+ # @yieldparam [Traceroute] traceroute
508
+ # The traceroute information.
509
+ #
510
+ # @return [Traceroute]
511
+ # The traceroute information.
512
+ #
513
+ # @since 0.7.0
514
+ #
515
+ def traceroute
516
+ @traceroute ||= if (trace = @node.at('trace'))
517
+ Traceroute.new(trace)
518
+ end
519
+
520
+ yield @traceroute if (@traceroute && block_given?)
521
+ return @traceroute
522
+ end
523
+
480
524
  #
481
525
  # Converts the host to a String.
482
526
  #
@@ -489,5 +533,15 @@ module Nmap
489
533
  address.to_s
490
534
  end
491
535
 
536
+ #
537
+ # Inspects the host.
538
+ #
539
+ # @return [String]
540
+ # The inspected host.
541
+ #
542
+ def inspect
543
+ "#<#{self.class}: #{self}>"
544
+ end
545
+
492
546
  end
493
547
  end