ronin 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/ChangeLog.md +23 -0
  2. data/README.md +19 -13
  3. data/Rakefile +2 -1
  4. data/gemspec.yml +18 -17
  5. data/lib/bond/completions/ronin.rb +147 -0
  6. data/lib/ronin/auto_load.rb +30 -28
  7. data/lib/ronin/database/migrations/1.0.0.rb +1 -0
  8. data/lib/ronin/model/has_authors.rb +92 -2
  9. data/lib/ronin/model/has_description.rb +54 -2
  10. data/lib/ronin/model/has_license.rb +101 -2
  11. data/lib/ronin/model/has_name.rb +72 -2
  12. data/lib/ronin/model/has_title.rb +52 -2
  13. data/lib/ronin/model/has_unique_name.rb +93 -2
  14. data/lib/ronin/model/has_version.rb +58 -2
  15. data/lib/ronin/model/model.rb +91 -52
  16. data/lib/ronin/os.rb +30 -15
  17. data/lib/ronin/repository.rb +1 -1
  18. data/lib/ronin/ronin.rb +0 -15
  19. data/lib/ronin/script/script.rb +257 -2
  20. data/lib/ronin/ui/console.rb +2 -199
  21. data/lib/ronin/ui/console/commands.rb +164 -0
  22. data/lib/ronin/ui/console/console.rb +215 -0
  23. data/lib/ronin/ui/console/context.rb +95 -0
  24. data/lib/ronin/version.rb +1 -1
  25. data/spec/os_spec.rb +18 -13
  26. metadata +206 -239
  27. data/lib/ronin/class_methods.rb +0 -49
  28. data/lib/ronin/model/class_methods.rb +0 -58
  29. data/lib/ronin/model/has_authors/class_methods.rb +0 -60
  30. data/lib/ronin/model/has_authors/has_authors.rb +0 -70
  31. data/lib/ronin/model/has_description/class_methods.rb +0 -49
  32. data/lib/ronin/model/has_description/has_description.rb +0 -49
  33. data/lib/ronin/model/has_license/class_methods.rb +0 -68
  34. data/lib/ronin/model/has_license/has_license.rb +0 -71
  35. data/lib/ronin/model/has_name/class_methods.rb +0 -48
  36. data/lib/ronin/model/has_name/has_name.rb +0 -62
  37. data/lib/ronin/model/has_title/class_methods.rb +0 -48
  38. data/lib/ronin/model/has_title/has_title.rb +0 -48
  39. data/lib/ronin/model/has_unique_name/class_methods.rb +0 -51
  40. data/lib/ronin/model/has_unique_name/has_unique_name.rb +0 -78
  41. data/lib/ronin/model/has_version/class_methods.rb +0 -54
  42. data/lib/ronin/model/has_version/has_version.rb +0 -48
  43. data/lib/ronin/script/class_methods.rb +0 -84
  44. data/lib/ronin/script/instance_methods.rb +0 -217
@@ -17,7 +17,6 @@
17
17
  # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
- require 'ronin/model/class_methods'
21
20
  require 'ronin/model/types'
22
21
  require 'ronin/support/inflector'
23
22
 
@@ -51,74 +50,114 @@ module Ronin
51
50
  base.send :include, DataMapper,
52
51
  DataMapper::Migrations,
53
52
  DataMapper::Serialize,
54
- Model::Types
55
- base.send :extend, Model::ClassMethods
53
+ Model::Types,
54
+ InstanceMethods
55
+ base.send :extend, ClassMethods
56
56
  end
57
57
 
58
58
  #
59
- # Formats the attributes of the model into human readable names
60
- # and values.
59
+ # Class methods that are added when {Model} is included into a class.
61
60
  #
