ronin 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.gitignore +11 -0
  2. data/ChangeLog.md +28 -10
  3. data/Gemfile +1 -1
  4. data/README.md +14 -41
  5. data/Rakefile +3 -0
  6. data/gemspec.yml +14 -15
  7. data/lib/bond/completions/ronin.rb +0 -5
  8. data/lib/ronin/address.rb +17 -0
  9. data/lib/ronin/author.rb +1 -1
  10. data/lib/ronin/database/database.rb +11 -3
  11. data/lib/ronin/email_address.rb +33 -0
  12. data/lib/ronin/host_name.rb +57 -6
  13. data/lib/ronin/ip_address.rb +49 -5
  14. data/lib/ronin/license.rb +1 -1
  15. data/lib/ronin/mac_address.rb +39 -1
  16. data/lib/ronin/model/has_license.rb +12 -3
  17. data/lib/ronin/model/importable.rb +65 -0
  18. data/lib/ronin/repository.rb +12 -4
  19. data/lib/ronin/spec/database.rb +1 -1
  20. data/lib/ronin/tcp_port.rb +3 -12
  21. data/lib/ronin/udp_port.rb +2 -11
  22. data/lib/ronin/ui/cli/commands/emails.rb +0 -45
  23. data/lib/ronin/ui/cli/commands/hosts.rb +4 -31
  24. data/lib/ronin/ui/cli/commands/ips.rb +4 -30
  25. data/lib/ronin/ui/cli/commands/urls.rb +5 -45
  26. data/lib/ronin/ui/cli/model_command.rb +17 -27
  27. data/lib/ronin/ui/cli/resources_command.rb +25 -1
  28. data/lib/ronin/ui/cli/script_command.rb +1 -1
  29. data/lib/ronin/ui/console/context.rb +1 -1
  30. data/lib/ronin/url.rb +43 -1
  31. data/lib/ronin/version.rb +1 -1
  32. data/ronin.gemspec +1 -1
  33. data/spec/email_address_spec.rb +20 -0
  34. data/spec/host_name_spec.rb +20 -0
  35. data/spec/ip_address_spec.rb +104 -0
  36. data/spec/mac_address_spec.rb +20 -0
  37. data/spec/url_spec.rb +24 -0
  38. metadata +118 -155
  39. data/lib/ronin/network/mixins.rb +0 -27
  40. data/lib/ronin/network/mixins/esmtp.rb +0 -165
  41. data/lib/ronin/network/mixins/http.rb +0 -723
  42. data/lib/ronin/network/mixins/imap.rb +0 -151
  43. data/lib/ronin/network/mixins/pop3.rb +0 -141
  44. data/lib/ronin/network/mixins/smtp.rb +0 -159
  45. data/lib/ronin/network/mixins/tcp.rb +0 -331
  46. data/lib/ronin/network/mixins/telnet.rb +0 -199
  47. data/lib/ronin/network/mixins/udp.rb +0 -227
  48. data/lib/ronin/spec/ui/output.rb +0 -28
  49. data/lib/ronin/ui/output.rb +0 -21
  50. data/lib/ronin/ui/output/helpers.rb +0 -248
  51. data/lib/ronin/ui/output/output.rb +0 -146
  52. data/lib/ronin/ui/output/terminal.rb +0 -21
  53. data/lib/ronin/ui/output/terminal/color.rb +0 -118
  54. data/lib/ronin/ui/output/terminal/raw.rb +0 -103
  55. data/lib/ronin/ui/shell.rb +0 -92
  56. data/spec/ip_address.rb +0 -84
  57. data/spec/ui/output_spec.rb +0 -32
@@ -17,6 +17,9 @@
17
17
  # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
+ require 'ronin/extensions/ip_addr'
21
+ require 'ronin/extensions/resolv'
22
+ require 'ronin/model/importable'
20
23
  require 'ronin/address'
21
24
  require 'ronin/ip_address_mac_address'
22
25
  require 'ronin/host_name_ip_address'
@@ -24,7 +27,6 @@ require 'ronin/os'
24
27
  require 'ronin/open_port'
25
28
 
26
29
  require 'ipaddr'
27
- require 'resolv'
28
30
 
29
31
  module Ronin
30
32
  #
@@ -32,6 +34,8 @@ module Ronin
32
34
  #
33
35
  class IPAddress < Address
34
36
 
37
+ include Model::Importable
38
+
35
39
  # The IP Address
36
40
  property :address, Property::IPAddress, :required => true,
