ronin-exploits 0.2.0 → 0.2.1
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.
- data.tar.gz.sig +0 -0
- data/History.txt +27 -0
- data/Manifest.txt +21 -5
- data/README.txt +40 -3
- data/Rakefile +6 -6
- data/TODO.txt +12 -9
- data/lib/ronin/exploits/allow.rb +1 -1
- data/lib/ronin/{targeted_arch.rb → exploits/arch.rb} +1 -5
- data/lib/ronin/exploits/exploit.rb +59 -144
- data/lib/ronin/exploits/ftp.rb +4 -1
- data/lib/ronin/exploits/helpers.rb +1 -0
- data/lib/ronin/exploits/helpers/file_based.rb +113 -0
- data/lib/ronin/exploits/http.rb +10 -0
- data/lib/ronin/exploits/license.rb +34 -0
- data/lib/ronin/exploits/os.rb +34 -0
- data/lib/ronin/{targeted_product.rb → exploits/product.rb} +1 -1
- data/lib/ronin/exploits/remote_tcp.rb +2 -3
- data/lib/ronin/exploits/remote_udp.rb +2 -3
- data/lib/ronin/exploits/target.rb +8 -10
- data/lib/ronin/exploits/verifiers.rb +92 -0
- data/lib/ronin/exploits/version.rb +1 -1
- data/lib/ronin/exploits/web.rb +21 -1
- data/lib/ronin/model/has_default_port.rb +54 -0
- data/lib/ronin/model/targets_arch.rb +8 -10
- data/lib/ronin/model/targets_os.rb +9 -9
- data/lib/ronin/payloads.rb +1 -0
- data/lib/ronin/payloads/arch.rb +32 -0
- data/lib/ronin/payloads/asm_payload.rb +34 -0
- data/lib/ronin/payloads/encoder.rb +24 -18
- data/lib/ronin/payloads/helpers/exceptions.rb +2 -1
- data/lib/ronin/payloads/helpers/exceptions/{unimplemented.rb → not_implemented.rb} +1 -1
- data/lib/ronin/payloads/helpers/file_system.rb +12 -12
- data/lib/ronin/payloads/helpers/rpc.rb +7 -7
- data/lib/ronin/payloads/helpers/shell.rb +2 -2
- data/lib/ronin/payloads/license.rb +34 -0
- data/lib/ronin/payloads/nops.rb +3 -1
- data/lib/ronin/{targeted_os.rb → payloads/os.rb} +1 -5
- data/lib/ronin/payloads/payload.rb +89 -41
- data/lib/ronin/payloads/shellcode.rb +4 -1
- data/lib/ronin/ui/command_line/commands/exploits.rb +1 -1
- data/lib/ronin/ui/command_line/commands/payload.rb +2 -2
- data/lib/ronin/ui/command_line/commands/payloads.rb +1 -1
- data/spec/exploits/exploit_spec.rb +12 -30
- data/spec/exploits/file_based_exploit_spec.rb +39 -0
- data/spec/exploits/ftp_spec.rb +1 -5
- data/spec/exploits/http_spec.rb +4 -4
- data/spec/exploits/remote_tcp_spec.rb +7 -3
- data/spec/exploits/remote_udp_spec.rb +7 -3
- data/spec/exploits/target_spec.rb +9 -2
- data/spec/exploits/targets/buffer_overflow_spec.rb +6 -2
- data/spec/exploits/web_spec.rb +6 -0
- data/spec/model/has_default_port_spec.rb +27 -0
- data/spec/model/models/default_port_model.rb +13 -0
- data/spec/model/models/non_default_port_model.rb +11 -0
- data/spec/model/models/targets_arch_model.rb +11 -0
- data/spec/model/models/targets_os_model.rb +11 -0
- data/spec/model/targets_arch_spec.rb +22 -0
- data/spec/model/targets_os_spec.rb +23 -0
- data/spec/objects/exploits/example.rb +25 -0
- data/spec/objects/exploits/test.rb +0 -4
- data/spec/objects/payloads/test.rb +5 -1
- data/spec/payloads/encoder_spec.rb +5 -1
- data/spec/payloads/payload_spec.rb +77 -14
- metadata +58 -13
- metadata.gz.sig +0 -0
- data/spec/objects/payloads/example.rb +0 -19
@@ -21,7 +21,7 @@
|
|
21
21
|
#++
|
22
22
|
#
|
23
23
|
|
24
|
-
require 'ronin/payloads/helpers/exceptions/
|
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(
|
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
|
data/lib/ronin/payloads/nops.rb
CHANGED
@@ -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
|
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
|
121
|
-
#
|
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(
|
126
|
-
|
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
|
-
#
|
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!(
|
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 <
|
29
|
+
class Shellcode < ASMPayload
|
30
|
+
|
31
|
+
include Helpers::Shell
|
29
32
|
|
30
33
|
contextify :ronin_shellcode
|
31
34
|
|
@@ -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.
|
88
|
+
unless (payload = Payloads::Payload.load_first(@query))
|
89
89
|
fail("could not find the specified payload")
|
90
90
|
end
|
91
91
|
else
|
@@ -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.
|
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.
|
67
|
-
OS.
|
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.
|
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
|