62
- # @param [Hash] options
63
- # Additional options.
64
- #
65
- # @option options [Array<Symbol>] :exclude ([])
66
- # A list of attribute names to exclude.
67
- #
68
- # @yield [name, value]
69
- # If a block is given, it will be passed the name and humanized
70
- # value of each attribute.
71
- #
72
- # @yieldparam [String] name
73
- # The humanized name of the attribute.
74
- #
75
- # @yieldparam [String] value
76
- # The human readable value of the attribute.
77
- #
78
- # @return [Hash{String => String}]
79
- # A hash of the humanly readable names and values of the attributes.
80
- #
81
- # @api semipublic
82
- #
83
- def humanize_attributes(options={})
84
- exclude = [:id, :type]
61
+ module ClassMethods
62
+ #
63
+ # The default name to use when defining relationships with the
64
+ # model.
65
+ #
66
+ # @return [Symbol]
67
+ # The name to use in relationships.
68
+ #
69
+ # @since 1.0.0
70
+ #
71
+ # @api semipublic
72
+ #
73
+ def relationship_name
74
+ name = Support::Inflector.underscore(self.name.split('::').last)
75
+
76
+ return Support::Inflector.pluralize(name).to_sym
77
+ end
78
+
79
+ #
80
+ # Loads and initialize the resources.
81
+ #
82
+ # @api private
83
+ #
84
+ def load(records,query)
85
+ resources = super(records,query)
86
+ resources.each { |resource| resource.send :initialize }
85
87
 
86
- if options[:exclude]
87
- exclude += options[:exclude]
88
+ return resources
88
89
  end
90
+ end
89
91
 
90
- formatter = lambda { |value|
91
- if value.kind_of?(Array)
92
- value.map(&formatter).join(', ')
93
- elsif value.kind_of?(Symbol)
94
- Support::Inflector.humanize(value)
95
- else
96
- value.to_s
92
+ #
93
+ # Instance methods that are added when {Model} is included into a class.
94
+ #
95
+ module InstanceMethods
96
+ #
97
+ # Formats the attributes of the model into human readable names
98
+ # and values.
99
+ #
100
+ # @param [Hash] options
101
+ # Additional options.
102
+ #
103
+ # @option options [Array<Symbol>] :exclude ([])
104
+ # A list of attribute names to exclude.
105
+ #
106
+ # @yield [name, value]
107
+ # If a block is given, it will be passed the name and humanized
108
+ # value of each attribute.
109
+ #
110
+ # @yieldparam [String] name
111
+ # The humanized name of the attribute.
112
+ #
113
+ # @yieldparam [String] value
114
+ # The human readable value of the attribute.
115
+ #
116
+ # @return [Hash{String => String}]
117
+ # A hash of the humanly readable names and values of the attributes.
118
+ #
119
+ # @api semipublic
120
+ #
121
+ def humanize_attributes(options={})
122
+ exclude = [:id, :type]
123
+
124
+ if options[:exclude]
125
+ exclude += options[:exclude]
97
126
  end
98
- }
99
127
 
100
- formatted = {}
128
+ formatter = lambda { |value|
129
+ if value.kind_of?(Array)
130
+ value.map(&formatter).join(', ')
131
+ elsif value.kind_of?(Symbol)
132
+ Support::Inflector.humanize(value)
133
+ else
134
+ value.to_s
135
+ end
136
+ }
137
+
138
+ formatted = {}
101
139
 
102
- self.attributes.each do |name,value|
103
- next if (value.nil? || (value.respond_to?(:empty?) && value.empty?))
140
+ self.attributes.each do |name,value|
141
+ next if (value.nil? || (value.respond_to?(:empty?) && value.empty?))
104
142
 
105
- unless (exclude.include?(name) || value.nil?)
106
- name = name.to_s
143
+ unless (exclude.include?(name) || value.nil?)
144
+ name = name.to_s
107
145
 
108
- unless name[-3..-1] == '_id'
109
- name = Support::Inflector.humanize(name)
110
- value = formatter.call(value)
146
+ unless name[-3..-1] == '_id'
147
+ name = Support::Inflector.humanize(name)
148
+ value = formatter.call(value)
111
149
 