37
41
  :unique => true
@@ -75,6 +79,37 @@ module Ronin
75
79
  :model => 'OS',
76
80
  :via => :os
77
81
 
82
+ #
83
+ # Extracts and parses IP addresses from text.
84
+ #
85
+ # @param [String] text
86
+ # The text to parse.
87
+ #
88
+ # @param [Symbol, Integer] version
89
+ # Specifies whether to parse IPv4 or IPv6 addresses.
90
+ #
91
+ # @yield [ip]
92
+ # The given block will be passed each extracted IP address.
93
+ #
94
+ # @yieldparam [IPAddress] ip
95
+ # An extracted IP Address from the text.
96
+ #
97
+ # @see http://ronin-ruby.github.com/docs/ronin-support/IPAddr.html#extract-class_method
98
+ #
99
+ # @since 1.3.0
100
+ #
101
+ # @api public
102
+ #
103
+ def self.extract(text,version=nil)
104
+ return enum_for(:extract,text,version).to_a unless block_given?
105
+
106
+ IPAddr.extract(text,version) do |ip|
107
+ yield parse(ip)
108
+ end
109
+
110
+ return nil
111
+ end
112
+
78
113
  #
79
114
  # Searches for all IPv4 addresses.
80
115
  #
@@ -160,6 +195,9 @@ module Ronin
160
195
  # @param [String] name
161
196
  # The host name to look up.
162
197
  #
198
+ # @param [String] nameserver
199
+ # Optional nameserver to query.
200
+ #
163
201
  # @return [Array<IPAddress>]
164
202
  # The new or previously saved IP Addresses for the host name.
165
203
  #
@@ -167,10 +205,12 @@ module Ronin
167
205
  #
168
206
  # @api public
169
207
  #
170
- def self.lookup(name)
208
+ def self.lookup(name,nameserver=nil)
171
209
  host = HostName.first_or_new(:address => name)
210
+ resolver = Resolv.resolver(nameserver)
211
+
172
212
  ips = begin
173
- Resolv.getaddresses(name)
213
+ resolver.getaddresses(name)
174
214
  rescue
175
215
  []
176
216
  end
@@ -188,6 +228,9 @@ module Ronin
188
228
  #
189
229
  # Performs a reverse lookup on the IP address.
190
230
  #
231
+ # @param [String] nameserver
232
+ # Optional nameserver to query.
233
+ #
191
234
  # @return [Array<HostName>]
192
235
  # The host-names associated with the IP Address.
193
236
  #
@@ -195,9 +238,10 @@ module Ronin
195
238
  #
196
239
  # @api public
197
240
  #
198
- def lookup!
241
+ def lookup!(nameserver=nil)
242
+ resolver = Resolv.resolver(nameserver)
199
243
  hosts = begin
200
- Resolv.getnames(self.address.to_s)
244
+ resolver.getnames(self.address.to_s)
201
245
  rescue
202
246
  []
203
247
  end
data/lib/ronin/license.rb CHANGED
@@ -42,7 +42,7 @@ module Ronin
42
42
  property :description, Text, :required => true
43
43
 
44
44
  # URL of the License document
45
- property :url, String, :length => 256
45
+ property :url, URI, :length => 256
46
46
 
47
47
  # Berkeley Software Distribution License
48
48
  predefine :bsd,
@@ -17,10 +17,13 @@
17
17
  # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
+ require 'ronin/extensions/regexp'
20
21
  require 'ronin/address'
21
22
  require 'ronin/ip_address'
22
23
  require 'ronin/ip_address_mac_address'
23
24
 
25
+ require 'strscan'
26
+
24
27
  module Ronin
25
28
  #
26
29
  # Represents MAC addresses that can be stored in the {Database}.
@@ -30,7 +33,11 @@ module Ronin
30
33
  # The MAC address
31
34
  property :address, String, :length => 17..17,
32
35
  :required => true,
33
- :unique => true
36
+ :unique => true,
37
+ :format => /^#{Regexp::MAC}$/,
38
+ :messages => {
39
+ :format => 'Must be a valid MAC address'
40
+ }
34
41
 
35
42
  # The IP Addresses the MAC Address hosts
36
43
  has 0..n, :ip_address_mac_addresses, :model => 'IPAddressMACAddress'
@@ -39,6 +46,37 @@ module Ronin
39
46
  has 0..n, :ip_addresses, :through => :ip_address_mac_addresses,
40
47
  :model => 'IPAddress'
41
48
 
