ronin-exploits 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/History.txt +80 -2
  2. data/Manifest.txt +63 -16
  3. data/README.txt +89 -2
  4. data/Rakefile +1 -1
  5. data/TODO.txt +1 -1
  6. data/bin/ronin-exploits +12 -0
  7. data/bin/ronin-payload +12 -0
  8. data/bin/ronin-payloads +12 -0
  9. data/lib/ronin/exploits.rb +13 -10
  10. data/lib/ronin/exploits/{impact.rb → allow.rb} +9 -4
  11. data/lib/ronin/exploits/exceptions.rb +3 -0
  12. data/lib/ronin/exploits/exceptions/target_data_missing.rb +29 -0
  13. data/lib/ronin/exploits/exceptions/target_unspecified.rb +29 -0
  14. data/lib/ronin/exploits/exceptions/unknown_helper.rb +29 -0
  15. data/lib/ronin/exploits/exploit.rb +330 -77
  16. data/lib/ronin/exploits/{format_string_target.rb → ftp.rb} +5 -11
  17. data/lib/ronin/exploits/helpers.rb +27 -0
  18. data/lib/ronin/exploits/helpers/binary.rb +44 -0
  19. data/lib/ronin/exploits/helpers/buffer_overflow.rb +102 -0
  20. data/lib/ronin/exploits/helpers/format_string.rb +107 -0
  21. data/lib/ronin/exploits/helpers/padding.rb +84 -0
  22. data/lib/ronin/exploits/http.rb +37 -0
  23. data/lib/ronin/exploits/{requirement.rb → local.rb} +2 -14
  24. data/lib/ronin/exploits/remote.rb +34 -0
  25. data/lib/ronin/exploits/remote_tcp.rb +70 -0
  26. data/lib/ronin/exploits/remote_udp.rb +70 -0
  27. data/lib/ronin/exploits/target.rb +134 -0
  28. data/lib/ronin/exploits/targets.rb +29 -0
  29. data/lib/ronin/exploits/{buffer_overflow_target.rb → targets/buffer_overflow.rb} +13 -11
  30. data/lib/ronin/exploits/{exploit_target.rb → targets/format_string.rb} +11 -14
  31. data/lib/ronin/exploits/version.rb +1 -1
  32. data/lib/ronin/exploits/{web_exploit.rb → web.rb} +3 -3
  33. data/lib/ronin/model/targets_arch.rb +59 -0
  34. data/lib/ronin/model/targets_os.rb +59 -0
  35. data/lib/ronin/payloads.rb +7 -3
  36. data/lib/ronin/payloads/binary_payload.rb +3 -7
  37. data/lib/ronin/payloads/{ability.rb → control.rb} +7 -2
  38. data/lib/ronin/payloads/encoder.rb +78 -0
  39. data/lib/ronin/payloads/encoders.rb +33 -0
  40. data/lib/ronin/payloads/encoders/xor.rb +81 -0
  41. data/lib/ronin/payloads/exceptions.rb +24 -0
  42. data/lib/ronin/payloads/exceptions/unknown_helper.rb +29 -0
  43. data/lib/ronin/payloads/helpers.rb +26 -0
  44. data/lib/ronin/payloads/helpers/exceptions.rb +24 -0
  45. data/lib/ronin/payloads/helpers/exceptions/program_not_found.rb +31 -0
  46. data/lib/ronin/payloads/helpers/exceptions/unimplemented.rb +31 -0
  47. data/lib/ronin/payloads/helpers/file_system.rb +187 -0
  48. data/lib/ronin/payloads/helpers/rpc.rb +83 -0
  49. data/lib/ronin/payloads/helpers/shell.rb +91 -0
  50. data/lib/ronin/payloads/nops.rb +32 -0
  51. data/lib/ronin/payloads/payload.rb +90 -53
  52. data/lib/ronin/payloads/shellcode.rb +1 -1
  53. data/lib/ronin/payloads/web_payload.rb +2 -1
  54. data/lib/ronin/targeted_arch.rb +38 -0
  55. data/lib/ronin/targeted_os.rb +38 -0
  56. data/lib/ronin/targeted_product.rb +34 -0
  57. data/lib/ronin/ui/command_line/commands/exploits.rb +77 -0
  58. data/lib/ronin/ui/command_line/commands/payload.rb +106 -0
  59. data/lib/ronin/ui/command_line/commands/payloads.rb +73 -0
  60. data/spec/exploits/binary_exploit_spec.rb +44 -0
  61. data/spec/exploits/buffer_overflow_exploit_spec.rb +70 -0
  62. data/spec/exploits/exploit_spec.rb +122 -25
  63. data/spec/exploits/format_string_exploit_spec.rb +32 -0
  64. data/spec/exploits/ftp_spec.rb +17 -0
  65. data/spec/exploits/http_spec.rb +17 -0
  66. data/spec/exploits/padding_exploit_spec.rb +44 -0
  67. data/spec/exploits/remote_tcp_spec.rb +24 -0
  68. data/spec/exploits/remote_udp_spec.rb +24 -0
  69. data/spec/exploits/target_spec.rb +91 -0
  70. data/spec/exploits/targets/buffer_overflow_spec.rb +18 -0
  71. data/spec/exploits/{web_exploit_spec.rb → web_spec.rb} +5 -5
  72. data/spec/helpers/database.rb +5 -0
  73. data/spec/helpers/objects.rb +22 -0
  74. data/spec/objects/exploits/test.rb +28 -0
  75. data/spec/objects/payloads/example.rb +19 -0
  76. data/spec/objects/payloads/test.rb +11 -0
  77. data/spec/payloads/encoder_spec.rb +26 -0
  78. data/spec/payloads/encoders/xor_spec.rb +20 -0
  79. data/spec/payloads/payload_spec.rb +48 -13
  80. data/spec/spec_helper.rb +3 -5
  81. metadata +71 -22
  82. data/lib/ronin/exploits/binary_exploit.rb +0 -139
  83. data/lib/ronin/exploits/buffer_overflow.rb +0 -80
  84. data/lib/ronin/exploits/exploitable.rb +0 -77
  85. data/lib/ronin/exploits/format_string.rb +0 -88
  86. data/lib/ronin/models.rb +0 -38
  87. data/lib/ronin/translators/xor.rb +0 -96
  88. data/spec/exploits/exploitable_spec.rb +0 -21
  89. data/spec/translators/xor_spec.rb +0 -26