112
- if block_given?
113
- yield name, value
114
- end
150
+ if block_given?
151
+ yield name, value
152
+ end
115
153
 
116
- formatted[name] = value
154
+ formatted[name] = value
155
+ end
117
156
  end
118
157
  end
119
- end
120
158
 
121
- return formatted
159
+ return formatted
160
+ end
122
161
  end
123
162
  end
124
163
  end
data/lib/ronin/os.rb CHANGED
@@ -23,6 +23,8 @@ require 'ronin/os_guess'
23
23
  require 'ronin/ip_address'
24
24
  require 'ronin/extensions/meta'
25
25
 
26
+ require 'dm-is-predefined'
27
+
26
28
  module Ronin
27
29
  #
28
30
  # Represents an Operating System and pre-defines other common ones
@@ -34,6 +36,8 @@ module Ronin
34
36
  include Model
35
37
  include Model::HasName
36
38
 
39
+ is :predefined
40
+
37
41
  # Primary key
38
42
  property :id, Serial
39
43
 
@@ -127,14 +131,25 @@ module Ronin
127
131
  #
128
132
  # @api private
129
133
  #
130
- def OS.predefine(name,os_name)
131
- os_name = os_name.to_s
134
+ def OS.predefine(name,attributes)
135
+ unless attributes[:name]
136
+ raise(ArgumentError,"must specify the :name attribute")
137
+ end
138
+
139
+ super(name,attributes)
140
+
141
+ # if no version was predefined, allow the predefined helper-methods
142
+ # to accept a version argument
143
+ unless attributes[:version]
144
+ os_name = attributes[:name]
145
+
146
+ meta_def(name) do |*arguments|
147
+ attributes = predefined_attributes[name]
148
+ version = if arguments.first
149
+ arguments.first.to_s
150
+ end
132
151
 
133
- meta_def(name) do |*arguments|
134
- if (version = arguments.first)
135
- OS.first_or_create(:name => os_name, :version => version.to_s)
136
- else
137
- OS.new(:name => os_name)
152
+ OS.first_or_create(attributes.merge(:version => version))
138
153
  end
139
154
  end
140
155
 
@@ -142,28 +157,28 @@ module Ronin
142
157
  end
143
158
 
144
159
  # The Linux OS
145
- predefine :linux, 'Linux'
160
+ predefine :linux, :name => 'Linux'
146
161
 
147
162
  # The FreeBSD OS
148
- predefine :freebsd, 'FreeBSD'
163
+ predefine :freebsd, :name => 'FreeBSD'
149
164
 
150
165
  # The OpenBSD OS
151
- predefine :openbsd, 'OpenBSD'
166
+ predefine :openbsd, :name => 'OpenBSD'
152
167
 
153
168
  # The NetBSD OS
154
- predefine :netbsd, 'NetBSD'
169
+ predefine :netbsd, :name => 'NetBSD'
155
170
 
156
171
  # OSX
157
- predefine :osx, 'OSX'
172
+ predefine :osx, :name => 'OSX'
158
173
 
159
174
  # The Solaris OS
160
- predefine :solaris, 'Solaris'
175
+ predefine :solaris, :name => 'Solaris'
161
176
 
162
177
  # The Windows OS
163
- predefine :windows, 'Windows'
178
+ predefine :windows, :name => 'Windows'
164
179
 
165
180
  # The family UNIX OSes
166
- predefine :unix, 'UNIX'
181
+ predefine :unix, :name => 'UNIX'
167
182
 
168
183
  end
169
184
  end
@@ -723,7 +723,7 @@ module Ronin
723
723
  end
724
724
 
725
725
  if (license = metadata['license'])
726
- self.license = License.predefined_resource_with(:name => license)
726
+ self.license = License.first_or_predefined(:name => license)
727
727
  end
728
728
 
729
729
  if (uri = metadata['uri'])
data/lib/ronin/ronin.rb CHANGED
@@ -17,26 +17,11 @@
17
17
  # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
