ruby-nmap 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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