ronin-exploits 0.1.1 → 0.2.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.
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