ronin-exploits 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.txt +27 -0
  3. data/Manifest.txt +21 -5
  4. data/README.txt +40 -3
  5. data/Rakefile +6 -6
  6. data/TODO.txt +12 -9
  7. data/lib/ronin/exploits/allow.rb +1 -1
  8. data/lib/ronin/{targeted_arch.rb → exploits/arch.rb} +1 -5
  9. data/lib/ronin/exploits/exploit.rb +59 -144
  10. data/lib/ronin/exploits/ftp.rb +4 -1
  11. data/lib/ronin/exploits/helpers.rb +1 -0
  12. data/lib/ronin/exploits/helpers/file_based.rb +113 -0
  13. data/lib/ronin/exploits/http.rb +10 -0
  14. data/lib/ronin/exploits/license.rb +34 -0
  15. data/lib/ronin/exploits/os.rb +34 -0
  16. data/lib/ronin/{targeted_product.rb → exploits/product.rb} +1 -1
  17. data/lib/ronin/exploits/remote_tcp.rb +2 -3
  18. data/lib/ronin/exploits/remote_udp.rb +2 -3
  19. data/lib/ronin/exploits/target.rb +8 -10
  20. data/lib/ronin/exploits/verifiers.rb +92 -0
  21. data/lib/ronin/exploits/version.rb +1 -1
  22. data/lib/ronin/exploits/web.rb +21 -1
  23. data/lib/ronin/model/has_default_port.rb +54 -0
  24. data/lib/ronin/model/targets_arch.rb +8 -10
  25. data/lib/ronin/model/targets_os.rb +9 -9
  26. data/lib/ronin/payloads.rb +1 -0
  27. data/lib/ronin/payloads/arch.rb +32 -0
  28. data/lib/ronin/payloads/asm_payload.rb +34 -0
  29. data/lib/ronin/payloads/encoder.rb +24 -18
  30. data/lib/ronin/payloads/helpers/exceptions.rb +2 -1
  31. data/lib/ronin/payloads/helpers/exceptions/{unimplemented.rb → not_implemented.rb} +1 -1
  32. data/lib/ronin/payloads/helpers/file_system.rb +12 -12
  33. data/lib/ronin/payloads/helpers/rpc.rb +7 -7
  34. data/lib/ronin/payloads/helpers/shell.rb +2 -2
  35. data/lib/ronin/payloads/license.rb +34 -0
  36. data/lib/ronin/payloads/nops.rb +3 -1
  37. data/lib/ronin/{targeted_os.rb → payloads/os.rb} +1 -5
  38. data/lib/ronin/payloads/payload.rb +89 -41
  39. data/lib/ronin/payloads/shellcode.rb +4 -1
  40. data/lib/ronin/ui/command_line/commands/exploits.rb +1 -1
  41. data/lib/ronin/ui/command_line/commands/payload.rb +2 -2
  42. data/lib/ronin/ui/command_line/commands/payloads.rb +1 -1
  43. data/spec/exploits/exploit_spec.rb +12 -30
  44. data/spec/exploits/file_based_exploit_spec.rb +39 -0
  45. data/spec/exploits/ftp_spec.rb +1 -5
  46. data/spec/exploits/http_spec.rb +4 -4
  47. data/spec/exploits/remote_tcp_spec.rb +7 -3
  48. data/spec/exploits/remote_udp_spec.rb +7 -3
  49. data/spec/exploits/target_spec.rb +9 -2
  50. data/spec/exploits/targets/buffer_overflow_spec.rb +6 -2
  51. data/spec/exploits/web_spec.rb +6 -0
  52. data/spec/model/has_default_port_spec.rb +27 -0
  53. data/spec/model/models/default_port_model.rb +13 -0
  54. data/spec/model/models/non_default_port_model.rb +11 -0
  55. data/spec/model/models/targets_arch_model.rb +11 -0
  56. data/spec/model/models/targets_os_model.rb +11 -0
  57. data/spec/model/targets_arch_spec.rb +22 -0
  58. data/spec/model/targets_os_spec.rb +23 -0
  59. data/spec/objects/exploits/example.rb +25 -0
  60. data/spec/objects/exploits/test.rb +0 -4
  61. data/spec/objects/payloads/test.rb +5 -1
  62. data/spec/payloads/encoder_spec.rb +5 -1
  63. data/spec/payloads/payload_spec.rb +77 -14
  64. metadata +58 -13
  65. metadata.gz.sig +0 -0
  66. data/spec/objects/payloads/example.rb +0 -19
