ronin-exploits 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|