@@ -0,0 +1,106 @@
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/payloads'
25
+ require 'ronin/ui/command_line/command'
26
+ require 'ronin/ui/verbose'
27
+ require 'ronin/database'
28
+
29
+ require 'parameters/parser'
30
+
31
+ module Ronin
32
+ module UI
33
+ module CommandLine
34
+ module Commands
35
+ class Payload < Command
36
+
37
+ include Parameters::Parser
38
+
39
+ def defaults
40
+ @path = nil
41
+ @query = {}
42
+ @params = {}
43
+ end
44
+
45
+ def define_options(opts)
46
+ opts.usage = '[options] [NAME]'
47
+
48
+ opts.options do
49
+ opts.on('-D','--database URI','The URI for the database') do |uri|
50
+ Database.config = uri.to_s
51
+ end
52
+
53
+ opts.on('-p','--param NAME=VALUE','Add a parameter NAME and VALUE') do |name_and_value|
54
+ @params.merge!(Parser.parse_param(name_and_value))
55
+ end
56
+
57
+ opts.on('-f','--file PATH','Load the payload from the specified FILE') do |path|
58
+ @path = path
59
+ end
60
+
61
+ opts.on('-v','--verbose','Enables verbose output') do
62
+ UI::Verbose.enable!
63
+ end
64
+
65
+ opts.on('-V','--version VERSION','Use the payload with the specified VERSION') do |version|
66
+ @query[:version] = version.to_s
67
+ end
68
+ end
69
+
70
+ opts.arguments(
71
+ 'NAME' => 'The NAME of the payload to load'
72
+ )
73
+
74
+ opts.summary %{
75
+ Build the specified payload
76
+ }
77
+ end
78
+
79
+ def arguments(*args)
80
+ Database.setup!
81
+
82
+ # Load the payload
83
+ if @path
84
+ payload = Payloads::Payload.load_from(@path)
85
+ elsif args.length >= 1
86
+ @query[:name] = args.first
87
+
88
+ unless (payload = Payloads::Payload.first(@query))
89
+ fail("could not find the specified payload")
90
+ end
91
+ else
92
+ fail("must either specify a payload NAME or a PATH")
93
+ end
94
+
95
+ # Build the payload
96
+ payload.build!(@params)
97
+
98
+ # Dump the built payload
99
+ puts payload.payload.dump
100
+ end
101
+
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,73 @@
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/ui/command_line/command'
25
+
26
+ require 'ronin/payloads'
27
+ require 'ronin/database'
28
+
29
+ module Ronin
30
+ module UI
31
+ module CommandLine
32
+ module Commands
33
+ class Payloads < Command
34
+
35
+ def defaults
36
+ @query = {}
37
+ end
38
+
39
+ def define_options(opts)
40
+ opts.usage = '[options]'
41
+
42
+ opts.options do
43
+ opts.on('-D','--database URI','The URI for the database') do |uri|
44
+ Database.config = uri.to_s
45
+ end
46
+
47
+ opts.on('-n','--name NAME','Search for payloads with the similar NAME') do |name|
48
+ @query[:name.like] = name.to_s
49
+ end
50
+
51
+ opts.on('-v','--version VERSION','Search for payloads with the similar VERSION') do |version|
52
+ @query[:version.like] = version.to_s
53
+ end
54
+ end
55
+ end
56
+
57
+ def arguments(*args)
58
+ Database.setup!
59
+
60
+ payloads = Ronin::Payloads::Payload.all(@query)
61
+
62
+ if payloads.empty?
63
+ fail("could not find similar payloads")
64
+ end
65
+
66
+ payloads.each { |payload| puts " #{payload.name}" }
67
+ end
68
+
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,44 @@
1
+ require 'ronin/exploits/local'
2
+ require 'ronin/exploits/helpers/binary'
3
+
4
+ require 'spec_helper'
5
+
6
+ describe Exploits::Helpers::Binary do
7
+ before(:all) do
8
+ @exploit = Exploits::Local.new do
9
+ helper :binary
10
+
11
+ targeting(:arch => Arch.i686)
12
+ targeting(:arch => nil)
13
+
14
+ def pack_integer
15
+ pack(0xffffaaaa)
16
+ end
17
+
18
+ def pack_integer_with_address_length
19
+ pack(0xffffaaaa,2)
20
+ end
21
+ end
22
+ end
23
+
24
+ it "should require a targeted arch" do
25
+ @exploit.target = @exploit.targets.last
26
+ @exploit.target.arch.should be_nil
27
+
28
+ lambda {
29
+ @exploit.pack_integer
30
+ }.should raise_error(Exploits::TargetDataMissing)
31
+ end
32
+
33
+ it "should be able to pack an integer" do
34
+ @exploit.target = @exploit.targets.first
35
+
36
+ @exploit.pack_integer.should == "\xaa\xaa\xff\xff"
37
+ end
38
+
39
+ it "should be able to pack an integer with an address length" do
40
+ @exploit.target = @exploit.targets.first
41
+
42
+ @exploit.pack_integer_with_address_length.should == "\xaa\xaa"
43
+ end
44
+ end
@@ -0,0 +1,70 @@
1
+ require 'ronin/exploits/local'
2
+ require 'ronin/exploits/helpers/buffer_overflow'
3
+
4
+ require 'spec_helper'
5
+
6
+ describe Exploits::Helpers::BufferOverflow do
7
+ before(:all) do
8
+ @exploit = Exploits::Local.new do
9
+ helper :buffer_overflow
10
+
11
+ self.name = 'example_bof'
12
+
13
+ targeting do |target|
14
+ target.arch = Arch.i686
15
+ target.buffer_length = 256
16
+ target.ip = 0xffffaaaa
17
+ end
18
+
19
+ targeting do |target|
20
+ target.arch = Arch.i686
21
+ target.buffer_length = 256
22
+ target.bp = 0xffffbbbb
23
+ target.ip = 0xffffaaaa
24
+ end
25
+
26
+ targeting do |target|
27
+ target.arch = Arch.i686
28
+ target.buffer_length = 256
29
+ target.bp = 0xffffbbbb
30
+ target.ip = 0xffffaabb
31
+ target.frame_repeat = 2
32
+ end
33
+ end
34
+ end
35
+
36
+ it "should use Targets::BufferOverflow for targets" do
37
+ @exploit.targets.all? { |target|
38
+ target.class == Exploits::Targets::BufferOverflow
39
+ }.should == true
40
+ end
41
+
42
+ it "should build a buffer overflow" do
43
+ @exploit.target = @exploit.targets[0]
44
+ @exploit.build!
45
+
46
+ @exploit.buffer.length.should == (256 + 4*2)
47
+ @exploit.buffer[256,4].should == "\xaa\xaa\xff\xff"
48
+ @exploit.buffer[260,4].should == "\xaa\xaa\xff\xff"
49
+ end
50
+
51
+ it "should build a buffer overflow that includes the BP" do
52
+ @exploit.target = @exploit.targets[1]
53
+ @exploit.build!
54
+
55
+ @exploit.buffer.length.should == (256 + 4*2)
56
+ @exploit.buffer[256,4].should == "\xbb\xbb\xff\xff"
57
+ @exploit.buffer[260,4].should == "\xaa\xaa\xff\xff"
58
+ end
59
+
60
+ it "should build a buffer overflow that has repeating stack frames" do
61
+ @exploit.target = @exploit.targets[2]
62
+ @exploit.build!
63
+
64
+ @exploit.buffer.length.should == (256 + 4*4)
65
+ @exploit.buffer[256,4].should == "\xbb\xbb\xff\xff"
66
+ @exploit.buffer[260,4].should == "\xbb\xaa\xff\xff"
67
+ @exploit.buffer[264,4].should == "\xbb\xbb\xff\xff"
68
+ @exploit.buffer[268,4].should == "\xbb\xaa\xff\xff"
69
+ end
70
+ end
@@ -1,18 +1,16 @@
1
1
  require 'ronin/exploits/exploit'