@@ -21,7 +21,7 @@
21
21
  #++
22
22
  #
23
23
 
24
- require 'ronin/payloads/helpers/exceptions/unimplemented'
24
+ require 'ronin/payloads/helpers/exceptions/not_implemented'
25
25
  require 'ronin/payloads/helpers/exceptions/program_not_found'
26
26
 
27
27
  module Ronin
@@ -40,7 +40,7 @@ module Ronin
40
40
  # Executes the specified _command_ with the given _arguments_.
41
41
  #
42
42
  def exec(command,*arguments)
43
- raise(Unimplemented,"the exec method has not been implemented",caller)
43
+ raise(NotImplemented,"the exec method has not been implemented",caller)
44
44
  end
45
45
 
46
46
  #
@@ -0,0 +1,34 @@
1
+ #
2
+ #--
3
+ # Ronin Exploits - A Ruby library for Ronin that provides exploitation and
4
+ # payload crafting functionality.
5
+ #
6
+ # Copyright (c) 2007-2009 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #++
22
+ #
23
+
24
+ require 'ronin/license'
25
+
26
+ module Ronin
27
+ class License
28
+
29
+ # The payloads under the license
30
+ has n, :payloads,
31
+ :class_name => 'Ronin::Payloads::Payload'
32
+
33
+ end
34
+ end
@@ -21,9 +21,11 @@
21
21
  #++
22
22
  #
23
23
 
24
+ require 'ronin/payloads/asm_payload'
25
+
24
26
  module Ronin
25
27
  module Payloads
26
- class Nops < BinaryPayload
28
+ class Nops < ASMPayload
27
29
 
28
30
  contextify :ronin_nops
29
31
 
@@ -24,11 +24,7 @@
24
24
  require 'ronin/os'
25
25
 
26
26
  module Ronin
27
- class TargetedOS < OS
28
-
29
- # The exploit targets for the OS
30
- has n, :targets,
31
- :class_name => 'Ronin::Exploits::Target'
27
+ class OS
32
28
 
33
29
  # The payloads which target the OS
34
30
  has n, :payloads,
@@ -22,12 +22,19 @@
22
22
  #
23
23
 
24
24
  require 'ronin/payloads/exceptions/unknown_helper'
25
+ require 'ronin/payloads/license'
26
+ require 'ronin/payloads/arch'
27
+ require 'ronin/payloads/os'
25
28
  require 'ronin/payloads/payload_author'
26
29
  require 'ronin/payloads/control'
27
30
  require 'ronin/model/targets_arch'
28
31
  require 'ronin/model/targets_os'
32
+ require 'ronin/model/has_name'
33
+ require 'ronin/model/has_description'
34
+ require 'ronin/model/has_version'
35
+ require 'ronin/model/has_license'
36
+ require 'ronin/ui/diagnostics'
29
37
  require 'ronin/cacheable'
30
- require 'ronin/has_license'
31
38
 
32
39
  require 'parameters'
33
40
 
@@ -37,24 +44,19 @@ module Ronin
37
44
 
38
45
  include Parameters
39
46
  include Cacheable
47
+ include Model::HasName
48
+ include Model::HasDescription
49
+ include Model::HasVersion
50
+ include Model::HasLicense
40
51
  include Model::TargetsArch
