ronin-exploits 0.1.0
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/COPYING.txt +339 -0
- data/History.txt +18 -0
- data/Manifest.txt +42 -0
- data/README.txt +69 -0
- data/Rakefile +15 -0
- data/TODO.txt +25 -0
- data/lib/ronin/exploits.rb +39 -0
- data/lib/ronin/exploits/binary_exploit.rb +133 -0
- data/lib/ronin/exploits/buffer_overflow.rb +76 -0
- data/lib/ronin/exploits/buffer_overflow_target.rb +46 -0
- data/lib/ronin/exploits/exceptions.rb +25 -0
- data/lib/ronin/exploits/exceptions/exploit_not_built.rb +29 -0
- data/lib/ronin/exploits/exceptions/restricted_char.rb +29 -0
- data/lib/ronin/exploits/exploit.rb +263 -0
- data/lib/ronin/exploits/exploit_author.rb +34 -0
- data/lib/ronin/exploits/exploit_target.rb +48 -0
- data/lib/ronin/exploits/exploitable.rb +77 -0
- data/lib/ronin/exploits/format_string.rb +84 -0
- data/lib/ronin/exploits/format_string_target.rb +43 -0
- data/lib/ronin/exploits/impact.rb +46 -0
- data/lib/ronin/exploits/requirement.rb +46 -0
- data/lib/ronin/exploits/version.rb +29 -0
- data/lib/ronin/exploits/web_exploit.rb +77 -0
- data/lib/ronin/models.rb +38 -0
- data/lib/ronin/payloads.rb +33 -0
- data/lib/ronin/payloads/ability.rb +46 -0
- data/lib/ronin/payloads/binary_payload.rb +40 -0
- data/lib/ronin/payloads/payload.rb +203 -0
- data/lib/ronin/payloads/payload_author.rb +34 -0
- data/lib/ronin/payloads/shellcode.rb +34 -0
- data/lib/ronin/payloads/web_payload.rb +34 -0
- data/lib/ronin/translators/xor.rb +96 -0
- data/lib/ronin/vuln/behavior.rb +92 -0
- data/spec/exploits/exploit_spec.rb +80 -0
- data/spec/exploits/exploitable_spec.rb +21 -0
- data/spec/exploits/web_exploit_spec.rb +29 -0
- data/spec/exploits_spec.rb +9 -0
- data/spec/payloads/payload_spec.rb +60 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/translators/xor_spec.rb +26 -0
- data/spec/vuln/behavior_spec.rb +15 -0
- data/tasks/spec.rb +9 -0
- metadata +119 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Ronin - A Ruby platform designed for information security and data
|
4
|
+
# exploration tasks.
|
5
|
+
#
|
6
|
+
# Copyright (c) 2006-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/translators/translator'
|
25
|
+
require 'ronin/chars'
|
26
|
+
|
27
|
+
module Ronin
|
28
|
+
module Translators
|
29
|
+
class XOR < Translator
|
30
|
+
|
31
|
+
# Set of characters to allow in the encoded data
|
32
|
+
attr_accessor :allow
|
33
|
+
|
34
|
+
#
|
35
|
+
# Creates a new XOR Translator object using the given _options_.
|
36
|
+
# If a _block_ is given it will be passed the newly created
|
37
|
+
# Translator object.
|
38
|
+
#
|
39
|
+
# _options_ may include the following keys:
|
40
|
+
# <tt>:allow</tt>:: The set of characters allowed in the encoded
|
41
|
+
# result. Defaults to <tt>(1..255)</tt>.
|
42
|
+
# <tt>:disallow</tt>:: The set of characters that are not allowed
|
43
|
+
# in the encoded result.
|
44
|
+
#
|
45
|
+
def initialize(options={},&block)
|
46
|
+
@allow = Chars::CharSet.new(options[:allow] || (1..255))
|
47
|
+
|
48
|
+
if options[:disallow]
|
49
|
+
@allow -= options[:disallow]
|
50
|
+
end
|
51
|
+
|
52
|
+
super(&block)
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# XOR encodes the specified _data_ prefixing the XOR key to the
|
57
|
+
# encoded data. If a _block_ is given, it will be passed the encoded
|
58
|
+
# data.
|
59
|
+
#
|
60
|
+
def encode(data,&block)
|
61
|
+
alphabet = Chars.all.select { |b| data.include?(b.chr) }
|
62
|
+
excluded = (Chars.all - alphabet)
|
63
|
+
|
64
|
+
key = excluded.select { |b|
|
65
|
+
@allow.include?(b) && alphabet.all? { |i|
|
66
|
+
@allow.include?(i ^ b)
|
67
|
+
}
|
68
|
+
}.last
|
69
|
+
|
70
|
+
text = ''
|
71
|
+
|
72
|
+
text << key.chr
|
73
|
+
data.each_byte { |b| text << (b ^ key).chr }
|
74
|
+
|
75
|
+
block.call(text) if block
|
76
|
+
return text
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# XOR decodes the specified _text_. If a _block_ is given, it will be
|
81
|
+
# passed the decoded data.
|
82
|
+
#
|
83
|
+
def decode(text,&block)
|
84
|
+
data = ''
|
85
|
+
key = text[0]
|
86
|
+
|
87
|
+
text[1..-1].each_byte do |b|
|
88
|
+
data << (b ^ key).chr
|
89
|
+
end
|
90
|
+
|
91
|
+
return data
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,92 @@
|
|
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/extensions/meta'
|
25
|
+
require 'ronin/extensions/string'
|
26
|
+
require 'ronin/model'
|
27
|
+
|
28
|
+
require 'dm-predefined'
|
29
|
+
|
30
|
+
module Ronin
|
31
|
+
module Vuln
|
32
|
+
class Behavior
|
33
|
+
|
34
|
+
include Model
|
35
|
+
include DataMapper::Predefined
|
36
|
+
|
37
|
+
# Primary key of the behavior
|
38
|
+
property :id, Serial
|
39
|
+
|
40
|
+
# Name of the behavior
|
41
|
+
property :name, String
|
42
|
+
|
43
|
+
# Description for the behavior
|
44
|
+
property :description, Text
|
45
|
+
|
46
|
+
# Validates
|
47
|
+
validates_present :name, :description
|
48
|
+
validates_is_unique :name
|
49
|
+
|
50
|
+
#
|
51
|
+
# Returns the name of the behavior.
|
52
|
+
#
|
53
|
+
def to_s
|
54
|
+
@name.to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
#
|
60
|
+
# Defines a new builtin Behavior with the specified _name_ and the
|
61
|
+
# given _description_.
|
62
|
+
#
|
63
|
+
def self.define(name,description=nil)
|
64
|
+
super(name,:name => name.to_s, :description => description)
|
65
|
+
end
|
66
|
+
|
67
|
+
define :memory_read, "The ability to read memory"
|
68
|
+
define :memory_write, "The ability to write to memory"
|
69
|
+
define :file_create, "Arbitrary file creation"
|
70
|
+
define :file_read, "The ability to read from a file"
|
71
|
+
define :file_write, "The ability to write to a file"
|
72
|
+
define :file_modify, "The ability to modify an existing file"
|
73
|
+
define :file_ownership, "The ability to change ownership of an existing file"
|
74
|
+
define :file_mtime, "The ability to change the modification timestamp of a file"
|
75
|
+
define :file_ctime, "The ability to change the creation timestamp of a file"
|
76
|
+
define :socket_redirect, "The ability to redirect a socket's connection"
|
77
|
+
define :socket_connect, "The ability to create a network socket"
|
78
|
+
define :socket_listen, "The ability to listen on a network socket"
|
79
|
+
define :socket_read, "The ability to read from a network socket"
|
80
|
+
define :socket_write, "The ability to write to a network socket"
|
81
|
+
define :code_exec, "Arbitrary code execution"
|
82
|
+
define :command_exec, "Arbitrary command execution"
|
83
|
+
define :auth_bypass, "Authentication by-pass"
|
84
|
+
define :priv_escalation, "Privilege escalation"
|
85
|
+
define :exhaust_memory, "Exhaust freely available memory"
|
86
|
+
define :exhaust_disk, "Exhaust freely available disk-space"
|
87
|
+
define :exhaust_bandwidth, "Exhaust available bandwidth"
|
88
|
+
define :exahust_cpu, "Exhaust CPU performance"
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'ronin/exploits/exploit'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Exploits::Exploit do
|
6
|
+
before(:each) do
|
7
|
+
@exp = Exploits::Exploit.new(:name => 'test') do
|
8
|
+
def builder
|
9
|
+
'result'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should require a name attribute" do
|
15
|
+
exp2 = Exploits::Exploit.new(:object_path => 'test.rb')
|
16
|
+
exp2.should_not be_valid
|
17
|
+
|
18
|
+
exp2.name = 'test'
|
19
|
+
exp2.should be_valid
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should have a unique name and version" do
|
23
|
+
first_exp = Exploits::Exploit.create(
|
24
|
+
:object_path => 'test.rb',
|
25
|
+
:name => 'test',
|
26
|
+
:version => '0.0.1'
|
27
|
+
)
|
28
|
+
first_exp.should be_valid
|
29
|
+
|
30
|
+
second_exp = Exploits::Exploit.new(
|
31
|
+
:object_path => 'other.rb',
|
32
|
+
:name => 'test',
|
33
|
+
:version => '0.0.1'
|
34
|
+
)
|
35
|
+
second_exp.should_not be_valid
|
36
|
+
|
37
|
+
third_exp = Exploits::Exploit.new(
|
38
|
+
:object_path => 'other.rb',
|
39
|
+
:name => 'test',
|
40
|
+
:version => '0.0.2'
|
41
|
+
)
|
42
|
+
third_exp.should be_valid
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should be able to switch between payloads" do
|
46
|
+
@exp.payload = 'payload1'
|
47
|
+
|
48
|
+
@exp.switch_payload('payload2') do
|
49
|
+
@exp.payload.should == 'payload2'
|
50
|
+
end
|
51
|
+
|
52
|
+
@exp.payload.should == 'payload1'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should have 'unbuilt' and 'built' states" do
|
56
|
+
@exp.should_not be_built
|
57
|
+
@exp.build
|
58
|
+
@exp.should be_built
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return the result of the builder" do
|
62
|
+
@exp.build.should == 'result'
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should require the exploit is built before being deployed" do
|
66
|
+
lambda { @exp.deploy }.should raise_error(Exploits::ExploitNotBuilt)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should have a default deployer method" do
|
70
|
+
@exp.build
|
71
|
+
|
72
|
+
@exp.deploy do |exploit|
|
73
|
+
@exp.should == exploit
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should return the name and the version when calling to_s" do
|
78
|
+
@exp.to_s.should == 'test 0.1'
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'ronin/exploits/exploitable'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Exploits::Exploitable do
|
6
|
+
before(:all) do
|
7
|
+
class Vulnerable
|
8
|
+
|
9
|
+
include Exploits::Exploitable
|
10
|
+
|
11
|
+
has_exploits :test do |obj|
|
12
|
+
[Exploits::Exploit.new(:name => :first_generated)]
|
13
|
+
end
|
14
|
+
|
15
|
+
has_exploits :test_two do |obj|
|
16
|
+
[Exploits::BinaryExploit.new(:name => :second_generated)]
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'ronin/exploits/web_exploit'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Exploits::WebExploit do
|
6
|
+
describe "targeted_url" do
|
7
|
+
it "should create a targeted URL using the host param" do
|
8
|
+
host = 'www.example.com'
|
9
|
+
exploit = Exploits::WebExploit.new(:host => host)
|
10
|
+
|
11
|
+
exploit.targeted_url.host.should == host
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should create a targeted URL using the host param and the url_path property" do
|
15
|
+
host = 'www.example.com'
|
16
|
+
path = '/'
|
17
|
+
exploit = Exploits::WebExploit.new(:host => host, :url_path => path)
|
18
|
+
|
19
|
+
exploit.targeted_url.host.should == host
|
20
|
+
exploit.targeted_url.path.should == path
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should raise a MissingParam exception if host params is missing" do
|
24
|
+
exploit = Exploits::WebExploit.new(:url_path => '/')
|
25
|
+
|
26
|
+
lambda { exploit.targeted_url }.should raise_error(Parameters::MissingParam)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'ronin/payloads/payload'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Payloads::Payload do
|
6
|
+
before(:each) do
|
7
|
+
@payload = Payloads::Payload.new(:name => 'test') do
|
8
|
+
def builder
|
9
|
+
@payload = 'code'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should require a name attribute" do
|
15
|
+
payload = Payloads::Payload.new(:object_path => 'test.rb')
|
16
|
+
payload.should_not be_valid
|
17
|
+
|
18
|
+
payload.name = 'test'
|
19
|
+
payload.should be_valid
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should have a unique name and version" do
|
23
|
+
first_payload = Payloads::Payload.create(
|
24
|
+
:object_path => 'test.rb',
|
25
|
+
:name => 'test',
|
26
|
+
:version => '0.0.1'
|
27
|
+
)
|
28
|
+
first_payload.should be_valid
|
29
|
+
|
30
|
+
second_payload = Payloads::Payload.new(
|
31
|
+
:object_path => 'other.rb',
|
32
|
+
:name => 'test',
|
33
|
+
:version => '0.0.1'
|
34
|
+
)
|
35
|
+
second_payload.should_not be_valid
|
36
|
+
|
37
|
+
third_payload = Payloads::Payload.new(
|
38
|
+
:object_path => 'other.rb',
|
39
|
+
:name => 'test',
|
40
|
+
:version => '0.0.2'
|
41
|
+
)
|
42
|
+
third_payload.should be_valid
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have 'built' and 'unbiult' states" do
|
46
|
+
@payload.should_not be_built
|
47
|
+
@payload.build
|
48
|
+
@payload.should be_built
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return the built payload when calling build" do
|
52
|
+
@payload.build.should == 'code'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should have a default deployer method" do
|
56
|
+
@payload.deploy do |payload|
|
57
|
+
@payload.should == payload
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'ronin/translators/xor'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Ronin do
|
6
|
+
describe Translators::XOR do
|
7
|
+
before(:all) do
|
8
|
+
@data = "\x00\x01\x90ABC123[]{}'"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should encode-out unwanted characters" do
|
12
|
+
disallow = [0x00, 0x01, 0x90]
|
13
|
+
xor = Translators::XOR.new(:disallow => disallow)
|
14
|
+
|
15
|
+
xor.encode(@data).each_byte do |b|
|
16
|
+
disallow.include?(b).should_not == true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should decode XOR encoded data" do
|
21
|
+
xor = Translators::XOR.new
|
22
|
+
|
23
|
+
xor.decode(xor.encode(@data)).should == @data
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'ronin/vuln/behavior'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Vuln::Behavior do
|
5
|
+
it "should require name and description attributes" do
|
6
|
+
behavior = Vuln::Behavior.new
|
7
|
+
behavior.should_not be_valid
|
8
|
+
|
9
|
+
behavior.name = 'arbitrary lol injection'
|
10
|
+
behavior.should_not be_valid
|
11
|
+
|
12
|
+
behavior.description = %{Allows for the arbitrary injection of lolz.}
|
13
|
+
behavior.should be_valid
|
14
|
+
end
|
15
|
+
end
|