2
2
 
3
3
  require 'spec_helper'
4
+ require 'helpers/objects'
4
5
 
5
6
  describe Exploits::Exploit do
6
7
  before(:each) do
7
- @exp = Exploits::Exploit.new(:name => 'test') do
8
- def builder
9
- 'result'
10
- end
11
- end
8
+ @exploit = load_exploit('test')
9
+ @payload = load_payload('example')
12
10
  end
13
11
 
14
12
  it "should require a name attribute" do
15
- exp2 = Exploits::Exploit.new(:object_path => 'test.rb')
13
+ exp2 = Exploits::Exploit.new
16
14
  exp2.should_not be_valid
17
15
 
18
16
  exp2.name = 'test'
@@ -21,60 +19,159 @@ describe Exploits::Exploit do
21
19
 
22
20
  it "should have a unique name and version" do
23
21
  first_exp = Exploits::Exploit.create(
24
- :object_path => 'test.rb',
25
- :name => 'test',
22
+ :name => 'test2',
26
23
  :version => '0.0.1'
27
24
  )
28
25
  first_exp.should be_valid
29
26
 
30
27
  second_exp = Exploits::Exploit.new(
31
- :object_path => 'other.rb',
32
- :name => 'test',
28
+ :name => 'test2',
33
29
  :version => '0.0.1'
34
30
  )