49
+ #
50
+ # Extracts MAC addresses from the given text.
51
+ #
52
+ # @param [String] text
53
+ # The text to parse.
54
+ #
55
+ # @yield [mac]
56
+ # The given block will be passed each extracted MAC address.
57
+ #
58
+ # @yieldparam [MACAddress] mac
59
+ # An extracted MAC Address
60
+ #
61
+ # @return [Array<MACAddress>]
62
+ # If no block is given, an Array of MACAddress will be returned.
63
+ #
64
+ # @see 1.3.0
65
+ #
66
+ # @api public
67
+ #
68
+ def self.extract(text)
69
+ return enum_for(:extract,text).to_a unless block_given?
70
+
71
+ scanner = StringScanner.new(text)
72
+
73
+ while scanner.skip_until(Regexp::MAC)
74
+ yield parse(scanner.matched)
75
+ end
76
+
77
+ return nil
78
+ end
79
+
42
80
  #
43
81
  # The IP Address that most recently used the MAC Address.
44
82
  #
@@ -105,15 +105,24 @@ module Ronin
105
105
  # The new license of the model.
106
106
  #
107
107
  # @example
108
- # license! :mit
108
+ # licensed_under :mit
109
109
  #
110
- # @since 1.0.0
110
+ # @since 1.3.0
111
111
  #
112
112
  # @api public
113
113
  #
114
- def license!(name)
114
+ def licensed_under(name)
115
115
  self.license = Ronin::License.predefined_resource(name)
116
116
  end
117
+
118
+ #
119
+ # @deprecated `license!` was deprecated in favor of {#licensed_under}.
120
+ #
121
+ # @since 1.0.0
122
+ #
123
+ def license!(name)
124
+ licensed_under(name)
125
+ end
117
126
  end
118
127
  end
119
128
  end
@@ -0,0 +1,65 @@
1
+ #
2
+ # Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
3
+ #
4
+ # This file is part of Ronin.
5
+ #
6
+ # Ronin is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Ronin is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ module Ronin
21
+ module Model
22
+ #
23
+ # Uses the `extract` method to extract and save resources from the
24
+ # contents of text-files.
25
+ #
26
+ # @since 1.3.0
27
+ #
28
+ module Importable
29
+ def self.included(base)
30
+ base.extend ClassMethods
31
+ end
32
+
33
+ module ClassMethods
34
+ #
35
+ # Extracts and imports resources from the given file.
36
+ #
37
+ # @param [String] path
38
+ # The path of the file.
39
+ #
40
+ # @yield [resource]
41
+ # The given block will be passed every imported resource.
42
+ #
43
+ # @yieldparam [Model] resource
44
+ # A successfully imported resource.
45
+ #
46
+ # @return [Array<Model>]
47
+ # If no block is given, an Array of imported resources is returned.
48
+ #
49
+ # @api public
50
+ #
51
+ def import(path)
52
+ return enum_for(:import,path).to_a unless block_given?
53
+
54
+ File.open(path) do |file|
55
+ file.each_line do |line|
56
+ extract(line) do |resource|
57
+ yield(resource) if resource.save
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -125,8 +125,12 @@ module Ronin
125
125
  # The path to the repository.
126
126
  #
127
127
  # @param [Symbol] scm
128
- # The SCM used by the repository. Can be either `:git`, `:mercurial`,
129
- # `:sub_version` or `:rsync`.
128
+ # The SCM used by the repository. Can be either:
129
+ #
130
+ # * `:git`
131
+ # * `:mercurial` / `:hg`
132
+ # * `:sub_version` / `:svn`
133
+ # * `:rsync`
130
134
  #
131
135
  # @param [String, URI::HTTP, URI::HTTPS] uri
132
136
  # The URI the repository resides at.
@@ -259,8 +263,12 @@ module Ronin
259
263
  # The URI to the repository.
260
264
  #
261
265
  # @option options [Symbol] :scm
262
- # The SCM used by the repository. May be either `:git`, `:mercurial`,
263
- # `:sub_version` or `:rsync`.
266
+ # The SCM used by the repository. May be either:
267
+ #
268
+ # * `:git`
269
+ # * `:mercurial` / `:hg`
270
+ # * `:sub_version` / `:svn`
271
+ # * `:rsync`
264
272
  #
265
273
  # @return [Repository]
266
274
  # The newly installed repository.
@@ -25,7 +25,7 @@ require 'tempfile'
25
25
  RSpec.configure do |spec|
26
26
  spec.before(:suite) do