41
52
  include Model::TargetsOS
42
- include HasLicense
53
+ include UI::Diagnostics
43
54
 
44
55
  contextify :ronin_payload
45
56
 
46
57
  # Primary key of the payload
47
58
  property :id, Serial
48
59
 
49
- # Name of the specific payload
50
- property :name, String, :index => true
51
-
52
- # Version of the payload
53
- property :version, String, :default => '0.1', :index => true
54
-
55
- # Description of the payload
56
- property :description, Text
57
-
58
60
  # Author(s) of the payload
59
61
  has n, :authors, :class_name => 'Ronin::Payloads::PayloadAuthor'
60
62
 
@@ -65,6 +67,9 @@ module Ronin
65
67
  validates_present :name
66
68
  validates_is_unique :version, :scope => [:name]
67
69
 
70
+ # The exploit to deploy with
71
+ attr_accessor :exploit
72
+
68
73
  # The built and encoded payload
69
74
  attr_accessor :payload
70
75
 
@@ -76,33 +81,14 @@ module Ronin
76
81
  def initialize(attributes={},&block)
77
82
  super(attributes)
78
83
 
84
+ initialize_params(attributes)
85
+
79
86
  @built = false
87
+ @deployed = false
80
88
 
81
89
  instance_eval(&block) if block
82
90
  end
83
91
 
84
- #
85
- # Finds all payloads with names like the specified _name_.
86
- #
87
- def self.named(name)
88
- self.all(:name.like => "%#{name}%")
89
- end
90
-
91
- #
92
- # Finds all payloads with descriptions like the specified
93
- # _description_.
94
- #
95
- def self.describing(description)
96
- self.all(:description.like => "%#{description}%")
97
- end
98
-
99
- #
100
- # Finds the payload with the most recent vesion.
101
- #
102
- def self.latest
103
- self.first(:order => [:version.desc])
104
- end
105
-
106
92
  #
107
93
  # Adds a new PayloadAuthor with the given _attributes_. If a _block_
108
94
  # is given, it will be passed to the newly created PayloadAuthor
@@ -117,13 +103,20 @@ module Ronin
117
103
  end
118
104
 
119
105
  #
120
- # Adds a new Control to the payload that provides the specified
121
- # _behavior_.
106
+ # Adds a new Control to the payload that controls the specified
107
+ # _behaviors_.
122
108
  #
123
- # controlling :code_exec
109
+ # controlling :code_exec.
110
+ # :file_read,
111
+ # :file_write,
112
+ # :file_create
124
113
  #
125
- def controlling(behavior)
126
- self.controls << Control.new(:behavior => Vuln::Behavior[behavior])
114
+ def controlling(*behaviors)
115
+ behaviors.each do |behavior|
116
+ self.controls << Control.new(
117
+ :behavior => Vuln::Behavior[behavior]
118
+ )
119
+ end
127
120
  end
128
121
 
129
122
  #
@@ -168,16 +161,59 @@ module Ronin
168
161
  end
169
162
 
170
163
  #
171
- # Default method to call after the payload has been deployed.
164
+ # Returns +true+ if the payload has previously been deployed,
165
+ # returns +false+ otherwise.
166
+ #
167
+ def deployed?
168
+ @deployed == true
169
+ end
170
+
171
+ #
172
+ # Verifies the built payload and deploys the payload. If a _block_
173
+ # is given, it will be passed the deployed payload object. If
174
+ # an exploit is given, it will be called with the given _options_
175
+ # and the built payload before the payload is deployed.
172
176
  #
173
- def deploy!(&block)
177
+ def deploy!(options={},&block)
178
+ # verify the payload
174
179
  verify!
180
+
181
+ if @exploit
182
+ # build, verify and deploy the exploit with the built payload
183
+ @exploit.call(options.merge(:payload => @payload))
184
+ end
185
+
186
+ @deployed = false
187
+
175
188
  deploy()