35
31
  second_exp.should_not be_valid
36
32
 
37
33
  third_exp = Exploits::Exploit.new(
38
- :object_path => 'other.rb',
39
- :name => 'test',
34
+ :name => 'test2',
40
35
  :version => '0.0.2'
41
36
  )
42
37
  third_exp.should be_valid
43
38
  end
44
39
 
40
+ it "should not have any allowances by default" do
41
+ @exploit.allows.should be_empty
42
+ end
43
+
44
+ it "should specify the behaviors allowed by the exploit" do
45
+ @exploit.allowing :memory_read
46
+
47
+ @exploit.behaviors.first.should == Vuln::Behavior[:memory_read]
48
+ end
49
+
50
+ it "should allow for the extending of Helper modules" do
51
+ @exploit.instance_eval { helper :padding }.should == true
52
+ end
53
+
54
+ it "should raise an UnknownHelper when extending an unknown helper" do
55
+ lambda {
56
+ @exploit.instance_eval { helper :obvious_not_there }
57
+ }.should raise_error(Exploits::UnknownHelper)
58
+ end
59
+
60
+ it "should have targeted Archs" do
61
+ @exploit.targeted_archs.should == [Arch.i686, Arch.i386]
62
+ end
63
+
64
+ it "should have targeted OSes" do
65
+ @exploit.targeted_oses.should == [
66
+ OS.linux_version('2.6.23'),
67
+ OS.windows_version('7.1')
68
+ ]
69
+ end
70
+
71
+ it "should have targeted products" do
72
+ @exploit.targeted_products.all? { |product|
73
+ product.name == 'ExampleWare' && product.version == '1.5'
74
+ }.should == true
75
+ end
76
+
77
+ it "should allow the explicit selection of a target" do
78
+ @exploit.select_target { |target| target.arch == Arch.i686 }
79
+
80
+ @exploit.target.arch.should == Arch.i686
81
+ end
82
+
83
+ it "should have a default target" do
84
+ @exploit.target.should_not be_nil
85
+
86
+ @exploit.target.arch.should == Arch.i686
87
+
88
+ @exploit.target.os.name.should == 'Linux'
89
+ @exploit.target.os.version.should == '2.6.23'
90
+ end
91
+
92
+ it "should have a default targeted Arch" do
93
+ @exploit.arch.should == Arch.i686
94
+ end
95
+
96
+ it "should have a default targeted OS" do
97
+ @exploit.os.should == OS.linux_version('2.6.23')
98
+ end
99
+
100
+ it "should have a default targeted Product" do
101
+ @exploit.product.name.should == 'ExampleWare'
102
+ @exploit.product.version.should == '1.5'
103
+ end
104
+
45
105
  it "should be able to switch between payloads" do