27
27
  database_file = Tempfile.new('ronin_database').path
28
- database_uri = {:adapter => 'sqlite3', :database => database_file}
28
+ database_uri = {:adapter => 'sqlite3', :database => database_file}
29
29
 
30
30
  Ronin::Database.repositories[:default] = database_uri
31
31
 
@@ -26,21 +26,12 @@ module Ronin
26
26
  #
27
27
  class TCPPort < Port
28
28
 
29
+ # The protocol used for the port
30
+ property :protocol, String, :default => 'tcp'
31
+
29
32
  # The URLs that use the port
30
33
  has 0..n, :urls, :model => 'URL',
31
34
  :child_key => [:port_id]
32
35
 
33
- #
34
- # Creates a new {TCPPort} resource.
35
- #
36
- # @param [Hash] attributes
37
- # The attribute names and values to initialize the TCP port with.
38
- #
39
- # @api public
40
- #
41
- def initialize(attributes={})
42
- super(attributes.merge(:protocol => 'tcp'))
43
- end
44
-
45
36
  end
46
37
  end
@@ -25,17 +25,8 @@ module Ronin
25
25
  #
26
26
  class UDPPort < Port
27
27
 
28
- #
29
- # Creates a new {UDPPort} resource.
30
- #
31
- # @param [Hash] attributes
32
- # The attribute names and values to initialize the UDP port with.
33
- #
34
- # @api public
35
- #
36
- def initialize(attributes={})
37
- super(attributes.merge(:protocol => 'udp'))
38
- end
28
+ # The protocol used for the port
29
+ property :protocol, String, :default => 'tcp'
39
30
 
40
31
  end
41
32
  end
@@ -51,51 +51,6 @@ module Ronin
51
51
  :aliases => '-i',
52
52
  :banner => 'FILE'
53
53
 
54
- #
55
- # Queries the {EmailAddress} model.
56
- #
57
- # @since 1.0.0
58
- #
59
- def execute
60
- if options[:import]
61
- import options[:import]
62
- elsif options.list?
63
- super
64
- end
65
- end
66
-
67
- protected
68
-
69
- #
70
- # Imports email addresses from a file.
71
- #
72
- # @param [String] path
73
- # The path to the file.
74
- #
75
- # @since 1.0.0
76
- #
77
- def import(path)
78
- File.open(path) do |file|
79
- file.each_line do |line|
80
- line.strip!
81
- next if line.empty?
82
-
83
- email = begin
84
- EmailAddress.parse(line)
85
- rescue => e
86
- print_error e.message
87
- next
88
- end
89
-
90
- if email.save
91
- print_info "Imported #{email}"
92
- else
93
- print_error "Unable to import #{line.dump}."
94
- end
95
- end
96
- end
97
- end
98
-
99
54
  end
100
55
  end
101
56
  end
@@ -65,11 +65,9 @@ module Ronin
65
65
  # @since 1.0.0
66
66
  #
67
67
  def execute
68
- if options[:import]
69
- import options[:import]
70
- elsif options[:lookup]
68
+ if options[:lookup]
71
69
  lookup options[:lookup]
72
- elsif options.list?
70
+ else
73
71
  super
74
72
  end
75
73
  end
@@ -94,31 +92,6 @@ module Ronin
94
92
  print_info "Looked up #{ip}"
95
93
  end
96
94
 
97
- #
98
- # Imports host names from a file.
99
- #
100
- # @param [String] path
101
- # The path to the file.
102
- #
103
- # @since 1.0.0
104
- #
105
- def import(path)
106
- File.open(path) do |file|
107
- file.each_line do |line|
108
- line.strip!
109
- next if line.empty?
110
-
111
- host = HostName.new(:address => line)
112
-
113
- if host.save
114
- print_info "Imported #{host}"
115
- else
116
- print_error "Unable to import #{line.dump}."
117
- end
118
- end
119
- end
120
- end
121
-
122
95
  #
123
96
  # Prints a host name.
124
97
  #
@@ -134,11 +107,11 @@ module Ronin
134
107
 
135
108
  indent do
136
109
  if (org = host.organization)
137
- print_hash('Organization' => org)
110
+ print_hash 'Organization' => org
138
111
  end
139
112
 
140
113
  if (last_scanned_at = host.last_scanned_at)
141
- print_hash('Last Scanned' => last_scanned_at)
114
+ print_hash 'Last Scanned' => last_scanned_at
142
115
  end
143
116
 
144
117
  unless host.ip_addresses.empty?