189
+
190
+ @deployed = true
176
191
 
177
192
  block.call(self) if block
178
193
  return self
179
194
  end
180
195
 
196
+ #
197
+ # Builds the payload with the given _options_ and deploys it with
198
+ # the given _block_. If a _block_ is given, it will be passed the
199
+ # deployed payload object.
200
+ #
201
+ # _options_ may contain the following keys:
202
+ # <tt>:exploit</tt>:: The exploit object to use with the payload.
203
+ #
204
+ def call(options={},&block)
205
+ if options[:exploit]
206
+ # set the exploit if one is given
207
+ @exploit = options.delete(:exploit)
208
+ end
209
+
210
+ # build the payload
211
+ build!(options)
212
+
213
+ # deploy the payload
214
+ return deploy!(options,&block)
215
+ end
216
+
181
217
  #
182
218
  # Returns the name and version of the payload.
183
219
  #
@@ -185,6 +221,16 @@ module Ronin
185
221
  "#{self.name} #{self.version}"
186
222
  end
187
223
 
224
+ #
225
+ # Inspects the contents of the payload.
226
+ #
227
+ def inspect
228
+ str = "#{self.class}: #{self}"
229
+ str << " #{self.params.inspect}" unless self.params.empty?
230
+
231
+ return "#<#{str}>"
232
+ end
233
+
188
234
  protected
189
235
 
190
236
  #
@@ -202,7 +248,9 @@ module Ronin
202
248
 
203
249
  begin
204
250
  require File.join('ronin','payloads','helpers',name)
205
- rescue LoadError
251
+ rescue Gem::LoadError => e
252
+ raise(e)
253
+ rescue ::LoadError
206
254
  raise(UnknownHelper,"unknown helper #{name.dump}",caller)
207
255
  end
208
256
 
@@ -22,10 +22,13 @@
22
22
  #
23
23
 
24
24
  require 'ronin/payloads/binary_payload'
25
+ require 'ronin/payloads/helpers/shell'
25
26
 
26
27
  module Ronin
27
28
  module Payloads
28
- class Shellcode < BinaryPayload
29
+ class Shellcode < ASMPayload
30
+
31
+ include Helpers::Shell
29
32
 
30
33
  contextify :ronin_shellcode
31
34
 
@@ -59,7 +59,7 @@ module Ronin
59
59
  end
60
60
 
61
61
  def arguments(*args)
62
- Database.setup!
62
+ Database.setup
63
63
 
64
64
  exploits = Ronin::Exploits::Exploit.all(@query)
65
65
 
@@ -77,7 +77,7 @@ module Ronin
77
77
  end
78
78
 
79
79
  def arguments(*args)
80
- Database.setup!
80
+ Database.setup
81
81
 
82
82
  # Load the payload
83
83
  if @path
@@ -85,7 +85,7 @@ module Ronin
85
85
  elsif args.length >= 1
86
86
  @query[:name] = args.first
87
87
 
88
- unless (payload = Payloads::Payload.first(@query))
88
+ unless (payload = Payloads::Payload.load_first(@query))
89
89
  fail("could not find the specified payload")
90
90
  end
91
91
  else
@@ -55,7 +55,7 @@ module Ronin
55
55
  end
56
56
 
57
57
  def arguments(*args)
58
- Database.setup!
58
+ Database.setup
59
59
 
60
60
  payloads = Ronin::Payloads::Payload.all(@query)
61
61
 
@@ -6,7 +6,6 @@ require 'helpers/objects'
6
6
  describe Exploits::Exploit do
7
7
  before(:each) do
8
8
  @exploit = load_exploit('test')
9
- @payload = load_payload('example')
10
9
  end
11
10
 
12
11
  it "should require a name attribute" do
@@ -42,9 +41,12 @@ describe Exploits::Exploit do
42
41
  end
43
42
 