46
- @exp.payload = 'payload1'
106
+ @exploit.payload = @payload
47
107
 
48
- @exp.switch_payload('payload2') do
49
- @exp.payload.should == 'payload2'
108
+ @exploit.switch_payload('other_payload') do
109
+ @exploit.payload.should == 'other_payload'
50
110
  end
51
111
 
52
- @exp.payload.should == 'payload1'
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
+ it "should encode a String payload" do
130
+ @exploit.payload = 'data'
131
+
132
+ @exploit.encode_payload!
133
+ @exploit.encoded_payload.should == 'data'
134
+ end
135
+
136
+ it "should encode a String using encoders" do
137
+ @exploit.payload = 'data'
138
+ @exploit.encoders << lambda { |payload| payload.upcase }
139
+
140
+ @exploit.encode_payload!
141
+ @exploit.encoded_payload.should == 'DATA'
142
+ end
143
+
144
+ it "should ignore payload encoders which return nil" do
145
+ @exploit.payload = 'data'
146
+ @exploit.encoders << lambda { |payload| nil }
147
+
148
+ @exploit.encode_payload!
149
+ @exploit.encoded_payload.should == 'data'
53
150
  end
54
151
 
55
152
  it "should have 'unbuilt' and 'built' states" do
56
- @exp.should_not be_built
57
- @exp.build
58
- @exp.should be_built
153
+ @exploit.should_not be_built
154
+ @exploit.build!
155
+ @exploit.should be_built
59
156
  end
60
157
 
61
158
  it "should return the result of the builder" do
62
- @exp.build.should == 'result'
159
+ @exploit.build!.should == 'result'
63
160
  end
64
161
 
65
162
  it "should require the exploit is built before being deployed" do
66
- lambda { @exp.deploy }.should raise_error(Exploits::ExploitNotBuilt)
163
+ lambda { @exploit.deploy! }.should raise_error(Exploits::ExploitNotBuilt)
67
164
  end
68
165
 
69
166
  it "should have a default deployer method" do
70
- @exp.build
167
+ @exploit.build!
71
168
 
72
- @exp.deploy do |exploit|
73
- @exp.should == exploit
169
+ @exploit.deploy! do |exploit|
170
+ @exploit.should == exploit
74
171
  end
75
172
  end
76
173
 
77
174
  it "should return the name and the version when calling to_s" do
78
- @exp.to_s.should == 'test 0.1'
175
+ @exploit.to_s.should == 'test 0.2'
79
176
  end
80
177
  end