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.
- data/History.txt +80 -2
- data/Manifest.txt +63 -16
- data/README.txt +89 -2
- data/Rakefile +1 -1
- data/TODO.txt +1 -1
- data/bin/ronin-exploits +12 -0
- data/bin/ronin-payload +12 -0
- data/bin/ronin-payloads +12 -0
- data/lib/ronin/exploits.rb +13 -10
- data/lib/ronin/exploits/{impact.rb → allow.rb} +9 -4
- data/lib/ronin/exploits/exceptions.rb +3 -0
- data/lib/ronin/exploits/exceptions/target_data_missing.rb +29 -0
- data/lib/ronin/exploits/exceptions/target_unspecified.rb +29 -0
- data/lib/ronin/exploits/exceptions/unknown_helper.rb +29 -0
- data/lib/ronin/exploits/exploit.rb +330 -77
- data/lib/ronin/exploits/{format_string_target.rb → ftp.rb} +5 -11
- data/lib/ronin/exploits/helpers.rb +27 -0
- data/lib/ronin/exploits/helpers/binary.rb +44 -0
- data/lib/ronin/exploits/helpers/buffer_overflow.rb +102 -0
- data/lib/ronin/exploits/helpers/format_string.rb +107 -0
- data/lib/ronin/exploits/helpers/padding.rb +84 -0
- data/lib/ronin/exploits/http.rb +37 -0
- data/lib/ronin/exploits/{requirement.rb → local.rb} +2 -14
- data/lib/ronin/exploits/remote.rb +34 -0
- data/lib/ronin/exploits/remote_tcp.rb +70 -0
- data/lib/ronin/exploits/remote_udp.rb +70 -0
- data/lib/ronin/exploits/target.rb +134 -0
- data/lib/ronin/exploits/targets.rb +29 -0
- data/lib/ronin/exploits/{buffer_overflow_target.rb → targets/buffer_overflow.rb} +13 -11
- data/lib/ronin/exploits/{exploit_target.rb → targets/format_string.rb} +11 -14
- data/lib/ronin/exploits/version.rb +1 -1
- data/lib/ronin/exploits/{web_exploit.rb → web.rb} +3 -3
- data/lib/ronin/model/targets_arch.rb +59 -0
- data/lib/ronin/model/targets_os.rb +59 -0
- data/lib/ronin/payloads.rb +7 -3
- data/lib/ronin/payloads/binary_payload.rb +3 -7
- data/lib/ronin/payloads/{ability.rb → control.rb} +7 -2
- data/lib/ronin/payloads/encoder.rb +78 -0
- data/lib/ronin/payloads/encoders.rb +33 -0
- data/lib/ronin/payloads/encoders/xor.rb +81 -0
- data/lib/ronin/payloads/exceptions.rb +24 -0
- data/lib/ronin/payloads/exceptions/unknown_helper.rb +29 -0
- data/lib/ronin/payloads/helpers.rb +26 -0
- data/lib/ronin/payloads/helpers/exceptions.rb +24 -0
- data/lib/ronin/payloads/helpers/exceptions/program_not_found.rb +31 -0
- data/lib/ronin/payloads/helpers/exceptions/unimplemented.rb +31 -0
- data/lib/ronin/payloads/helpers/file_system.rb +187 -0
- data/lib/ronin/payloads/helpers/rpc.rb +83 -0
- data/lib/ronin/payloads/helpers/shell.rb +91 -0
- data/lib/ronin/payloads/nops.rb +32 -0
- data/lib/ronin/payloads/payload.rb +90 -53
- data/lib/ronin/payloads/shellcode.rb +1 -1
- data/lib/ronin/payloads/web_payload.rb +2 -1
- data/lib/ronin/targeted_arch.rb +38 -0
- data/lib/ronin/targeted_os.rb +38 -0
- data/lib/ronin/targeted_product.rb +34 -0
- data/lib/ronin/ui/command_line/commands/exploits.rb +77 -0
- data/lib/ronin/ui/command_line/commands/payload.rb +106 -0
- data/lib/ronin/ui/command_line/commands/payloads.rb +73 -0
- data/spec/exploits/binary_exploit_spec.rb +44 -0
- data/spec/exploits/buffer_overflow_exploit_spec.rb +70 -0
- data/spec/exploits/exploit_spec.rb +122 -25
- data/spec/exploits/format_string_exploit_spec.rb +32 -0
- data/spec/exploits/ftp_spec.rb +17 -0
- data/spec/exploits/http_spec.rb +17 -0
- data/spec/exploits/padding_exploit_spec.rb +44 -0
- data/spec/exploits/remote_tcp_spec.rb +24 -0
- data/spec/exploits/remote_udp_spec.rb +24 -0
- data/spec/exploits/target_spec.rb +91 -0
- data/spec/exploits/targets/buffer_overflow_spec.rb +18 -0
- data/spec/exploits/{web_exploit_spec.rb → web_spec.rb} +5 -5
- data/spec/helpers/database.rb +5 -0
- data/spec/helpers/objects.rb +22 -0
- data/spec/objects/exploits/test.rb +28 -0
- data/spec/objects/payloads/example.rb +19 -0
- data/spec/objects/payloads/test.rb +11 -0
- data/spec/payloads/encoder_spec.rb +26 -0
- data/spec/payloads/encoders/xor_spec.rb +20 -0
- data/spec/payloads/payload_spec.rb +48 -13
- data/spec/spec_helper.rb +3 -5
- metadata +71 -22
- data/lib/ronin/exploits/binary_exploit.rb +0 -139
- data/lib/ronin/exploits/buffer_overflow.rb +0 -80
- data/lib/ronin/exploits/exploitable.rb +0 -77
- data/lib/ronin/exploits/format_string.rb +0 -88
- data/lib/ronin/models.rb +0 -38
- data/lib/ronin/translators/xor.rb +0 -96
- data/spec/exploits/exploitable_spec.rb +0 -21
- data/spec/translators/xor_spec.rb +0 -26
@@ -0,0 +1,32 @@
|
|
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
|
+
module Ronin
|
25
|
+
module Payloads
|
26
|
+
class Nops < BinaryPayload
|
27
|
+
|
28
|
+
contextify :ronin_nops
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -21,19 +21,27 @@
|
|
21
21
|
#++
|
22
22
|
#
|
23
23
|
|
24
|
-
require 'ronin/payloads/
|
24
|
+
require 'ronin/payloads/exceptions/unknown_helper'
|
25
25
|
require 'ronin/payloads/payload_author'
|
26
|
-
require 'ronin/
|
26
|
+
require 'ronin/payloads/control'
|
27
|
+
require 'ronin/model/targets_arch'
|
28
|
+
require 'ronin/model/targets_os'
|
29
|
+
require 'ronin/cacheable'
|
27
30
|
require 'ronin/has_license'
|
28
31
|
|
32
|
+
require 'parameters'
|
33
|
+
|
29
34
|
module Ronin
|
30
35
|
module Payloads
|
31
36
|
class Payload
|
32
37
|
|
33
|
-
include
|
38
|
+
include Parameters
|
39
|
+
include Cacheable
|
40
|
+
include Model::TargetsArch
|
41
|
+
include Model::TargetsOS
|
34
42
|
include HasLicense
|
35
43
|
|
36
|
-
|
44
|
+
contextify :ronin_payload
|
37
45
|
|
38
46
|
# Primary key of the payload
|
39
47
|
property :id, Serial
|
@@ -48,18 +56,15 @@ module Ronin
|
|
48
56
|
property :description, Text
|
49
57
|
|
50
58
|
# Author(s) of the payload
|
51
|
-
has n, :authors, :class_name => 'PayloadAuthor'
|
59
|
+
has n, :authors, :class_name => 'Ronin::Payloads::PayloadAuthor'
|
52
60
|
|
53
|
-
#
|
54
|
-
has n, :
|
61
|
+
# Controls the payload provides
|
62
|
+
has n, :controls
|
55
63
|
|
56
64
|
# Validations
|
57
65
|
validates_present :name
|
58
66
|
validates_is_unique :version, :scope => [:name]
|
59
67
|
|
60
|
-
# Encoders to apply to the payload
|
61
|
-
attr_reader :encoders
|
62
|
-
|
63
68
|
# The built and encoded payload
|
64
69
|
attr_accessor :payload
|
65
70
|
|
@@ -71,7 +76,6 @@ module Ronin
|
|
71
76
|
def initialize(attributes={},&block)
|
72
77
|
super(attributes)
|
73
78
|
|
74
|
-
@encoders = []
|
75
79
|
@built = false
|
76
80
|
|
77
81
|
instance_eval(&block) if block
|
@@ -99,40 +103,34 @@ module Ronin
|
|
99
103
|
self.first(:order => [:version.desc])
|
100
104
|
end
|
101
105
|
|
102
|
-
#
|
103
|
-
# Adds a new Ability to the payload that provides the specified
|
104
|
-
# _behavior_.
|
105
|
-
#
|
106
|
-
def provides(behavior)
|
107
|
-
self.abilities << Ability.new(
|
108
|
-
:behavior => behavior,
|
109
|
-
:payload => self
|
110
|
-
)
|
111
|
-
end
|
112
|
-
|
113
106
|
#
|
114
107
|
# Adds a new PayloadAuthor with the given _attributes_. If a _block_
|
115
108
|
# is given, it will be passed to the newly created PayloadAuthor
|
116
109
|
# object.
|
117
110
|
#
|
111
|
+
# author :name => 'Anonymous',
|
112
|
+
# :email => 'anon@example.com',
|
113
|
+
# :organization => 'Anonymous LLC'
|
114
|
+
#
|
118
115
|
def author(attributes={},&block)
|
119
|
-
authors << PayloadAuthor.new(
|
120
|
-
attributes.merge(:payload => self),
|
121
|
-
&block
|
122
|
-
)
|
116
|
+
self.authors << PayloadAuthor.new(attributes,&block)
|
123
117
|
end
|
124
118
|
|
125
119
|
#
|
126
|
-
#
|
120
|
+
# Adds a new Control to the payload that provides the specified
|
121
|
+
# _behavior_.
|
122
|
+
#
|
123
|
+
# controlling :code_exec
|
127
124
|
#
|
128
|
-
def
|
129
|
-
|
125
|
+
def controlling(behavior)
|
126
|
+
self.controls << Control.new(:behavior => Vuln::Behavior[behavior])
|
130
127
|
end
|
131
128
|
|
132
129
|
#
|
133
|
-
#
|
130
|
+
# Returns the behaviors controlled by the payload.
|
134
131
|
#
|
135
|
-
def
|
132
|
+
def behaviors
|
133
|
+
self.controls.map { |control| control.behavior }
|
136
134
|
end
|
137
135
|
|
138
136
|
#
|
@@ -147,58 +145,97 @@ module Ronin
|
|
147
145
|
# If a _block_ is given, it will be passed the built and encoded
|
148
146
|
# payload.
|
149
147
|
#
|
150
|
-
def build(
|
151
|
-
self.params =
|
148
|
+
def build!(options={},&block)
|
149
|
+
self.params = options
|
152
150
|
|
153
151
|
@built = false
|
154
152
|
@payload = ''
|
155
153
|
|
156
|
-
|
154
|
+
build()
|
157
155
|
|
158
156
|
@built = true
|
159
157
|
|
160
|
-
@encoders.each do |encoder|
|
161
|
-
@payload = encoder.encode(@payload)
|
162
|
-
end
|
163
|
-
|
164
158
|
block.call(@payload) if block
|
165
159
|
return @payload
|
166
160
|
end
|
167
161
|
|
168
162
|
#
|
169
|
-
#
|
163
|
+
# Verifies the payload is properly configured and ready to be
|
164
|
+
# deployed.
|
170
165
|
#
|
171
|
-
def
|
166
|
+
def verify!
|
167
|
+
verify
|
172
168
|
end
|
173
169
|
|
174
170
|
#
|
175
|
-
# Default
|
171
|
+
# Default method to call after the payload has been deployed.
|
176
172
|
#
|
177
|
-
def
|
178
|
-
|
173
|
+
def deploy!(&block)
|
174
|
+
verify!
|
175
|
+
deploy()
|
176
|
+
|
177
|
+
block.call(self) if block
|
178
|
+
return self
|
179
179
|
end
|
180
180
|
|
181
181
|
#
|
182
|
-
#
|
182
|
+
# Returns the name and version of the payload.
|
183
183
|
#
|
184
|
-
def
|
185
|
-
|
184
|
+
def to_s
|
185
|
+
"#{self.name} #{self.version}"
|
186
186
|
end
|
187
187
|
|
188
|
+
protected
|
189
|
+
|
188
190
|
#
|
189
|
-
#
|
191
|
+
# Extends the payload with the helper module defined in
|
192
|
+
# Ronin::Payloads::Helpers that has the similar specified
|
193
|
+
# _name_. If no module can be found within
|
194
|
+
# Ronin::Payloads::Helpers with the similar _name_, an
|
195
|
+
# UnknownHelper exception will be raised.
|
190
196
|
#
|
191
|
-
|
192
|
-
|
197
|
+
# helper :shell
|
198
|
+
#
|
199
|
+
def helper(name)
|
200
|
+
name = name.to_s
|
201
|
+
module_name = name.to_const_string
|
202
|
+
|
203
|
+
begin
|
204
|
+
require File.join('ronin','payloads','helpers',name)
|
205
|
+
rescue LoadError
|
206
|
+
raise(UnknownHelper,"unknown helper #{name.dump}",caller)
|
207
|
+
end
|
208
|
+
|
209
|
+
unless Ronin::Payloads::Helpers.const_defined?(module_name)
|
210
|
+
raise(UnknownHelper,"unknown helper #{name.dump}",caller)
|
211
|
+
end
|
193
212
|
|
194
|
-
|
213
|
+
helper_module = Ronin::Payloads::Helpers.const_get(module_name)
|
214
|
+
|
215
|
+
unless helper_module.kind_of?(Module)
|
216
|
+
raise(UnknownHelper,"unknown helper #{name.dump}",caller)
|
217
|
+
end
|
218
|
+
|
219
|
+
extend helper_module
|
220
|
+
return true
|
195
221
|
end
|
196
222
|
|
197
223
|
#
|
198
|
-
#
|
224
|
+
# Default builder method.
|
199
225
|
#
|
200
|
-
def
|
201
|
-
|
226
|
+
def build
|
227
|
+
end
|
228
|
+
|
229
|
+
#
|
230
|
+
# Default payload verifier method.
|
231
|
+
#
|
232
|
+
def verify
|
233
|
+
end
|
234
|
+
|
235
|
+
#
|
236
|
+
# Default payload deployer method.
|
237
|
+
#
|
238
|
+
def deploy(&block)
|
202
239
|
end
|
203
240
|
|
204
241
|
end
|
@@ -0,0 +1,38 @@
|
|
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/arch'
|
25
|
+
|
26
|
+
module Ronin
|
27
|
+
class TargetedArch < Arch
|
28
|
+
|
29
|
+
# The exploit targets for the Arch
|
30
|
+
has n, :targets,
|
31
|
+
:class_name => 'Ronin::Exploits::Target'
|
32
|
+
|
33
|
+
# The payloads which target the Arch
|
34
|
+
has n, :payloads,
|
35
|
+
:class_name => 'Ronin::Payloads::Payload'
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
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/os'
|
25
|
+
|
26
|
+
module Ronin
|
27
|
+
class TargetedOS < OS
|
28
|
+
|
29
|
+
# The exploit targets for the OS
|
30
|
+
has n, :targets,
|
31
|
+
:class_name => 'Ronin::Exploits::Target'
|
32
|
+
|
33
|
+
# The payloads which target the OS
|
34
|
+
has n, :payloads,
|
35
|
+
:class_name => 'Ronin::Payloads::Payload'
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -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/product'
|
25
|
+
|
26
|
+
module Ronin
|
27
|
+
class TargetedProduct < Product
|
28
|
+
|
29
|
+
# The exploit targets for the Product
|
30
|
+
has n, :targets,
|
31
|
+
:class_name => 'Ronin::Exploits::Target'
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,77 @@
|
|
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/exploits'
|
27
|
+
require 'ronin/database'
|
28
|
+
|
29
|
+
module Ronin
|
30
|
+
module UI
|
31
|
+
module CommandLine
|
32
|
+
module Commands
|
33
|
+
class Exploits < 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 exploits with the similar NAME') do |name|
|
48
|
+
@query[:name.like] = name.to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
opts.on('-v','--version VERSION','Search for exploits with the similar VERSION') do |version|
|
52
|
+
@query[:version.like] = version.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on('-s','--status STATUS','Search for exploits with the STATUS (potential, proven or weaponized)') do |status|
|
56
|
+
@query[:status] = status.to_sym
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def arguments(*args)
|
62
|
+
Database.setup!
|
63
|
+
|
64
|
+
exploits = Ronin::Exploits::Exploit.all(@query)
|
65
|
+
|
66
|
+
if exploits.empty?
|
67
|
+
fail("could not find similar exploits")
|
68
|
+
end
|
69
|
+
|
70
|
+
exploits.each { |exploit| puts " #{exploit}" }
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|