- require 'ronin/class_methods'
21
20
  require 'ronin/auto_load'
22
21
 
23
22
  module Ronin
24
23
  include AutoLoad
25
24
 
26
- #
27
- # Includes {ClassMethods} when {Ronin} is included.
28
- #
29
- # @param [Class, Module] base
30
- # The class or module that {Ronin} is being included into.
31
- #
32
- # @since 1.0.0
33
- #
34
- # @api private
35
- #
36
- def self.included(base)
37
- base.send :extend, ClassMethods
38
- end
39
-
40
25
  #
41
26
  # Convenience method for loading Ronin {Script}s.
42
27
  #
@@ -17,8 +17,6 @@
17
17
  # along with Ronin. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
- require 'ronin/script/instance_methods'
21
- require 'ronin/script/class_methods'
22
20
  require 'ronin/script/path'
23
21
  require 'ronin/model/model'
24
22
  require 'ronin/model/has_name'
@@ -90,6 +88,263 @@ module Ronin
90
88
  Path.has 1, base.relationship_name, base, :child_key => [:script_path_id]
91
89
  end
92
90
 
91
+ #
92
+ # @since 1.1.0
93
+ #
94
+ module ClassMethods
95
+ #
96
+ # Loads the {Script} of the same class.
97
+ #
98
+ # @param [String] path
99
+ # The path to load the script from.
100
+ #
101
+ # @return [Script]
102
+ # The loaded script.
103
+ #
104
+ # @example
105
+ # Exploits::HTTP.load_from('mod_php_exploit.rb')
106
+ # # => #<Ronin::Exploits::HTTP: ...>
107
+ #
108
+ # @since 1.1.0
109
+ #
110
+ def load_from(path)
111
+ load_object(path)
112
+ end
113
+
114
+ #
115
+ # Loads all objects with the matching attributes.
116
+ #
117
+ # @param [Hash] attributes
118
+ # Attributes to search for.
119
+ #
120
+ # @since 1.1.0
121
+ #
122
+ # @api public
123
+ #
124
+ def load_all(attributes={})
125
+ resources = all(attributes)
126
+ resources.each { |resource| resource.load_script! }
127
+
128
+ return resources
129
+ end
130
+
131
+ #
132
+ # Loads the first object with matching attributes.
133
+ #
134
+ # @param [Hash] attributes
135
+ # Attributes to search for.
136
+ #
137
+ # @return [Cacheable]
138
+ # The loaded cached objects.
139
+ #
140
+ # @since 1.1.0
141
+ #
142
+ # @api public
143
+ #
144
+ def load_first(attributes={})
145
+ if (resource = first(attributes))
146
+ resource.load_script!
147
+ end
148
+
149
+ return resource
150
+ end
151
+ end
152
+
153
+ #
154
+ # Instance methods for an {Script}.
155
+ #
156
+ # @since 1.1.0
157
+ #
158
+ module InstanceMethods
159
+ #
160
+ # Initializes the Ronin Script.
161
+ #
162
+ # @param [Array] arguments
163
+ # Arguments for initializing the Script.
164
+ #
165
+ # @since 1.1.0
166
+ #
167
+ # @api semipublic
168
+ #
169
+ def initialize(*arguments,&block)
170
+ @script_loaded = false
171
+ @cache_prepared = false
172
+
173
+ if arguments.first.kind_of?(Hash)
174
+ initialize_params(arguments.first)
175
+ end
176
+
177
+ super(*arguments,&block)
178
+ end
179
+
180
+ #
181
+ # The script type.
182
+ #
183
+ # @return [String]
184
+ # The name of the script class.
185
+ #
186
+ # @since 1.1.0
187
+ #
188
+ # @api semipublic
189
+ #
190
+ def script_type
191
+ @script_type ||= self.class.base_model.name.split('::').last
192
+ end
193
+
194
+ #
195
+ # Determines if the original code, from the cache file, has been
196
+ # loaded into the object.
197
+ #
198
+ # @return [Boolean]
199
+ # Specifies whether the original code has been loaded into the
200
+ # object.
201
+ #
202
+ # @since 1.1.0
203
+ #
204
+ # @api private
205
+ #
206
+ def script_loaded?
207
+ @script_loaded == true
208
+ end
209
+
210
+ #
211
+ # Loads the code from the cached file for the object, and instance
212
+ # evaluates it into the object.
213
+ #
214
+ # @return [Boolean]
215
+ # Indicates the original code was successfully loaded.
216
+ #
217
+ # @since 1.1.0
218
+ #
219
+ # @api private
220
+ #
221
+ def load_script!
222
+ if (cached? && !script_loaded?)
223
+ block = self.class.load_object_block(self.script_path.path)
224
+
225
+ @script_loaded = true
226
+ instance_eval(&block) if block
227
+ return true
228
+ end
229
+
230
+ return false
231
+ end
232
+
233
+ #
234
+ # @return [Boolean]
235
+ # Specifies whether the object has been prepared to be cached,
236
+ #
237
+ # @since 1.1.0
238
+ #
239
+ # @api private
240
+ #
241
+ def prepared_for_cache?
242
+ @cache_prepared == true
243
+ end
244
+
245
+ #
246
+ # Indicates whether the object has been cached.
247
+ #
248
+ # @return [Boolean]
249
+ # Specifies whether the object has been previously cached.
250
+ #
251
+ # @since 1.1.0
252
+ #
253
+ # @api private
254
+ #
255
+ def cached?
256
+ (saved? && self.script_path)
257
+ end
258
+
259
+ #
260
+ # Default method which invokes the script.
261
+ #
262
+ # @param [Array] arguments
263
+ # Optional arguments.
264
+ #
265
+ # @since 1.1.0
266
+ #
267
+ def run(*arguments)
268
+ end
269
+
270
+ #
271
+ # Converts the script to a String.
272
+ #
273
+ # @return [String]
274
+ # The name and version of the script.
275
+ #
276
+ # @since 1.1.0
277
+ #
278
+ # @api public
279
+ #
280
+ def to_s
281
+ if (self.name && self.version)
282
+ "#{self.name} #{self.version}"
283
+ elsif self.name
284
+ super
285
+ elsif self.version
286
+ self.version.to_s
287
+ end
288
+ end
289
+
290
+ #
291
+ # Inspects both the properties and parameters of the Ronin Script.
292
+ #
293
+ # @return [String]
294
+ # The inspected Ronin Script.
295
+ #
296
+ # @since 1.1.0
297
+ #
298
+ # @api public
299
+ #
300
+ def inspect
301
+ body = []
302
+
303
+ self.attributes.each do |name,value|
304
+ body << "#{name}: #{value.inspect}"
305
+ end
306
+
307
+ param_pairs = []
308
+
309
+ self.params.each do |name,param|
310
+ param_pairs << "#{name}: #{param.value.inspect}"
311
+ end
312
+
313
+ body << "params: {#{param_pairs.join(', ')}}"
314
+
315
+ return "#<#{self.class}: #{body.join(', ')}>"
316
+ end
317
+
318
+ protected
319
+
320
+ #
321
+ # Will call the given block only once, in order to prepare the
322
+ # object for caching.
323
+ #
324
+ # @yield []
325
+ # The block will be ran inside the object when the object is to be
326
+ # prepared for caching.
327
+ #
328
+ # @return [Boolean]
329
+ # Specifies whether the object was successfully prepared for
330
+ # caching.
331
+ #
332
+ # @since 1.1.0
333
+ #
334
+ # @api public
335
+ #
336
+ def cache
337
+ if (block_given? && !(cached? || prepared_for_cache?))
338
+ @cache_prepared = true
339
+
340
+ yield
341
+ return true
342
+ end
343
+
344
+ return false
345
+ end
346
+ end
347
+
93
348
  #
94
349
  # Loads a script from a file.
95
350
  #