44
43
  it "should specify the behaviors allowed by the exploit" do
45
- @exploit.allowing :memory_read
44
+ @exploit.allowing :memory_read, :memory_write
46
45
 
47
- @exploit.behaviors.first.should == Vuln::Behavior[:memory_read]
46
+ @exploit.behaviors.should == [
47
+ Vuln::Behavior[:memory_read],
48
+ Vuln::Behavior[:memory_write]
49
+ ]
48
50
  end
49
51
 
50
52
  it "should allow for the extending of Helper modules" do
@@ -63,8 +65,8 @@ describe Exploits::Exploit do
63
65
 
64
66
  it "should have targeted OSes" do
65
67
  @exploit.targeted_oses.should == [
66
- OS.linux_version('2.6.23'),
67
- OS.windows_version('7.1')
68
+ OS.linux('2.6.23'),
69
+ OS.windows('7.1')
68
70
  ]
69
71
  end
70
72
 
@@ -94,7 +96,7 @@ describe Exploits::Exploit do
94
96
  end
95
97
 
96
98
  it "should have a default targeted OS" do
97
- @exploit.os.should == OS.linux_version('2.6.23')
99
+ @exploit.os.should == OS.linux('2.6.23')
98
100
  end
99
101
 
100
102
  it "should have a default targeted Product" do
@@ -102,30 +104,6 @@ describe Exploits::Exploit do
102
104
  @exploit.product.version.should == '1.5'
103
105
  end
104
106
 
105
- it "should be able to switch between payloads" do
106
- @exploit.payload = @payload
107
-
108
- @exploit.switch_payload('other_payload') do
109
- @exploit.payload.should == 'other_payload'
110
- end
111
-
112
- @exploit.payload.should == @payload
113
- end
114
-
115
- it "should build the payload if it is a kind of Payloads::Payload" do
116
- @exploit.payload = @payload
117
- @exploit.encode_payload!
118
-
119
- @exploit.payload.should be_built
120
- end
121
-
122
- it "should share parameters with the payload if it is a kind of Payloads::Payload" do
123
- @exploit.payload = @payload
124
- @exploit.encode_payload!
125
-
126
- @payload.var.should == @exploit.var
127
- end
128
-
129
107
  it "should encode a String payload" do
130
108
  @exploit.payload = 'data'
131
109
 
@@ -174,4 +152,8 @@ describe Exploits::Exploit do
174
152
  it "should return the name and the version when calling to_s" do
175
153
  @exploit.to_s.should == 'test 0.2'
176
154
  end
155
+
156
+ it "should have a custom inspect method" do
157
+ @exploit.inspect.should == '#<Ronin::Exploits::Exploit: test 0.2>'
158
+ end
177
159
  end
@@ -0,0 +1,39 @@
1
+ require 'ronin/exploits/local'
2
+ require 'ronin/exploits/helpers/file_based'
3
+
4
+ require 'spec_helper'
5
+
6
+ describe Exploits::Helpers::FileBased do
7
+ before(:all) do
8
+ @exploit = Exploits::Local.new do
9
+ helper :file_based
10
+
11
+ self.name = 'file exploit'
12
+ self.file_name = 'file_exploit.dat'
13
+
14
+ def build
15
+ file_open do |file|
16
+ file << 'some data'
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ it "should have an absolute path for the file to be built" do
23
+ @exploit.file_path.should_not be_empty
24
+ end
25
+
26
+ it "should have a default output directory" do
27
+ @exploit.output_dir.should == Ronin::Config::TMP_DIR
28
+ end
29
+
30
+ it "should have a default file name, derived from the exploit name" do
31
+ @exploit.file_name.should == 'file_exploit.dat'
32
+ end
33
+
34
+ it "should build a file" do
35
+ @exploit.build!
36
+
37
+ File.read(@exploit.file_path).should == 'some data'
38
+ end
39
+ end